diff --git a/.github/workflows/build-and-deploy-snapshot.yml b/.github/workflows/build-and-deploy-snapshot.yml index c5662389304e..e94a87c025c7 100644 --- a/.github/workflows/build-and-deploy-snapshot.yml +++ b/.github/workflows/build-and-deploy-snapshot.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: push: branches: - - 'main' + - 4.0.x-restructure concurrency: group: ${{ github.workflow }}-${{ github.ref }} jobs: @@ -28,7 +28,7 @@ jobs: - name: Deploy uses: spring-io/artifactory-deploy-action@dc1913008c0599f0c4b1fdafb6ff3c502b3565ea # v0.0.2 with: - build-name: ${{ vars.COMMERCIAL && format('spring-boot-commercial-{0}', '4.0.x') || format('spring-boot-{0}', '4.0.x') }} + build-name: ${{ vars.COMMERCIAL && format('spring-boot-commercial-{0}', '4.0.x-restructure') || format('spring-boot-{0}', '4.0.x-restructure') }} folder: 'deployment-repository' password: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_PASSWORD || secrets.ARTIFACTORY_PASSWORD }} project: ${{ vars.COMMERCIAL && 'spring' }} @@ -47,17 +47,6 @@ jobs: webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} outputs: version: ${{ steps.build-and-publish.outputs.version }} - trigger-docs-build: - name: Trigger Docs Build - needs: build-and-deploy-snapshot - permissions: - actions: write - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Run Deploy Docs Workflow - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml --repo spring-projects/spring-boot -r docs-build -f build-refname=${{ github.ref_name }} -f build-version=${{ needs.build-and-deploy-snapshot.outputs.version }} verify: name: Verify needs: build-and-deploy-snapshot diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 40501dccc180..ec8508096393 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: branches: - - 'main' + - 4.0.x-restructure jobs: ci: name: '${{ matrix.os.name}} | Java ${{ matrix.java.version}}' diff --git a/.github/workflows/run-system-tests.yml b/.github/workflows/run-system-tests.yml index 154fa4712482..7983d16437ac 100644 --- a/.github/workflows/run-system-tests.yml +++ b/.github/workflows/run-system-tests.yml @@ -2,7 +2,7 @@ name: Run System Tests on: push: branches: - - 'main' + - 4.0.x-restructure jobs: run-system-tests: name: 'Java ${{ matrix.java.version}}' diff --git a/build.gradle b/build.gradle index 31c906b3ee31..78211d1b4fc0 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ subprojects { } configurations.all { - resolutionStrategy.cacheChangingModulesFor 0, "minutes" + resolutionStrategy.cacheChangingModulesFor 1, "hours" } } diff --git a/gradle.properties b/gradle.properties index 9f6e5608c639..605c034695d4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=4.0.0-SNAPSHOT +version=4.0.0-restructure-SNAPSHOT latestVersion=true spring.build-type=oss diff --git a/gradle/plugins/config/checkstyle/checkstyle.xml b/gradle/plugins/config/checkstyle/checkstyle.xml new file mode 100644 index 000000000000..1ad50d8fcb84 --- /dev/null +++ b/gradle/plugins/config/checkstyle/checkstyle.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/gradle/plugins/cycle-detection-plugin/build.gradle b/gradle/plugins/cycle-detection-plugin/build.gradle new file mode 100644 index 000000000000..6d22490682a4 --- /dev/null +++ b/gradle/plugins/cycle-detection-plugin/build.gradle @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id 'java-gradle-plugin' + id "checkstyle" + id "io.spring.javaformat" version "$javaFormatVersion" + +} + +repositories { + mavenCentral() +} + +checkstyle { + toolVersion = "${checkstyleToolVersion}" +} + +dependencies { + checkstyle("com.puppycrawl.tools:checkstyle:${checkstyle.toolVersion}") + checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}") + + implementation("org.jgrapht:jgrapht-core:1.5.2") +} + +gradlePlugin { + plugins { + cycleDetectionPlugin { + id = "org.springframework.boot.cycle-detection" + implementationClass = "org.springframework.boot.build.cycledetection.CycleDetectionPlugin" + } + } +} diff --git a/gradle/plugins/cycle-detection-plugin/src/main/java/org/springframework/boot/build/cycledetection/CycleDetectionPlugin.java b/gradle/plugins/cycle-detection-plugin/src/main/java/org/springframework/boot/build/cycledetection/CycleDetectionPlugin.java new file mode 100644 index 000000000000..e254c4282faf --- /dev/null +++ b/gradle/plugins/cycle-detection-plugin/src/main/java/org/springframework/boot/build/cycledetection/CycleDetectionPlugin.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.cycledetection; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.gradle.api.GradleException; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.execution.TaskExecutionGraph; +import org.gradle.api.initialization.Settings; +import org.jgrapht.Graph; +import org.jgrapht.alg.cycle.TarjanSimpleCycles; +import org.jgrapht.graph.DefaultDirectedGraph; +import org.jgrapht.graph.DefaultEdge; + +/** + * A {@link Settings} {@link Plugin plugin} to detect cycles between a build's projects. + * + * @author Andy Wilkinson + */ +public class CycleDetectionPlugin implements Plugin { + + @Override + public void apply(Settings settings) { + settings.getGradle().getTaskGraph().whenReady(this::detectCycles); + } + + private void detectCycles(TaskExecutionGraph taskGraph) { + Map> dependenciesByProject = getProjectsAndDependencies(taskGraph); + Graph graph = createGraph(dependenciesByProject); + List> cycles = findCycles(graph); + if (!cycles.isEmpty()) { + StringBuilder message = new StringBuilder("Cycles detected:\n"); + for (List cycle : cycles) { + cycle.add(cycle.get(0)); + message.append(" " + String.join(" -> ", cycle) + "\n"); + } + throw new GradleException(message.toString()); + } + } + + private Map> getProjectsAndDependencies(TaskExecutionGraph taskGraph) { + Map> dependenciesByProject = new HashMap<>(); + for (Task task : taskGraph.getAllTasks()) { + Project project = task.getProject(); + Set dependencies = dependenciesByProject.computeIfAbsent(project, (p) -> new LinkedHashSet<>()); + taskGraph.getDependencies(task) + .stream() + .map(Task::getProject) + .filter((taskProject) -> !taskProject.equals(project)) + .forEach(dependencies::add); + } + return dependenciesByProject; + } + + private Graph createGraph(Map> dependenciesByProject) { + Graph graph = new DefaultDirectedGraph<>(DefaultEdge.class); + dependenciesByProject.keySet().forEach((project) -> graph.addVertex(project.getName())); + dependenciesByProject.forEach((project, dependencies) -> dependencies + .forEach((dependency) -> graph.addEdge(project.getName(), dependency.getName()))); + return graph; + } + + private List> findCycles(Graph graph) { + TarjanSimpleCycles simpleCycles = new TarjanSimpleCycles<>(graph); + List> cycles = simpleCycles.findSimpleCycles(); + return cycles; + } + +} diff --git a/gradle/plugins/settings.gradle b/gradle/plugins/settings.gradle new file mode 100644 index 000000000000..27b39639aacd --- /dev/null +++ b/gradle/plugins/settings.gradle @@ -0,0 +1,29 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +pluginManagement { + new File(rootDir.parentFile.parentFile, "gradle.properties").withInputStream { + def properties = new Properties() + properties.load(it) + properties.forEach(settings.ext::set) + gradle.rootProject { + properties.forEach(project.ext::set) + } + } +} + +include 'cycle-detection-plugin' diff --git a/settings.gradle b/settings.gradle index c04b109c4a62..c0b0f2b017ca 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,10 +31,12 @@ pluginManagement { } } } + includeBuild("gradle/plugins") } plugins { id "io.spring.develocity.conventions" version "0.0.22" + id "org.springframework.boot.cycle-detection" } rootProject.name="spring-boot-build" @@ -54,17 +56,98 @@ settings.gradle.projectsLoaded { } include "spring-boot-project:spring-boot" +include "spring-boot-project:spring-boot-activemq" include "spring-boot-project:spring-boot-actuator" include "spring-boot-project:spring-boot-actuator-autoconfigure" +include "spring-boot-project:spring-boot-actuator-docs" +include "spring-boot-project:spring-boot-actuator-integration-tests" +include "spring-boot-project:spring-boot-amqp" +include "spring-boot-project:spring-boot-artemis" include "spring-boot-project:spring-boot-autoconfigure" +include "spring-boot-project:spring-boot-batch" +include "spring-boot-project:spring-boot-cache" +include "spring-boot-project:spring-boot-cassandra" +include "spring-boot-project:spring-boot-cloudfoundry" +include "spring-boot-project:spring-boot-couchbase" +include "spring-boot-project:spring-boot-data-cassandra" +include "spring-boot-project:spring-boot-data-commons" +include "spring-boot-project:spring-boot-data-couchbase" +include "spring-boot-project:spring-boot-data-elasticsearch" +include "spring-boot-project:spring-boot-data-jdbc" +include "spring-boot-project:spring-boot-data-jpa" +include "spring-boot-project:spring-boot-data-ldap" +include "spring-boot-project:spring-boot-data-mongodb" +include "spring-boot-project:spring-boot-data-neo4j" +include "spring-boot-project:spring-boot-data-r2dbc" +include "spring-boot-project:spring-boot-data-redis" +include "spring-boot-project:spring-boot-data-rest" include "spring-boot-project:spring-boot-dependencies" include "spring-boot-project:spring-boot-devtools" include "spring-boot-project:spring-boot-docker-compose" include "spring-boot-project:spring-boot-docs" +include "spring-boot-project:spring-boot-elasticsearch" +include "spring-boot-project:spring-boot-flyway" +include "spring-boot-project:spring-boot-freemarker" +include "spring-boot-project:spring-boot-graphql" +include "spring-boot-project:spring-boot-graphql-test" +include "spring-boot-project:spring-boot-groovy-templates" +include "spring-boot-project:spring-boot-gson" +include "spring-boot-project:spring-boot-h2console" +include "spring-boot-project:spring-boot-hateoas" +include "spring-boot-project:spring-boot-hazelcast" +include "spring-boot-project:spring-boot-health" +include "spring-boot-project:spring-boot-hibernate" +include "spring-boot-project:spring-boot-http-client" +include "spring-boot-project:spring-boot-http-converter" +include "spring-boot-project:spring-boot-http-codec" +include "spring-boot-project:spring-boot-integration" +include "spring-boot-project:spring-boot-integration-tests" +include "spring-boot-project:spring-boot-jackson" +include "spring-boot-project:spring-boot-jdbc" +include "spring-boot-project:spring-boot-jersey" +include "spring-boot-project:spring-boot-jetty" +include "spring-boot-project:spring-boot-jms" +include "spring-boot-project:spring-boot-jooq" +include "spring-boot-project:spring-boot-jpa" +include "spring-boot-project:spring-boot-jsonb" +include "spring-boot-project:spring-boot-kafka" +include "spring-boot-project:spring-boot-ldap" +include "spring-boot-project:spring-boot-liquibase" +include "spring-boot-project:spring-boot-neo4j" +include "spring-boot-project:spring-boot-mail" +include "spring-boot-project:spring-boot-metrics" +include "spring-boot-project:spring-boot-mongodb" +include "spring-boot-project:spring-boot-mustache" +include "spring-boot-project:spring-boot-netty" +include "spring-boot-project:spring-boot-observation" +include "spring-boot-project:spring-boot-opentelemetry" include "spring-boot-project:spring-boot-parent" +include "spring-boot-project:spring-boot-pulsar" +include "spring-boot-project:spring-boot-quartz" +include "spring-boot-project:spring-boot-r2dbc" +include "spring-boot-project:spring-boot-reactor" +include "spring-boot-project:spring-boot-reactor-netty" +include "spring-boot-project:spring-boot-restclient" +include "spring-boot-project:spring-boot-restclient-test" +include "spring-boot-project:spring-boot-rsocket" +include "spring-boot-project:spring-boot-security" +include "spring-boot-project:spring-boot-security-oauth2-authorization-server" +include "spring-boot-project:spring-boot-security-oauth2-client" +include "spring-boot-project:spring-boot-security-oauth2-resource-server" +include "spring-boot-project:spring-boot-security-saml2" +include "spring-boot-project:spring-boot-sendgrid" +include "spring-boot-project:spring-boot-servlet" +include "spring-boot-project:spring-boot-session" +include "spring-boot-project:spring-boot-session-data-mongodb" +include "spring-boot-project:spring-boot-session-data-redis" +include "spring-boot-project:spring-boot-session-hazelcast" +include "spring-boot-project:spring-boot-session-jdbc" +include "spring-boot-project:spring-boot-sql" include "spring-boot-project:spring-boot-test" include "spring-boot-project:spring-boot-test-autoconfigure" include "spring-boot-project:spring-boot-testcontainers" +include "spring-boot-project:spring-boot-thymeleaf" +include "spring-boot-project:spring-boot-tomcat" include "spring-boot-project:spring-boot-tools:spring-boot-antlib" include "spring-boot-project:spring-boot-tools:spring-boot-autoconfigure-processor" include "spring-boot-project:spring-boot-tools:spring-boot-buildpack-platform" @@ -82,6 +165,18 @@ include "spring-boot-project:spring-boot-tools:spring-boot-maven-plugin" include "spring-boot-project:spring-boot-tools:spring-boot-properties-migrator" include "spring-boot-project:spring-boot-tools:spring-boot-test-support" include "spring-boot-project:spring-boot-tools:spring-boot-test-support-docker" +include "spring-boot-project:spring-boot-tracing" +include "spring-boot-project:spring-boot-tx" +include "spring-boot-project:spring-boot-undertow" +include "spring-boot-project:spring-boot-validation" +include "spring-boot-project:spring-boot-web-server" +include "spring-boot-project:spring-boot-web-server-test" +include "spring-boot-project:spring-boot-webclient" +include "spring-boot-project:spring-boot-webflux" +include "spring-boot-project:spring-boot-webmvc" +include "spring-boot-project:spring-boot-webservices" +include "spring-boot-project:spring-boot-websocket" +include "spring-boot-project:spring-boot-zipkin" include "spring-boot-system-tests:spring-boot-deployment-tests" include "spring-boot-system-tests:spring-boot-image-tests" include "spring-boot-tests:spring-boot-integration-tests:spring-boot-configuration-processor-tests" diff --git a/spring-boot-project/spring-boot-activemq/build.gradle b/spring-boot-project/spring-boot-activemq/build.gradle new file mode 100644 index 000000000000..62fb240429ab --- /dev/null +++ b/spring-boot-project/spring-boot-activemq/build.gradle @@ -0,0 +1,52 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot ActiveMQ" + +dependencies { + api(project(":spring-boot-project:spring-boot-jms")) + api("org.apache.activemq:activemq-client") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional(project(":spring-boot-project:spring-boot-tx")) + optional("jakarta.transaction:jakarta.transaction-api") + optional("org.apache.activemq:activemq-broker") + optional("org.messaginghub:pooled-jms") { + exclude group: "org.apache.geronimo.specs", module: "geronimo-jms_2.0_spec" + } + optional("org.testcontainers:activemq") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("ch.qos.logback:logback-classic") + dockerTestImplementation("org.testcontainers:junit-jupiter") + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 90% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicDockerComposeConnectionDetailsFactoryIntegrationTests.java index 8f209bf0b2ae..e0019b06f3c1 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.activemq.docker.compose; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails; +import org.springframework.boot.activemq.autoconfigure.ActiveMQConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/docker/compose/ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 89% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/docker/compose/ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests.java index bd65d078f371..b522fbec6b3f 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/docker/compose/ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.activemq.docker.compose; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails; +import org.springframework.boot.activemq.autoconfigure.ActiveMQConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQClassicContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/testcontainers/ActiveMQClassicContainerConnectionDetailsFactoryIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQClassicContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/testcontainers/ActiveMQClassicContainerConnectionDetailsFactoryIntegrationTests.java index cb801f4e0753..71df237982db 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQClassicContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/testcontainers/ActiveMQClassicContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.activemq; +package org.springframework.boot.activemq.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -27,9 +27,9 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.activemq.autoconfigure.ActiveMQAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/testcontainers/ActiveMQContainerConnectionDetailsFactoryIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/testcontainers/ActiveMQContainerConnectionDetailsFactoryIntegrationTests.java index b354b88a8961..eafc36676ed0 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-activemq/src/dockerTest/java/org/springframework/boot/activemq/testcontainers/ActiveMQContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.activemq; +package org.springframework.boot.activemq.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -26,9 +26,9 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.activemq.autoconfigure.ActiveMQAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.SymptomaActiveMQContainer; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/activemq/activemq-classic-compose.yaml b/spring-boot-project/spring-boot-activemq/src/dockerTest/resources/org/springframework/boot/activemq/docker/compose/activemq-classic-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/activemq/activemq-classic-compose.yaml rename to spring-boot-project/spring-boot-activemq/src/dockerTest/resources/org/springframework/boot/activemq/docker/compose/activemq-classic-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/activemq/activemq-compose.yaml b/spring-boot-project/spring-boot-activemq/src/dockerTest/resources/org/springframework/boot/activemq/docker/compose/activemq-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/activemq/activemq-compose.yaml rename to spring-boot-project/spring-boot-activemq/src/dockerTest/resources/org/springframework/boot/activemq/docker/compose/activemq-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/activemq/artemis-compose.yaml b/spring-boot-project/spring-boot-activemq/src/dockerTest/resources/org/springframework/boot/activemq/docker/compose/artemis-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/activemq/artemis-compose.yaml rename to spring-boot-project/spring-boot-activemq/src/dockerTest/resources/org/springframework/boot/activemq/docker/compose/artemis-compose.yaml diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfiguration.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfiguration.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQAutoConfiguration.java index 3b3da8f47ce3..215fe1aa4d29 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfiguration.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import jakarta.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; @@ -23,10 +23,11 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.JmsProperties; -import org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration; +import org.springframework.boot.jms.autoconfigure.JmsProperties; +import org.springframework.boot.jms.autoconfigure.JndiConnectionFactoryAutoConfiguration; +import org.springframework.boot.transaction.jta.autoconfigure.JtaAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -37,9 +38,10 @@ * @author Stephane Nicoll * @author Phillip Webb * @author Eddú Meléndez - * @since 3.1.0 + * @since 4.0.0 */ -@AutoConfiguration(before = JmsAutoConfiguration.class, after = JndiConnectionFactoryAutoConfiguration.class) +@AutoConfiguration(before = JmsAutoConfiguration.class, + after = { JndiConnectionFactoryAutoConfiguration.class, JtaAutoConfiguration.class }) @ConditionalOnClass({ ConnectionFactory.class, ActiveMQConnectionFactory.class }) @ConditionalOnMissingBean(ConnectionFactory.class) @EnableConfigurationProperties({ ActiveMQProperties.class, JmsProperties.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionDetails.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionDetails.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionDetails.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionDetails.java index b5563c0b620e..450798faca22 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionDetails.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; @@ -23,7 +23,7 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 3.2.0 + * @since 4.0.0 */ public interface ActiveMQConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryConfiguration.java index 1b635bffe366..611728b73d8e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import jakarta.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; @@ -25,8 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryFactory; -import org.springframework.boot.autoconfigure.jms.JmsProperties; +import org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryFactory; +import org.springframework.boot.jms.autoconfigure.JmsProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.connection.CachingConnectionFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfigurer.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryConfigurer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfigurer.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryConfigurer.java index d44681288ed3..fc099d9ec21f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfigurer.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryConfigurer.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import java.util.Collections; import java.util.List; import org.apache.activemq.ActiveMQConnectionFactory; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQProperties.Packages; +import org.springframework.boot.activemq.autoconfigure.ActiveMQProperties.Packages; import org.springframework.util.Assert; /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryCustomizer.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryCustomizer.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryCustomizer.java index c50658e68d2c..fdcfbecb6aa3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQConnectionFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import org.apache.activemq.ActiveMQConnectionFactory; @@ -23,7 +23,7 @@ * {@link ActiveMQConnectionFactory} whilst retaining default auto-configuration. * * @author Stephane Nicoll - * @since 3.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface ActiveMQConnectionFactoryCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQProperties.java index 0e8b405fe682..04ad7cd753e2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQProperties.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import java.time.Duration; import java.util.ArrayList; import java.util.List; -import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; +import org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties; /** * Configuration properties for ActiveMQ. @@ -32,7 +32,7 @@ * @author Aurélien Leboulanger * @author Venil Noronha * @author Eddú Meléndez - * @since 3.1.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.activemq") public class ActiveMQProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQXAConnectionFactoryConfiguration.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQXAConnectionFactoryConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQXAConnectionFactoryConfiguration.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQXAConnectionFactoryConfiguration.java index 8448618b7b2b..5563af33e585 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQXAConnectionFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/ActiveMQXAConnectionFactoryConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import jakarta.jms.ConnectionFactory; import jakarta.transaction.TransactionManager; diff --git a/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/package-info.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/package-info.java new file mode 100644 index 000000000000..5a7faf4775df --- /dev/null +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for ActiveMQ. + */ +package org.springframework.boot.activemq.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicDockerComposeConnectionDetailsFactory.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicDockerComposeConnectionDetailsFactory.java index 533e075e3e5d..26b3ab0b3da1 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicDockerComposeConnectionDetailsFactory.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.activemq.docker.compose; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails; +import org.springframework.boot.activemq.autoconfigure.ActiveMQConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicEnvironment.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicEnvironment.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicEnvironment.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicEnvironment.java index dbd4f5093e9b..aa6963e8edf1 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicEnvironment.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.activemq.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQDockerComposeConnectionDetailsFactory.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQDockerComposeConnectionDetailsFactory.java index 2463bc47fe75..357f70e55025 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQDockerComposeConnectionDetailsFactory.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.activemq.docker.compose; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails; +import org.springframework.boot.activemq.autoconfigure.ActiveMQConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQEnvironment.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQEnvironment.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQEnvironment.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQEnvironment.java index a6d3d9978703..06d6562bfb6a 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQEnvironment.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/ActiveMQEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.activemq.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/package-info.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/package-info.java new file mode 100644 index 000000000000..86a2b9b8e2af --- /dev/null +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose ActiveMQ service connections. + */ +package org.springframework.boot.activemq.docker.compose; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQClassicContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/ActiveMQClassicContainerConnectionDetailsFactory.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQClassicContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/ActiveMQClassicContainerConnectionDetailsFactory.java index 5a2beafd869f..1741ce87648a 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQClassicContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/ActiveMQClassicContainerConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.activemq; +package org.springframework.boot.activemq.testcontainers; import org.testcontainers.activemq.ActiveMQContainer; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails; +import org.springframework.boot.activemq.autoconfigure.ActiveMQConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/ActiveMQContainerConnectionDetailsFactory.java similarity index 93% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/ActiveMQContainerConnectionDetailsFactory.java index 7d310b9d70e7..61aafd15ee18 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ActiveMQContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/ActiveMQContainerConnectionDetailsFactory.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.activemq; +package org.springframework.boot.activemq.testcontainers; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails; +import org.springframework.boot.activemq.autoconfigure.ActiveMQConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/package-info.java b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/package-info.java new file mode 100644 index 000000000000..b13c78bffdd7 --- /dev/null +++ b/spring-boot-project/spring-boot-activemq/src/main/java/org/springframework/boot/activemq/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers ActiveMQ service connections. + */ +package org.springframework.boot.activemq.testcontainers; diff --git a/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..806052f48646 --- /dev/null +++ b/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,94 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.activemq.pool.block-if-full", + "type": "java.lang.Boolean", + "description": "Whether to block when a connection is requested and the pool is full. Set it to false to throw a \"JMSException\" instead.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": true + }, + { + "name": "spring.activemq.pool.block-if-full-timeout", + "type": "java.time.Duration", + "description": "Blocking period before throwing an exception if the pool is still full.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": "-1ms" + }, + { + "name": "spring.activemq.pool.create-connection-on-startup", + "type": "java.lang.Boolean", + "description": "Whether to create a connection on startup. Can be used to warm up the pool on startup.", + "defaultValue": true, + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.activemq.pool.enabled", + "type": "java.lang.Boolean", + "description": "Whether a JmsPoolConnectionFactory should be created, instead of a regular ConnectionFactory.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": false + }, + { + "name": "spring.activemq.pool.expiry-timeout", + "type": "java.time.Duration", + "description": "Connection expiration timeout.", + "defaultValue": "0ms", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.activemq.pool.idle-timeout", + "type": "java.time.Duration", + "description": "Connection idle timeout.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": "30s" + }, + { + "name": "spring.activemq.pool.max-connections", + "type": "java.lang.Integer", + "description": "Maximum number of pooled connections.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": 1 + }, + { + "name": "spring.activemq.pool.max-sessions-per-connection", + "type": "java.lang.Integer", + "description": "Maximum number of pooled sessions per connection in the pool.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": 500 + }, + { + "name": "spring.activemq.pool.maximum-active-session-per-connection", + "deprecation": { + "replacement": "spring.activemq.pool.max-sessions-per-connection" + } + }, + { + "name": "spring.activemq.pool.reconnect-on-exception", + "type": "java.lang.Boolean", + "description": "Reset the connection when a \"JMSException\" occurs.", + "defaultValue": true, + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.activemq.pool.time-between-expiration-check", + "type": "java.time.Duration", + "description": "Time to sleep between runs of the idle connection eviction thread. When negative, no idle connection eviction thread runs.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": "-1ms" + }, + { + "name": "spring.activemq.pool.use-anonymous-producers", + "type": "java.lang.Boolean", + "description": "Whether to use only one anonymous \"MessageProducer\" instance. Set it to false to create one \"MessageProducer\" every time one is required.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": true + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..2e60d6543c44 --- /dev/null +++ b/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/spring.factories @@ -0,0 +1,5 @@ +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.activemq.docker.compose.ActiveMQClassicDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.activemq.docker.compose.ActiveMQDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.activemq.testcontainers.ActiveMQClassicContainerConnectionDetailsFactory,\ +org.springframework.boot.activemq.testcontainers.ActiveMQContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..8ccd1acc1e99 --- /dev/null +++ b/spring-boot-project/spring-boot-activemq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.activemq.autoconfigure.ActiveMQAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java b/spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/autoconfigure/ActiveMQAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java rename to spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/autoconfigure/ActiveMQAutoConfigurationTests.java index 423e52c4db91..461034532cf2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/autoconfigure/ActiveMQAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import jakarta.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; @@ -22,7 +22,7 @@ import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQPropertiesTests.java b/spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/autoconfigure/ActiveMQPropertiesTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQPropertiesTests.java rename to spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/autoconfigure/ActiveMQPropertiesTests.java index 752b15915aaa..ea5f0ffd4173 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQPropertiesTests.java +++ b/spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/autoconfigure/ActiveMQPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.activemq.autoconfigure; import org.apache.activemq.ActiveMQConnectionFactory; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicEnvironmentTests.java b/spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicEnvironmentTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicEnvironmentTests.java rename to spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicEnvironmentTests.java index f28a1bb60279..474e1dca8a4c 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQClassicEnvironmentTests.java +++ b/spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/docker/compose/ActiveMQClassicEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.activemq.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQEnvironmentTests.java b/spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/docker/compose/ActiveMQEnvironmentTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQEnvironmentTests.java rename to spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/docker/compose/ActiveMQEnvironmentTests.java index a359a18bcc7a..197308d4b7a9 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ActiveMQEnvironmentTests.java +++ b/spring-boot-project/spring-boot-activemq/src/test/java/org/springframework/boot/activemq/docker/compose/ActiveMQEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.activemq.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/logback-test.xml b/spring-boot-project/spring-boot-activemq/src/test/resources/logback-test.xml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/logback-test.xml rename to spring-boot-project/spring-boot-activemq/src/test/resources/logback-test.xml diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/test.p12 b/spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/resources/test.p12 similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/test.p12 rename to spring-boot-project/spring-boot-actuator-autoconfigure-all/src/test/resources/test.p12 diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle index 0311652c2cf8..4480ac2e8793 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle @@ -16,7 +16,7 @@ plugins { id "java-library" - id "org.springframework.boot.antora-contributor" + id "java-test-fixtures" id "org.springframework.boot.auto-configuration" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.deployed" @@ -26,213 +26,28 @@ plugins { description = "Spring Boot Actuator AutoConfigure" dependencies { - api(project(":spring-boot-project:spring-boot")) api(project(":spring-boot-project:spring-boot-actuator")) api(project(":spring-boot-project:spring-boot-autoconfigure")) implementation("com.fasterxml.jackson.core:jackson-databind") implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") - optional("ch.qos.logback:logback-classic") - optional("org.apache.cassandra:java-driver-core") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } - optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml") - optional("com.github.ben-manes.caffeine:caffeine") - optional("com.hazelcast:hazelcast") - optional("com.hazelcast:hazelcast-spring") - optional("com.zaxxer:HikariCP") - optional("io.lettuce:lettuce-core") - optional("io.micrometer:micrometer-observation") - optional("io.micrometer:micrometer-jakarta9") - optional("io.micrometer:micrometer-java21") - optional("io.micrometer:micrometer-tracing") - optional("io.micrometer:micrometer-tracing-bridge-brave") - optional("io.micrometer:micrometer-tracing-bridge-otel") - optional("io.micrometer:micrometer-registry-appoptics") - optional("io.micrometer:micrometer-registry-atlas") { - exclude group: "javax.inject", module: "javax.inject" - } - optional("io.micrometer:micrometer-registry-datadog") - optional("io.micrometer:micrometer-registry-dynatrace") - optional("io.micrometer:micrometer-registry-elastic") - optional("io.micrometer:micrometer-registry-ganglia") - optional("io.micrometer:micrometer-registry-graphite") - optional("io.micrometer:micrometer-registry-humio") - optional("io.micrometer:micrometer-registry-influx") - optional("io.micrometer:micrometer-registry-jmx") - optional("io.micrometer:micrometer-registry-kairos") - optional("io.micrometer:micrometer-registry-new-relic") - optional("io.micrometer:micrometer-registry-otlp") - optional("io.micrometer:micrometer-registry-prometheus") - optional("io.micrometer:micrometer-registry-stackdriver") { - exclude group: "javax.annotation", module: "javax.annotation-api" - } - optional("io.micrometer:micrometer-registry-signalfx") - optional("io.micrometer:micrometer-registry-statsd") - optional("io.zipkin.reporter2:zipkin-reporter-brave") - optional("io.opentelemetry:opentelemetry-exporter-zipkin") - optional("io.opentelemetry:opentelemetry-exporter-otlp") - optional("io.projectreactor.netty:reactor-netty-http") - optional("io.prometheus:prometheus-metrics-exporter-pushgateway") - optional("io.r2dbc:r2dbc-pool") - optional("io.r2dbc:r2dbc-proxy") - optional("io.r2dbc:r2dbc-spi") - optional("jakarta.jms:jakarta.jms-api") - optional("jakarta.persistence:jakarta.persistence-api") + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-web-server")) + + optional("com.fasterxml.jackson.core:jackson-databind") + optional("io.micrometer:micrometer-core") + optional("io.projectreactor:reactor-core") optional("jakarta.servlet:jakarta.servlet-api") - optional("javax.cache:cache-api") - optional("org.apache.activemq:activemq-broker") - optional("org.apache.activemq:activemq-client") - optional("org.apache.commons:commons-dbcp2") - optional("org.apache.kafka:kafka-clients") - optional("org.apache.kafka:kafka-streams") - optional("org.apache.logging.log4j:log4j-api") - optional("org.apache.tomcat.embed:tomcat-embed-core") - optional("org.apache.tomcat.embed:tomcat-embed-el") - optional("org.apache.tomcat:tomcat-jdbc") - optional("org.aspectj:aspectjweaver") - optional("org.cache2k:cache2k-micrometer") - optional("org.cache2k:cache2k-spring") - optional("org.eclipse.angus:angus-mail") - optional("org.eclipse.jetty:jetty-server") { - exclude group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api" - } - optional("org.elasticsearch.client:elasticsearch-rest-client") - optional("org.flywaydb:flyway-core") - optional("org.glassfish.jersey.core:jersey-server") - optional("org.glassfish.jersey.containers:jersey-container-servlet-core") - optional("org.glassfish.jersey.ext:jersey-micrometer") - optional("org.hibernate.orm:hibernate-core") - optional("org.hibernate.orm:hibernate-micrometer") - optional("org.hibernate.validator:hibernate-validator") - optional("org.influxdb:influxdb-java") - optional("org.junit.platform:junit-platform-launcher") - optional("org.liquibase:liquibase-core") { - exclude group: "javax.xml.bind", module: "jaxb-api" - } - optional("org.mongodb:mongodb-driver-reactivestreams") - optional("org.mongodb:mongodb-driver-sync") - optional("org.neo4j.driver:neo4j-java-driver") - optional("org.quartz-scheduler:quartz") - optional("org.springframework:spring-jdbc") - optional("org.springframework:spring-jms") - optional("org.springframework:spring-messaging") - optional("org.springframework:spring-webflux") - optional("org.springframework:spring-webmvc") - optional("org.springframework.amqp:spring-rabbit") - optional("org.springframework.batch:spring-batch-core") - optional("org.springframework.data:spring-data-cassandra") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } - optional("org.springframework.data:spring-data-couchbase") - optional("org.springframework.data:spring-data-jpa") - optional("org.springframework.data:spring-data-ldap") - optional("org.springframework.data:spring-data-mongodb") - optional("org.springframework.data:spring-data-redis") - optional("org.springframework.data:spring-data-elasticsearch") - optional("org.springframework.graphql:spring-graphql") - optional("org.springframework.integration:spring-integration-core") - optional("org.springframework.kafka:spring-kafka") optional("org.springframework.security:spring-security-config") - optional("org.springframework.security:spring-security-web") - optional("org.springframework.session:spring-session-core") - optional("redis.clients:jedis") + + testFixturesImplementation(project(":spring-boot-project:spring-boot-test")) + testFixturesImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation(testFixtures(project(":spring-boot-project:spring-boot"))) - testImplementation("io.micrometer:micrometer-observation-test") - testImplementation("io.opentelemetry:opentelemetry-exporter-common") - testImplementation("io.projectreactor:reactor-test") - testImplementation("io.prometheus:prometheus-metrics-exposition-formats") - testImplementation("io.r2dbc:r2dbc-h2") - testImplementation("com.squareup.okhttp3:mockwebserver") - testImplementation("com.jayway.jsonpath:json-path") - testImplementation("io.undertow:undertow-core") - testImplementation("io.undertow:undertow-servlet") - testImplementation("jakarta.xml.bind:jakarta.xml.bind-api") - testImplementation("org.apache.activemq:artemis-jakarta-client") - testImplementation("org.apache.activemq:artemis-jakarta-server") - testImplementation("org.apache.logging.log4j:log4j-to-slf4j") - testImplementation("org.aspectj:aspectjrt") - testImplementation("org.assertj:assertj-core") - testImplementation("org.awaitility:awaitility") - testImplementation("org.cache2k:cache2k-api") - testImplementation("org.eclipse.jetty.ee10:jetty-ee10-webapp") - testImplementation("org.eclipse.jetty.http2:jetty-http2-server") - testImplementation("org.glassfish.jersey.ext:jersey-spring6") - testImplementation("org.glassfish.jersey.media:jersey-media-json-jackson") - testImplementation("org.hamcrest:hamcrest") - testImplementation("org.hsqldb:hsqldb") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.skyscreamer:jsonassert") - testImplementation("org.springframework:spring-core-test") - testImplementation("org.springframework:spring-orm") - testImplementation("org.springframework:spring-test") - testImplementation("org.springframework.data:spring-data-rest-webmvc") - testImplementation("org.springframework.integration:spring-integration-jmx") - testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc") - testImplementation("org.springframework.restdocs:spring-restdocs-webtestclient") - testImplementation("org.springframework.security:spring-security-test") - testImplementation("org.yaml:snakeyaml") - - testRuntimeOnly("jakarta.management.j2ee:jakarta.management.j2ee-api") - testRuntimeOnly("jakarta.transaction:jakarta.transaction-api") - testRuntimeOnly("org.cache2k:cache2k-core") - testRuntimeOnly("org.opensaml:opensaml-core:4.0.1") - testRuntimeOnly("org.opensaml:opensaml-saml-api:4.0.1") - testRuntimeOnly("org.opensaml:opensaml-saml-impl:4.0.1") - testRuntimeOnly("org.springframework:spring-aspects") - testRuntimeOnly("org.springframework.security:spring-security-oauth2-jose") - testRuntimeOnly("org.springframework.security:spring-security-oauth2-resource-server") - testRuntimeOnly("org.springframework.security:spring-security-saml2-service-provider") { - exclude group: "org.opensaml", module: "opensaml-core" - exclude group: "org.opensaml", module: "opensaml-saml-api" - exclude group: "org.opensaml", module: "opensaml-saml-impl" - } -} - -tasks.named("test") { - jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" - filter { - excludeTestsMatching("*DocumentationTests") - } -} - -def documentationTest = tasks.register("documentationTest", Test) { - testClassesDirs = testing.suites.test.sources.output.classesDirs - classpath = testing.suites.test.sources.runtimeClasspath - jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" - filter { - includeTestsMatching("*DocumentationTests") - } - outputs.dir(layout.buildDirectory.dir("generated-snippets")) - develocity { - predictiveTestSelection { - enabled = false - } - } -} - -tasks.named("generateAntoraPlaybook") { - antoraExtensions.xref.stubs = ["appendix:.*", "api:.*", "reference:.*"] -} + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation("org.springframework:spring-webflux") -antoraContributions { - 'actuator-rest-api' { - aggregateContent { - from(documentationTest.map { layout.buildDirectory.dir("generated-snippets") }) { - into "modules/api/partials/rest/actuator" - } - } - localAggregateContent { - from(tasks.named("generateAntoraYml")) { - into "modules" - } - } - source() - } + testRuntimeOnly("ch.qos.logback:logback-classic") } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/amqp/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/amqp/package-info.java deleted file mode 100644 index 330c86e0567f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/amqp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator AMQP concerns. - */ -package org.springframework.boot.actuate.autoconfigure.amqp; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityHealthContributorAutoConfiguration.java index 8d4ae371d066..20f9e23fc371 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityHealthContributorAutoConfiguration.java @@ -23,8 +23,10 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.availability.ApplicationAvailability; +import org.springframework.boot.health.contributor.Health; import org.springframework.context.annotation.Bean; /** @@ -35,6 +37,7 @@ * @since 2.3.2 */ @AutoConfiguration(after = ApplicationAvailabilityAutoConfiguration.class) +@ConditionalOnClass(Health.class) public class AvailabilityHealthContributorAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java index de73c50b6c98..756338c4e784 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java @@ -23,10 +23,12 @@ import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; import org.springframework.boot.availability.ApplicationAvailability; import org.springframework.boot.cloud.CloudPlatform; +import org.springframework.boot.health.contributor.Health; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; @@ -42,6 +44,7 @@ */ @AutoConfiguration(after = { AvailabilityHealthContributorAutoConfiguration.class, ApplicationAvailabilityAutoConfiguration.class }) +@ConditionalOnClass(Health.class) @Conditional(AvailabilityProbesAutoConfiguration.ProbesCondition.class) public class AvailabilityProbesAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/package-info.java deleted file mode 100644 index 75af5c1069eb..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator cache concerns. - */ -package org.springframework.boot.actuate.autoconfigure.cache; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorAutoConfiguration.java deleted file mode 100644 index 19924c80da52..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorAutoConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cassandra; - -import com.datastax.oss.driver.api.core.CqlSession; - -import org.springframework.boot.actuate.autoconfigure.cassandra.CassandraHealthContributorConfigurations.CassandraDriverConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.cassandra.CassandraDriverHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for - * {@link CassandraDriverHealthIndicator}. - * - * @author Julien Dubois - * @author Stephane Nicoll - * @since 2.1.0 - */ -@AutoConfiguration( - after = { CassandraAutoConfiguration.class, CassandraReactiveHealthContributorAutoConfiguration.class }) -@ConditionalOnClass(CqlSession.class) -@ConditionalOnEnabledHealthIndicator("cassandra") -@Import(CassandraDriverConfiguration.class) -public class CassandraHealthContributorAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraReactiveHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraReactiveHealthContributorAutoConfiguration.java deleted file mode 100644 index bcf7f18be4fc..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraReactiveHealthContributorAutoConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cassandra; - -import com.datastax.oss.driver.api.core.CqlSession; -import reactor.core.publisher.Flux; - -import org.springframework.boot.actuate.autoconfigure.cassandra.CassandraHealthContributorConfigurations.CassandraReactiveDriverConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.cassandra.CassandraDriverReactiveHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for - * {@link CassandraDriverReactiveHealthIndicator}. - * - * @author Artsiom Yudovin - * @author Stephane Nicoll - * @since 2.1.0 - */ -@AutoConfiguration(after = CassandraAutoConfiguration.class) -@ConditionalOnClass({ CqlSession.class, Flux.class }) -@ConditionalOnEnabledHealthIndicator("cassandra") -@Import(CassandraReactiveDriverConfiguration.class) -public class CassandraReactiveHealthContributorAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/package-info.java deleted file mode 100644 index fac792018c5b..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Cassandra concerns. - */ -package org.springframework.boot.actuate.autoconfigure.cassandra; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscoverer.java deleted file mode 100644 index f44509c4157d..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscoverer.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebEndpointDiscoverer.CloudFoundryWebEndpointDiscovererRuntimeHints; -import org.springframework.boot.actuate.endpoint.EndpointFilter; -import org.springframework.boot.actuate.endpoint.OperationFilter; -import org.springframework.boot.actuate.endpoint.invoke.OperationInvokerAdvisor; -import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; -import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; -import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; -import org.springframework.boot.actuate.endpoint.web.PathMapper; -import org.springframework.boot.actuate.endpoint.web.WebOperation; -import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; -import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; -import org.springframework.boot.actuate.health.HealthEndpoint; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.ImportRuntimeHints; -import org.springframework.core.annotation.MergedAnnotations; - -/** - * {@link WebEndpointDiscoverer} for Cloud Foundry that uses Cloud Foundry specific - * extensions for the {@link HealthEndpoint}. - * - * @author Madhura Bhave - * @since 2.0.0 - */ -@ImportRuntimeHints(CloudFoundryWebEndpointDiscovererRuntimeHints.class) -public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer { - - /** - * Create a new {@link WebEndpointDiscoverer} instance. - * @param applicationContext the source application context - * @param parameterValueMapper the parameter value mapper - * @param endpointMediaTypes the endpoint media types - * @param endpointPathMappers the endpoint path mappers - * @param invokerAdvisors invoker advisors to apply - * @param endpointFilters endpoint filters to apply - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #CloudFoundryWebEndpointDiscoverer(ApplicationContext, ParameterValueMapper, EndpointMediaTypes, List, Collection, Collection, Collection)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public CloudFoundryWebEndpointDiscoverer(ApplicationContext applicationContext, - ParameterValueMapper parameterValueMapper, EndpointMediaTypes endpointMediaTypes, - List endpointPathMappers, Collection invokerAdvisors, - Collection> endpointFilters) { - this(applicationContext, parameterValueMapper, endpointMediaTypes, endpointPathMappers, invokerAdvisors, - endpointFilters, Collections.emptyList()); - } - - /** - * Create a new {@link WebEndpointDiscoverer} instance. - * @param applicationContext the source application context - * @param parameterValueMapper the parameter value mapper - * @param endpointMediaTypes the endpoint media types - * @param endpointPathMappers the endpoint path mappers - * @param invokerAdvisors invoker advisors to apply - * @param endpointFilters endpoint filters to apply - * @param operationFilters operation filters to apply - * @since 3.4.0 - */ - public CloudFoundryWebEndpointDiscoverer(ApplicationContext applicationContext, - ParameterValueMapper parameterValueMapper, EndpointMediaTypes endpointMediaTypes, - List endpointPathMappers, Collection invokerAdvisors, - Collection> endpointFilters, - Collection> operationFilters) { - super(applicationContext, parameterValueMapper, endpointMediaTypes, endpointPathMappers, null, invokerAdvisors, - endpointFilters, operationFilters); - } - - @Override - protected boolean isExtensionTypeExposed(Class extensionBeanType) { - // Filter regular health endpoint extensions so a CF version can replace them - return !isHealthEndpointExtension(extensionBeanType) - || isCloudFoundryHealthEndpointExtension(extensionBeanType); - } - - private boolean isHealthEndpointExtension(Class extensionBeanType) { - return MergedAnnotations.from(extensionBeanType) - .get(EndpointWebExtension.class) - .getValue("endpoint", Class.class) - .map(HealthEndpoint.class::isAssignableFrom) - .orElse(false); - } - - private boolean isCloudFoundryHealthEndpointExtension(Class extensionBeanType) { - return MergedAnnotations.from(extensionBeanType).isPresent(EndpointCloudFoundryExtension.class); - } - - static class CloudFoundryWebEndpointDiscovererRuntimeHints implements RuntimeHintsRegistrar { - - @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection() - .registerType(CloudFoundryEndpointFilter.class, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/package-info.java deleted file mode 100644 index b700dbb439aa..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Cloud Foundry concerns. - */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundrySecurityInterceptor.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundrySecurityInterceptor.java deleted file mode 100644 index c3cc4a515d7b..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundrySecurityInterceptor.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.util.Locale; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token; -import org.springframework.http.HttpStatus; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.util.StringUtils; -import org.springframework.web.cors.reactive.CorsUtils; -import org.springframework.web.server.ServerWebExchange; - -/** - * Security interceptor to validate the cloud foundry token. - * - * @author Madhura Bhave - */ -class CloudFoundrySecurityInterceptor { - - private static final Log logger = LogFactory.getLog(CloudFoundrySecurityInterceptor.class); - - private final ReactiveTokenValidator tokenValidator; - - private final ReactiveCloudFoundrySecurityService cloudFoundrySecurityService; - - private final String applicationId; - - private static final Mono SUCCESS = Mono.just(SecurityResponse.success()); - - CloudFoundrySecurityInterceptor(ReactiveTokenValidator tokenValidator, - ReactiveCloudFoundrySecurityService cloudFoundrySecurityService, String applicationId) { - this.tokenValidator = tokenValidator; - this.cloudFoundrySecurityService = cloudFoundrySecurityService; - this.applicationId = applicationId; - } - - Mono preHandle(ServerWebExchange exchange, String id) { - ServerHttpRequest request = exchange.getRequest(); - if (CorsUtils.isPreFlightRequest(request)) { - return SUCCESS; - } - if (!StringUtils.hasText(this.applicationId)) { - return Mono.error(new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, - "Application id is not available")); - } - if (this.cloudFoundrySecurityService == null) { - return Mono.error(new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, - "Cloud controller URL is not available")); - } - return check(exchange, id).then(SUCCESS).doOnError(this::logError).onErrorResume(this::getErrorResponse); - } - - private void logError(Throwable ex) { - logger.error(ex.getMessage(), ex); - } - - private Mono check(ServerWebExchange exchange, String id) { - try { - Token token = getToken(exchange.getRequest()); - return this.tokenValidator.validate(token) - .then(this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId)) - .filter((accessLevel) -> accessLevel.isAccessAllowed(id)) - .switchIfEmpty( - Mono.error(new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"))) - .doOnSuccess((accessLevel) -> exchange.getAttributes().put("cloudFoundryAccessLevel", accessLevel)) - .then(); - } - catch (CloudFoundryAuthorizationException ex) { - return Mono.error(ex); - } - } - - private Mono getErrorResponse(Throwable throwable) { - if (throwable instanceof CloudFoundryAuthorizationException cfException) { - return Mono.just(new SecurityResponse(cfException.getStatusCode(), - "{\"security_error\":\"" + cfException.getMessage() + "\"}")); - } - return Mono.just(new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR, throwable.getMessage())); - } - - private Token getToken(ServerHttpRequest request) { - String authorization = request.getHeaders().getFirst("Authorization"); - String bearerPrefix = "bearer "; - if (authorization == null || !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) { - throw new CloudFoundryAuthorizationException(Reason.MISSING_AUTHORIZATION, - "Authorization header is missing or invalid"); - } - return new Token(authorization.substring(bearerPrefix.length())); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java deleted file mode 100644 index 68f1517a883f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.function.Supplier; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebEndpointDiscoverer; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryInfoEndpointWebExtension; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; -import org.springframework.boot.actuate.endpoint.ExposableEndpoint; -import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; -import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; -import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; -import org.springframework.boot.actuate.health.HealthEndpoint; -import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; -import org.springframework.boot.actuate.info.GitInfoContributor; -import org.springframework.boot.actuate.info.InfoContributor; -import org.springframework.boot.actuate.info.InfoEndpoint; -import org.springframework.boot.actuate.info.InfoPropertiesInfoContributor; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.cloud.CloudPlatform; -import org.springframework.boot.info.GitProperties; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.security.web.server.MatcherSecurityWebFilterChain; -import org.springframework.security.web.server.WebFilterChainProxy; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; -import org.springframework.util.function.SingletonSupplier; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.server.WebFilter; - -/** - * {@link EnableAutoConfiguration Auto-configuration} to expose actuator endpoints for - * Cloud Foundry to use in a reactive environment. - * - * @author Madhura Bhave - * @since 2.0.0 - */ -@AutoConfiguration(after = { HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class }) -@ConditionalOnBooleanProperty(name = "management.cloudfoundry.enabled", matchIfMissing = true) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY) -public class ReactiveCloudFoundryActuatorAutoConfiguration { - - private static final String BASE_PATH = "/cloudfoundryapplication"; - - @Bean - @ConditionalOnMissingBean - @ConditionalOnAvailableEndpoint - @ConditionalOnBean({ HealthEndpoint.class, ReactiveHealthEndpointWebExtension.class }) - public CloudFoundryReactiveHealthEndpointWebExtension cloudFoundryReactiveHealthEndpointWebExtension( - ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension) { - return new CloudFoundryReactiveHealthEndpointWebExtension(reactiveHealthEndpointWebExtension); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnAvailableEndpoint - @ConditionalOnBean({ InfoEndpoint.class, GitProperties.class }) - public CloudFoundryInfoEndpointWebExtension cloudFoundryInfoEndpointWebExtension(GitProperties properties, - ObjectProvider infoContributors) { - List contributors = infoContributors.orderedStream() - .map((infoContributor) -> (infoContributor instanceof GitInfoContributor) - ? new GitInfoContributor(properties, InfoPropertiesInfoContributor.Mode.FULL) : infoContributor) - .toList(); - return new CloudFoundryInfoEndpointWebExtension(new InfoEndpoint(contributors)); - } - - @Bean - @SuppressWarnings("removal") - public CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebFluxEndpointHandlerMapping( - ParameterValueMapper parameterMapper, EndpointMediaTypes endpointMediaTypes, - WebClient.Builder webClientBuilder, - org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier controllerEndpointsSupplier, - ApplicationContext applicationContext) { - CloudFoundryWebEndpointDiscoverer endpointDiscoverer = new CloudFoundryWebEndpointDiscoverer(applicationContext, - parameterMapper, endpointMediaTypes, null, Collections.emptyList(), Collections.emptyList(), - Collections.emptyList()); - CloudFoundrySecurityInterceptor securityInterceptor = getSecurityInterceptor(webClientBuilder, - applicationContext.getEnvironment()); - Collection webEndpoints = endpointDiscoverer.getEndpoints(); - List> allEndpoints = new ArrayList<>(); - allEndpoints.addAll(webEndpoints); - allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); - return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping(BASE_PATH), webEndpoints, - endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints); - } - - private CloudFoundrySecurityInterceptor getSecurityInterceptor(WebClient.Builder webClientBuilder, - Environment environment) { - ReactiveCloudFoundrySecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService( - webClientBuilder, environment); - ReactiveTokenValidator tokenValidator = new ReactiveTokenValidator(cloudfoundrySecurityService); - return new CloudFoundrySecurityInterceptor(tokenValidator, cloudfoundrySecurityService, - environment.getProperty("vcap.application.application_id")); - } - - private ReactiveCloudFoundrySecurityService getCloudFoundrySecurityService(WebClient.Builder webClientBuilder, - Environment environment) { - String cloudControllerUrl = environment.getProperty("vcap.application.cf_api"); - boolean skipSslValidation = environment.getProperty("management.cloudfoundry.skip-ssl-validation", - Boolean.class, false); - return (cloudControllerUrl != null) - ? new ReactiveCloudFoundrySecurityService(webClientBuilder, cloudControllerUrl, skipSslValidation) - : null; - } - - private CorsConfiguration getCorsConfiguration() { - CorsConfiguration corsConfiguration = new CorsConfiguration(); - corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL); - corsConfiguration.setAllowedMethods(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name())); - corsConfiguration - .setAllowedHeaders(Arrays.asList(HttpHeaders.AUTHORIZATION, "X-Cf-App-Instance", HttpHeaders.CONTENT_TYPE)); - return corsConfiguration; - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(MatcherSecurityWebFilterChain.class) - static class IgnoredPathsSecurityConfiguration { - - @Bean - static WebFilterChainPostProcessor webFilterChainPostProcessor( - ObjectProvider handlerMapping) { - return new WebFilterChainPostProcessor(handlerMapping); - } - - } - - static class WebFilterChainPostProcessor implements BeanPostProcessor { - - private final Supplier pathMappedEndpoints; - - WebFilterChainPostProcessor(ObjectProvider handlerMapping) { - this.pathMappedEndpoints = SingletonSupplier - .of(() -> new PathMappedEndpoints(BASE_PATH, () -> handlerMapping.getObject().getAllEndpoints())); - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof WebFilterChainProxy webFilterChainProxy) { - return postProcess(webFilterChainProxy); - } - return bean; - } - - private WebFilterChainProxy postProcess(WebFilterChainProxy existing) { - List paths = getPaths(this.pathMappedEndpoints.get()); - ServerWebExchangeMatcher cloudFoundryRequestMatcher = ServerWebExchangeMatchers - .pathMatchers(paths.toArray(new String[] {})); - WebFilter noOpFilter = (exchange, chain) -> chain.filter(exchange); - MatcherSecurityWebFilterChain ignoredRequestFilterChain = new MatcherSecurityWebFilterChain( - cloudFoundryRequestMatcher, Collections.singletonList(noOpFilter)); - MatcherSecurityWebFilterChain allRequestsFilterChain = new MatcherSecurityWebFilterChain( - ServerWebExchangeMatchers.anyExchange(), Collections.singletonList(existing)); - return new WebFilterChainProxy(ignoredRequestFilterChain, allRequestsFilterChain); - } - - private static List getPaths(PathMappedEndpoints pathMappedEndpoints) { - List paths = new ArrayList<>(); - pathMappedEndpoints.getAllPaths().forEach((path) -> paths.add(path + "/**")); - paths.add(BASE_PATH); - paths.add(BASE_PATH + "/"); - return paths; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java deleted file mode 100644 index e0492af2f7c1..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import io.netty.handler.ssl.SslProvider; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import reactor.core.publisher.Mono; -import reactor.netty.http.Http11SslContextSpec; -import reactor.netty.http.client.HttpClient; -import reactor.netty.tcp.SslProvider.GenericSslContextSpec; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.client.reactive.ReactorClientHttpConnector; -import org.springframework.util.Assert; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -/** - * Reactive Cloud Foundry security service to handle REST calls to the cloud controller - * and UAA. - * - * @author Madhura Bhave - */ -class ReactiveCloudFoundrySecurityService { - - private static final ParameterizedTypeReference> STRING_OBJECT_MAP = new ParameterizedTypeReference<>() { - }; - - private final WebClient webClient; - - private final String cloudControllerUrl; - - ReactiveCloudFoundrySecurityService(WebClient.Builder webClientBuilder, String cloudControllerUrl, - boolean skipSslValidation) { - Assert.notNull(webClientBuilder, "'webClientBuilder' must not be null"); - Assert.notNull(cloudControllerUrl, "'cloudControllerUrl' must not be null"); - if (skipSslValidation) { - webClientBuilder.clientConnector(buildTrustAllSslConnector()); - } - this.webClient = webClientBuilder.build(); - this.cloudControllerUrl = cloudControllerUrl; - } - - protected ReactorClientHttpConnector buildTrustAllSslConnector() { - HttpClient client = HttpClient.create().secure((spec) -> spec.sslContext(createSslContextSpec())); - return new ReactorClientHttpConnector(client); - } - - private GenericSslContextSpec createSslContextSpec() { - return Http11SslContextSpec.forClient() - .configure((builder) -> builder.sslProvider(SslProvider.JDK) - .trustManager(InsecureTrustManagerFactory.INSTANCE)); - } - - /** - * Return a Mono of the access level that should be granted to the given token. - * @param token the token - * @param applicationId the cloud foundry application ID - * @return a Mono of the access level that should be granted - * @throws CloudFoundryAuthorizationException if the token is not authorized - */ - Mono getAccessLevel(String token, String applicationId) throws CloudFoundryAuthorizationException { - String uri = getPermissionsUri(applicationId); - return this.webClient.get() - .uri(uri) - .header("Authorization", "bearer " + token) - .retrieve() - .bodyToMono(Map.class) - .map(this::getAccessLevel) - .onErrorMap(this::mapError); - } - - private Throwable mapError(Throwable throwable) { - if (throwable instanceof WebClientResponseException webClientResponseException) { - HttpStatusCode statusCode = webClientResponseException.getStatusCode(); - if (statusCode.equals(HttpStatus.FORBIDDEN)) { - return new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"); - } - if (statusCode.is4xxClientError()) { - return new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Invalid token", throwable); - } - } - return new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "Cloud controller not reachable"); - } - - private AccessLevel getAccessLevel(Map body) { - if (Boolean.TRUE.equals(body.get("read_sensitive_data"))) { - return AccessLevel.FULL; - } - return AccessLevel.RESTRICTED; - } - - private String getPermissionsUri(String applicationId) { - return this.cloudControllerUrl + "/v2/apps/" + applicationId + "/permissions"; - } - - /** - * Return a Mono of all token keys known by the UAA. - * @return a Mono of token keys - */ - Mono> fetchTokenKeys() { - return getUaaUrl().flatMap(this::fetchTokenKeys); - } - - private Mono> fetchTokenKeys(String url) { - RequestHeadersSpec uri = this.webClient.get().uri(url + "/token_keys"); - return uri.retrieve() - .bodyToMono(STRING_OBJECT_MAP) - .map(this::extractTokenKeys) - .onErrorMap(((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, ex.getMessage()))); - } - - private Map extractTokenKeys(Map response) { - Map tokenKeys = new HashMap<>(); - for (Object key : (List) response.get("keys")) { - Map tokenKey = (Map) key; - tokenKeys.put((String) tokenKey.get("kid"), (String) tokenKey.get("value")); - } - return tokenKeys; - } - - /** - * Return a Mono of URL of the UAA. - * @return the UAA url Mono - */ - Mono getUaaUrl() { - return this.webClient.get() - .uri(this.cloudControllerUrl + "/info") - .retrieve() - .bodyToMono(Map.class) - .map((response) -> (String) response.get("token_endpoint")) - .cache() - .onErrorMap((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, - "Unable to fetch token keys from UAA.")); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidator.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidator.java deleted file mode 100644 index 1308f0fd84d9..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidator.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.Signature; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import reactor.core.publisher.Mono; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token; - -/** - * Validator used to ensure that a signed {@link Token} has not been tampered with. - * - * @author Madhura Bhave - */ -class ReactiveTokenValidator { - - private final ReactiveCloudFoundrySecurityService securityService; - - private volatile Map cachedTokenKeys = Collections.emptyMap(); - - ReactiveTokenValidator(ReactiveCloudFoundrySecurityService securityService) { - this.securityService = securityService; - } - - Mono validate(Token token) { - return validateAlgorithm(token).then(validateKeyIdAndSignature(token)) - .then(validateExpiry(token)) - .then(validateIssuer(token)) - .then(validateAudience(token)); - } - - private Mono validateAlgorithm(Token token) { - String algorithm = token.getSignatureAlgorithm(); - if (algorithm == null) { - return Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, - "Signing algorithm cannot be null")); - } - if (!algorithm.equals("RS256")) { - return Mono.error(new CloudFoundryAuthorizationException(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM, - "Signing algorithm " + algorithm + " not supported")); - } - return Mono.empty(); - } - - private Mono validateKeyIdAndSignature(Token token) { - return getTokenKey(token).filter((tokenKey) -> hasValidSignature(token, tokenKey)) - .switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, - "RSA Signature did not match content"))) - .then(); - } - - private Mono getTokenKey(Token token) { - String keyId = token.getKeyId(); - String cached = this.cachedTokenKeys.get(keyId); - if (cached != null) { - return Mono.just(cached); - } - return this.securityService.fetchTokenKeys() - .doOnSuccess(this::cacheTokenKeys) - .filter((tokenKeys) -> tokenKeys.containsKey(keyId)) - .map((tokenKeys) -> tokenKeys.get(keyId)) - .switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_KEY_ID, - "Key Id present in token header does not match"))); - } - - private void cacheTokenKeys(Map tokenKeys) { - this.cachedTokenKeys = Map.copyOf(tokenKeys); - } - - private boolean hasValidSignature(Token token, String key) { - try { - PublicKey publicKey = getPublicKey(key); - Signature signature = Signature.getInstance("SHA256withRSA"); - signature.initVerify(publicKey); - signature.update(token.getContent()); - return signature.verify(token.getSignature()); - } - catch (GeneralSecurityException ex) { - return false; - } - } - - private PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException { - key = key.replace("-----BEGIN PUBLIC KEY-----\n", ""); - key = key.replace("-----END PUBLIC KEY-----", ""); - key = key.trim().replace("\n", ""); - byte[] bytes = Base64.getDecoder().decode(key); - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes); - return KeyFactory.getInstance("RSA").generatePublic(keySpec); - } - - private Mono validateExpiry(Token token) { - long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()); - if (currentTime > token.getExpiry()) { - return Mono.error(new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED, "Token expired")); - } - return Mono.empty(); - } - - private Mono validateIssuer(Token token) { - return this.securityService.getUaaUrl() - .map((uaaUrl) -> String.format("%s/oauth/token", uaaUrl)) - .filter((issuerUri) -> issuerUri.equals(token.getIssuer())) - .switchIfEmpty(Mono - .error(new CloudFoundryAuthorizationException(Reason.INVALID_ISSUER, "Token issuer does not match"))) - .then(); - } - - private Mono validateAudience(Token token) { - if (!token.getScope().contains("actuator.read")) { - return Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_AUDIENCE, - "Token does not have audience actuator")); - } - return Mono.empty(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/package-info.java deleted file mode 100644 index cb3ef959bc43..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Cloud Foundry concerns using WebFlux. - */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptor.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptor.java deleted file mode 100644 index f5562d24a788..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptor.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; - -import java.util.Locale; - -import jakarta.servlet.http.HttpServletRequest; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.util.StringUtils; -import org.springframework.web.cors.CorsUtils; - -/** - * Security interceptor to validate the cloud foundry token. - * - * @author Madhura Bhave - */ -class CloudFoundrySecurityInterceptor { - - private static final Log logger = LogFactory.getLog(CloudFoundrySecurityInterceptor.class); - - private final TokenValidator tokenValidator; - - private final CloudFoundrySecurityService cloudFoundrySecurityService; - - private final String applicationId; - - private static final SecurityResponse SUCCESS = SecurityResponse.success(); - - CloudFoundrySecurityInterceptor(TokenValidator tokenValidator, - CloudFoundrySecurityService cloudFoundrySecurityService, String applicationId) { - this.tokenValidator = tokenValidator; - this.cloudFoundrySecurityService = cloudFoundrySecurityService; - this.applicationId = applicationId; - } - - SecurityResponse preHandle(HttpServletRequest request, EndpointId endpointId) { - if (CorsUtils.isPreFlightRequest(request)) { - return SecurityResponse.success(); - } - try { - if (!StringUtils.hasText(this.applicationId)) { - throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, - "Application id is not available"); - } - if (this.cloudFoundrySecurityService == null) { - throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, - "Cloud controller URL is not available"); - } - if (HttpMethod.OPTIONS.matches(request.getMethod())) { - return SUCCESS; - } - check(request, endpointId); - } - catch (Exception ex) { - logger.error(ex); - if (ex instanceof CloudFoundryAuthorizationException cfException) { - return new SecurityResponse(cfException.getStatusCode(), - "{\"security_error\":\"" + cfException.getMessage() + "\"}"); - } - return new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage()); - } - return SecurityResponse.success(); - } - - private void check(HttpServletRequest request, EndpointId endpointId) { - Token token = getToken(request); - this.tokenValidator.validate(token); - AccessLevel accessLevel = this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId); - if (!accessLevel.isAccessAllowed((endpointId != null) ? endpointId.toLowerCaseString() : "")) { - throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"); - } - request.setAttribute(AccessLevel.REQUEST_ATTRIBUTE, accessLevel); - } - - private Token getToken(HttpServletRequest request) { - String authorization = request.getHeader("Authorization"); - String bearerPrefix = "bearer "; - if (authorization == null || !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) { - throw new CloudFoundryAuthorizationException(Reason.MISSING_AUTHORIZATION, - "Authorization header is missing or invalid"); - } - return new Token(authorization.substring(bearerPrefix.length())); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityService.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityService.java deleted file mode 100644 index d51e0a3d8b65..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityService.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpStatus; -import org.springframework.http.RequestEntity; -import org.springframework.util.Assert; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.client.HttpStatusCodeException; -import org.springframework.web.client.RestTemplate; - -/** - * Cloud Foundry security service to handle REST calls to the cloud controller and UAA. - * - * @author Madhura Bhave - */ -class CloudFoundrySecurityService { - - private final RestTemplate restTemplate; - - private final String cloudControllerUrl; - - private String uaaUrl; - - CloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder, String cloudControllerUrl, - boolean skipSslValidation) { - Assert.notNull(restTemplateBuilder, "'restTemplateBuilder' must not be null"); - Assert.notNull(cloudControllerUrl, "'cloudControllerUrl' must not be null"); - if (skipSslValidation) { - restTemplateBuilder = restTemplateBuilder.requestFactory(SkipSslVerificationHttpRequestFactory.class); - } - this.restTemplate = restTemplateBuilder.build(); - this.cloudControllerUrl = cloudControllerUrl; - } - - /** - * Return the access level that should be granted to the given token. - * @param token the token - * @param applicationId the cloud foundry application ID - * @return the access level that should be granted - * @throws CloudFoundryAuthorizationException if the token is not authorized - */ - AccessLevel getAccessLevel(String token, String applicationId) throws CloudFoundryAuthorizationException { - try { - URI uri = getPermissionsUri(applicationId); - RequestEntity request = RequestEntity.get(uri).header("Authorization", "bearer " + token).build(); - Map body = this.restTemplate.exchange(request, Map.class).getBody(); - if (Boolean.TRUE.equals(body.get("read_sensitive_data"))) { - return AccessLevel.FULL; - } - return AccessLevel.RESTRICTED; - } - catch (HttpClientErrorException ex) { - if (ex.getStatusCode().equals(HttpStatus.FORBIDDEN)) { - throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"); - } - throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Invalid token", ex); - } - catch (HttpServerErrorException ex) { - throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "Cloud controller not reachable"); - } - } - - private URI getPermissionsUri(String applicationId) { - try { - return new URI(this.cloudControllerUrl + "/v2/apps/" + applicationId + "/permissions"); - } - catch (URISyntaxException ex) { - throw new IllegalStateException(ex); - } - } - - /** - * Return all token keys known by the UAA. - * @return a map of token keys - */ - Map fetchTokenKeys() { - try { - return extractTokenKeys(this.restTemplate.getForObject(getUaaUrl() + "/token_keys", Map.class)); - } - catch (HttpStatusCodeException ex) { - throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "UAA not reachable"); - } - } - - private Map extractTokenKeys(Map response) { - Map tokenKeys = new HashMap<>(); - for (Object key : (List) response.get("keys")) { - Map tokenKey = (Map) key; - tokenKeys.put((String) tokenKey.get("kid"), (String) tokenKey.get("value")); - } - return tokenKeys; - } - - /** - * Return the URL of the UAA. - * @return the UAA url - */ - String getUaaUrl() { - if (this.uaaUrl == null) { - try { - Map response = this.restTemplate.getForObject(this.cloudControllerUrl + "/info", Map.class); - this.uaaUrl = (String) response.get("token_endpoint"); - } - catch (HttpStatusCodeException ex) { - throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, - "Unable to fetch token keys from UAA"); - } - } - return this.uaaUrl; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/TokenValidator.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/TokenValidator.java deleted file mode 100644 index 03f3ef211e8c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/TokenValidator.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; - -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.Signature; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token; - -/** - * Validator used to ensure that a signed {@link Token} has not been tampered with. - * - * @author Madhura Bhave - */ -class TokenValidator { - - private final CloudFoundrySecurityService securityService; - - private Map tokenKeys; - - TokenValidator(CloudFoundrySecurityService cloudFoundrySecurityService) { - this.securityService = cloudFoundrySecurityService; - } - - void validate(Token token) { - validateAlgorithm(token); - validateKeyIdAndSignature(token); - validateExpiry(token); - validateIssuer(token); - validateAudience(token); - } - - private void validateAlgorithm(Token token) { - String algorithm = token.getSignatureAlgorithm(); - if (algorithm == null) { - throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, "Signing algorithm cannot be null"); - } - if (!algorithm.equals("RS256")) { - throw new CloudFoundryAuthorizationException(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM, - "Signing algorithm " + algorithm + " not supported"); - } - } - - private void validateKeyIdAndSignature(Token token) { - String keyId = token.getKeyId(); - if (this.tokenKeys == null || !hasValidKeyId(keyId)) { - this.tokenKeys = this.securityService.fetchTokenKeys(); - if (!hasValidKeyId(keyId)) { - throw new CloudFoundryAuthorizationException(Reason.INVALID_KEY_ID, - "Key Id present in token header does not match"); - } - } - - if (!hasValidSignature(token, this.tokenKeys.get(keyId))) { - throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, - "RSA Signature did not match content"); - } - } - - private boolean hasValidKeyId(String tokenKey) { - return this.tokenKeys.containsKey(tokenKey); - } - - private boolean hasValidSignature(Token token, String key) { - try { - PublicKey publicKey = getPublicKey(key); - Signature signature = Signature.getInstance("SHA256withRSA"); - signature.initVerify(publicKey); - signature.update(token.getContent()); - return signature.verify(token.getSignature()); - } - catch (GeneralSecurityException ex) { - return false; - } - } - - private PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException { - key = key.replace("-----BEGIN PUBLIC KEY-----\n", ""); - key = key.replace("-----END PUBLIC KEY-----", ""); - key = key.trim().replace("\n", ""); - byte[] bytes = Base64.getDecoder().decode(key); - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes); - return KeyFactory.getInstance("RSA").generatePublic(keySpec); - } - - private void validateExpiry(Token token) { - long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()); - if (currentTime > token.getExpiry()) { - throw new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED, "Token expired"); - } - } - - private void validateIssuer(Token token) { - String uaaUrl = this.securityService.getUaaUrl(); - String issuerUri = String.format("%s/oauth/token", uaaUrl); - if (!issuerUri.equals(token.getIssuer())) { - throw new CloudFoundryAuthorizationException(Reason.INVALID_ISSUER, - "Token issuer does not match " + uaaUrl + "/oauth/token"); - } - } - - private void validateAudience(Token token) { - if (!token.getScope().contains("actuator.read")) { - throw new CloudFoundryAuthorizationException(Reason.INVALID_AUDIENCE, - "Token does not have audience actuator"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/package-info.java deleted file mode 100644 index 499fbcb181be..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Cloud Foundry concerns using Spring MVC. - */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/package-info.java deleted file mode 100644 index 920ac22e85cf..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Couchbase concerns. - */ -package org.springframework.boot.actuate.autoconfigure.couchbase; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/package-info.java deleted file mode 100644 index 09d76f6e4119..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Elasticsearch concerns dependent on Spring Data. - */ -package org.springframework.boot.actuate.autoconfigure.data.elasticsearch; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoHealthContributorAutoConfiguration.java deleted file mode 100644 index 6db7d85186e8..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoHealthContributorAutoConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.data.mongo; - -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.data.mongo.MongoHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.data.mongodb.core.MongoTemplate; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for {@link MongoHealthIndicator}. - * - * @author Stephane Nicoll - * @since 2.1.0 - */ -@AutoConfiguration(after = { MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, - MongoReactiveHealthContributorAutoConfiguration.class }) -@ConditionalOnClass(MongoTemplate.class) -@ConditionalOnBean(MongoTemplate.class) -@ConditionalOnEnabledHealthIndicator("mongo") -public class MongoHealthContributorAutoConfiguration - extends CompositeHealthContributorConfiguration { - - public MongoHealthContributorAutoConfiguration() { - super(MongoHealthIndicator::new); - } - - @Bean - @ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" }) - public HealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) { - return createContributor(beanFactory, MongoTemplate.class); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoReactiveHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoReactiveHealthContributorAutoConfiguration.java deleted file mode 100644 index 80275bae82b0..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoReactiveHealthContributorAutoConfiguration.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.data.mongo; - -import reactor.core.publisher.Flux; - -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.data.mongo.MongoReactiveHealthIndicator; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.data.mongodb.core.ReactiveMongoTemplate; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for - * {@link MongoReactiveHealthIndicator}. - * - * @author Stephane Nicoll - * @since 2.1.0 - */ -@AutoConfiguration(after = MongoReactiveDataAutoConfiguration.class) -@ConditionalOnClass({ ReactiveMongoTemplate.class, Flux.class }) -@ConditionalOnBean(ReactiveMongoTemplate.class) -@ConditionalOnEnabledHealthIndicator("mongo") -public class MongoReactiveHealthContributorAutoConfiguration - extends CompositeReactiveHealthContributorConfiguration { - - public MongoReactiveHealthContributorAutoConfiguration() { - super(MongoReactiveHealthIndicator::new); - } - - @Bean - @ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" }) - public ReactiveHealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) { - return createContributor(beanFactory, ReactiveMongoTemplate.class); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/package-info.java deleted file mode 100644 index a2ab9cdad610..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator MongoDB concerns dependent on Spring Data. - */ -package org.springframework.boot.actuate.autoconfigure.data.mongo; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/package-info.java deleted file mode 100644 index a13e38e23839..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator concerns dependent on Spring Data. - */ -package org.springframework.boot.actuate.autoconfigure.data; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/package-info.java deleted file mode 100644 index 8ba9bcd02b8e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Redis concerns dependent on Spring Data. - */ -package org.springframework.boot.actuate.autoconfigure.data.redis; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/package-info.java deleted file mode 100644 index daf6df05d089..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Elasticsearch concerns. - */ -package org.springframework.boot.actuate.autoconfigure.elasticsearch; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpoint.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpoint.java index 48eaa671eae5..12b0d1872ee0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpoint.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpoint.java @@ -34,9 +34,9 @@ * endpoint is considered available if it is both enabled and exposed on the specified * technologies. *

- * Matches enablement according to the endpoints specific {@link Environment} property, - * falling back to {@code management.endpoints.enabled-by-default} or failing that - * {@link Endpoint#enableByDefault()}. + * Matches access according to the endpoint's specific {@link Environment} property, + * falling back to {@code management.endpoints.default-access} or failing that + * {@link Endpoint#defaultAccess()}. *

* Matches exposure according to any of the {@code management.endpoints.web.exposure.} * or {@code management.endpoints.jmx.exposure.} specific properties or failing that diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java index 792841cf9f12..bfa82f7c8c85 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java @@ -17,7 +17,6 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.condition; import java.util.Arrays; -import java.util.Collection; import java.util.EnumSet; import java.util.LinkedHashSet; import java.util.List; @@ -126,8 +125,7 @@ private ConditionOutcome getMatchOutcome(ConditionContext context, private ConditionOutcome getAccessOutcome(Environment environment, MergedAnnotation endpointAnnotation, EndpointId endpointId, ConditionMessage.Builder message) { Access defaultAccess = endpointAnnotation.getEnum("defaultAccess", Access.class); - boolean enableByDefault = endpointAnnotation.getBoolean("enableByDefault"); - Access access = getAccess(environment, endpointId, (enableByDefault) ? defaultAccess : Access.NONE); + Access access = getAccess(environment, endpointId, defaultAccess); return new ConditionOutcome(access != Access.NONE, message.because("the configured access for endpoint '%s' is %s".formatted(endpointId, access))); } @@ -153,17 +151,8 @@ private ConditionOutcome getExposureOutcome(ConditionContext context, private Set getExposures(MergedAnnotation conditionAnnotation) { EndpointExposure[] exposures = conditionAnnotation.getEnumArray("exposure", EndpointExposure.class); - return replaceCloudFoundryExposure( - (exposures.length == 0) ? EnumSet.allOf(EndpointExposure.class) : Arrays.asList(exposures)); - } - - @SuppressWarnings("removal") - private Set replaceCloudFoundryExposure(Collection exposures) { - Set result = EnumSet.copyOf(exposures); - if (result.remove(EndpointExposure.CLOUD_FOUNDRY)) { - result.add(EndpointExposure.WEB); - } - return result; + return (exposures.length == 0) ? EnumSet.allOf(EndpointExposure.class) + : EnumSet.copyOf(Arrays.asList(exposures)); } private Set getExposureOutcomeContributors(ConditionContext context) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/expose/EndpointExposure.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/expose/EndpointExposure.java index c79e228fe021..769b7029a248 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/expose/EndpointExposure.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/expose/EndpointExposure.java @@ -32,16 +32,7 @@ public enum EndpointExposure { /** * Exposed over a web endpoint. */ - WEB("health"), - - /** - * Exposed on Cloud Foundry over `/cloudfoundryapplication`. - * @since 2.6.4 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of using - * {@link EndpointExposure#WEB} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - CLOUD_FOUNDRY("*"); + WEB("health"); private final String[] defaultIncludes; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jackson/JacksonEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jackson/JacksonEndpointAutoConfiguration.java index 7466b7309d26..4d2f9a7a25f3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jackson/JacksonEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jackson/JacksonEndpointAutoConfiguration.java @@ -16,6 +16,9 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.jackson; +import java.util.HashSet; +import java.util.Set; + import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -25,9 +28,9 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.util.ClassUtils; /** * {@link EnableAutoConfiguration Auto-configuration} for Endpoint Jackson support. @@ -35,10 +38,12 @@ * @author Phillip Webb * @since 3.0.0 */ -@AutoConfiguration(after = JacksonAutoConfiguration.class) +@AutoConfiguration @SuppressWarnings("removal") public class JacksonEndpointAutoConfiguration { + private static final String CONTRIBUTED_HEALTH = "org.springframework.boot.health.contributor.ContributedHealth"; + @Bean @ConditionalOnBooleanProperty(name = "management.endpoints.jackson.isolated-object-mapper", matchIfMissing = true) @ConditionalOnClass({ ObjectMapper.class, Jackson2ObjectMapperBuilder.class }) @@ -48,7 +53,24 @@ public EndpointObjectMapper endpointObjectMapper() { SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS) .serializationInclusion(Include.NON_NULL) .build(); - return () -> objectMapper; + Set> supportedTypes = new HashSet<>(EndpointObjectMapper.DEFAULT_SUPPORTED_TYPES); + if (ClassUtils.isPresent(CONTRIBUTED_HEALTH, null)) { + supportedTypes.add(ClassUtils.resolveClassName(CONTRIBUTED_HEALTH, null)); + } + return new EndpointObjectMapper() { + + @Override + public ObjectMapper get() { + return objectMapper; + } + + @Override + public Set> getSupportedTypes() { + return supportedTypes; + } + + }; + } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.java deleted file mode 100644 index 615a511bc675..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.endpoint.web; - -import org.glassfish.jersey.server.ResourceConfig; - -import org.springframework.boot.actuate.autoconfigure.endpoint.expose.IncludeExcludeEndpointFilter; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; -import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.DispatcherServlet; - -/** - * {@link ManagementContextConfiguration @ManagementContextConfiguration} for servlet - * endpoints. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @author Madhura Bhave - * @since 2.0.0 - */ -@ManagementContextConfiguration(proxyBeanMethods = false) -@ConditionalOnWebApplication(type = Type.SERVLET) -public class ServletEndpointManagementContextConfiguration { - - @Bean - @SuppressWarnings("removal") - public IncludeExcludeEndpointFilter servletExposeExcludePropertyEndpointFilter( - WebEndpointProperties properties) { - WebEndpointProperties.Exposure exposure = properties.getExposure(); - return new IncludeExcludeEndpointFilter<>( - org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint.class, exposure.getInclude(), - exposure.getExclude()); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(DispatcherServlet.class) - public static class WebMvcServletEndpointManagementContextConfiguration { - - @Bean - @SuppressWarnings({ "deprecation", "removal" }) - public org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar servletEndpointRegistrar( - WebEndpointProperties properties, - org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier servletEndpointsSupplier, - DispatcherServletPath dispatcherServletPath, EndpointAccessResolver endpointAccessResolver) { - return new org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar( - dispatcherServletPath.getRelativePath(properties.getBasePath()), - servletEndpointsSupplier.getEndpoints(), endpointAccessResolver); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(ResourceConfig.class) - @ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") - public static class JerseyServletEndpointManagementContextConfiguration { - - @Bean - @SuppressWarnings({ "deprecation", "removal" }) - public org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar servletEndpointRegistrar( - WebEndpointProperties properties, - org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier servletEndpointsSupplier, - JerseyApplicationPath jerseyApplicationPath, EndpointAccessResolver endpointAccessResolver) { - return new org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar( - jerseyApplicationPath.getRelativePath(properties.getBasePath()), - servletEndpointsSupplier.getEndpoints(), endpointAccessResolver); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/package-info.java deleted file mode 100644 index 45674ea419f2..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for exposing actuator web endpoints using Jersey. - */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/package-info.java deleted file mode 100644 index dd5e148a8ced..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for exposing actuator web endpoints using WebFlux. - */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/package-info.java deleted file mode 100644 index fe2e3bf97f07..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for exposing actuator web endpoints using Spring MVC. - */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/flyway/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/flyway/package-info.java deleted file mode 100644 index 7acdc0bc8988..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/flyway/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Flyway concerns. - */ -package org.springframework.boot.actuate.autoconfigure.flyway; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java deleted file mode 100644 index e10706926b9a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Hazelcast concerns. - */ -package org.springframework.boot.actuate.autoconfigure.hazelcast; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthContributorRegistry.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthContributorRegistry.java deleted file mode 100644 index ad1a2a02ba96..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthContributorRegistry.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.health; - -import java.util.Collection; -import java.util.Map; - -import org.springframework.boot.actuate.health.DefaultHealthContributorRegistry; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthContributorRegistry; -import org.springframework.util.Assert; - -/** - * An auto-configured {@link HealthContributorRegistry} that ensures registered indicators - * do not clash with groups names. - * - * @author Phillip Webb - */ -class AutoConfiguredHealthContributorRegistry extends DefaultHealthContributorRegistry { - - private final Collection groupNames; - - AutoConfiguredHealthContributorRegistry(Map contributors, - Collection groupNames) { - super(contributors); - this.groupNames = groupNames; - contributors.keySet().forEach(this::assertDoesNotClashWithGroup); - } - - @Override - public void registerContributor(String name, HealthContributor contributor) { - assertDoesNotClashWithGroup(name); - super.registerContributor(name, contributor); - } - - private void assertDoesNotClashWithGroup(String name) { - Assert.state(!this.groupNames.contains(name), - () -> "HealthContributor with name \"" + name + "\" clashes with group"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredReactiveHealthContributorRegistry.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredReactiveHealthContributorRegistry.java deleted file mode 100644 index 463d7e00684a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredReactiveHealthContributorRegistry.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.health; - -import java.util.Collection; -import java.util.Map; - -import org.springframework.boot.actuate.health.DefaultReactiveHealthContributorRegistry; -import org.springframework.boot.actuate.health.HealthContributorRegistry; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.util.Assert; - -/** - * An auto-configured {@link HealthContributorRegistry} that ensures registered indicators - * do not clash with groups names. - * - * @author Phillip Webb - */ -class AutoConfiguredReactiveHealthContributorRegistry extends DefaultReactiveHealthContributorRegistry { - - private final Collection groupNames; - - AutoConfiguredReactiveHealthContributorRegistry(Map contributors, - Collection groupNames) { - super(contributors); - this.groupNames = groupNames; - contributors.keySet().forEach(this::assertDoesNotClashWithGroup); - } - - @Override - public void registerContributor(String name, ReactiveHealthContributor contributor) { - assertDoesNotClashWithGroup(name); - super.registerContributor(name, contributor); - } - - private void assertDoesNotClashWithGroup(String name) { - Assert.state(!this.groupNames.contains(name), - () -> "ReactiveHealthContributor with name \"" + name + "\" clashes with group"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/GroupsHealthContributorNameValidator.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/GroupsHealthContributorNameValidator.java new file mode 100644 index 000000000000..ef6c05cbdb39 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/GroupsHealthContributorNameValidator.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.health; + +import java.util.Collections; +import java.util.Set; + +import org.springframework.boot.actuate.health.HealthEndpointGroups; +import org.springframework.boot.health.registry.HealthContributorNameValidator; +import org.springframework.util.Assert; + +/** + * {@link HealthContributorNameValidator} to ensure names don't clash with groups. + * + * @author Phillip Webb + */ +class GroupsHealthContributorNameValidator implements HealthContributorNameValidator { + + private final Set groupNames; + + GroupsHealthContributorNameValidator(HealthEndpointGroups groups) { + this.groupNames = (groups != null) ? groups.getNames() : Collections.emptySet(); + } + + @Override + public void validate(String name) throws IllegalStateException { + Assert.state(!this.groupNames.contains(name), + () -> "HealthContributor with name \"" + name + "\" clashes with group"); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfiguration.java index 88ec76e22f11..adf59f9d0e6b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfiguration.java @@ -20,7 +20,10 @@ import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.health.contributor.Health; import org.springframework.context.annotation.Import; /** @@ -32,11 +35,14 @@ * @author Scott Frederick * @since 2.0.0 */ -@AutoConfiguration +@AutoConfiguration( + afterName = "org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration") +@ConditionalOnClass(Health.class) +@ConditionalOnBean(type = "org.springframework.boot.health.registry.HealthContributorRegistry") @ConditionalOnAvailableEndpoint(HealthEndpoint.class) @EnableConfigurationProperties(HealthEndpointProperties.class) -@Import({ HealthEndpointConfiguration.class, ReactiveHealthEndpointConfiguration.class, - HealthEndpointWebExtensionConfiguration.class, HealthEndpointReactiveWebExtensionConfiguration.class }) +@Import({ HealthEndpointConfiguration.class, HealthEndpointWebExtensionConfiguration.class, + HealthEndpointReactiveWebExtensionConfiguration.class }) public class HealthEndpointAutoConfiguration { } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.java index 3488eb283908..72e188e969c6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.java @@ -16,39 +16,26 @@ package org.springframework.boot.actuate.autoconfigure.health; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.CompositeReactiveHealthContributor; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthContributorRegistry; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; import org.springframework.boot.actuate.health.HealthEndpointGroupsPostProcessor; -import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.HttpCodeStatusMapper; -import org.springframework.boot.actuate.health.NamedContributor; -import org.springframework.boot.actuate.health.NamedContributors; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; import org.springframework.boot.actuate.health.SimpleHttpCodeStatusMapper; import org.springframework.boot.actuate.health.SimpleStatusAggregator; import org.springframework.boot.actuate.health.StatusAggregator; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.health.contributor.HealthContributors; +import org.springframework.boot.health.registry.HealthContributorRegistry; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; /** @@ -80,14 +67,9 @@ AutoConfiguredHealthEndpointGroups healthEndpointGroups(ApplicationContext appli } @Bean - @ConditionalOnMissingBean - HealthContributorRegistry healthContributorRegistry(ApplicationContext applicationContext, - HealthEndpointGroups groups, Map healthContributors, - Map reactiveHealthContributors) { - if (ClassUtils.isPresent("reactor.core.publisher.Flux", applicationContext.getClassLoader())) { - healthContributors.putAll(new AdaptedReactiveHealthContributors(reactiveHealthContributors).get()); - } - return new AutoConfiguredHealthContributorRegistry(healthContributors, groups.getNames()); + GroupsHealthContributorNameValidator groupsHealthContributorNameValidator( + ObjectProvider healthEndpointGroups) { + return new GroupsHealthContributorNameValidator(healthEndpointGroups.getIfAvailable()); } @Bean @@ -140,82 +122,6 @@ private Object applyPostProcessors(HealthEndpointGroups bean) { } - /** - * Adapter to expose {@link ReactiveHealthContributor} beans as - * {@link HealthContributor} instances. - */ - private static class AdaptedReactiveHealthContributors { - - private final Map adapted; - - AdaptedReactiveHealthContributors(Map reactiveContributors) { - Map adapted = new LinkedHashMap<>(); - reactiveContributors.forEach((name, contributor) -> adapted.put(name, adapt(contributor))); - this.adapted = Collections.unmodifiableMap(adapted); - } - - private HealthContributor adapt(ReactiveHealthContributor contributor) { - if (contributor instanceof ReactiveHealthIndicator healthIndicator) { - return adapt(healthIndicator); - } - if (contributor instanceof CompositeReactiveHealthContributor healthContributor) { - return adapt(healthContributor); - } - throw new IllegalStateException("Unsupported ReactiveHealthContributor type " + contributor.getClass()); - } - - private HealthIndicator adapt(ReactiveHealthIndicator indicator) { - return new HealthIndicator() { - - @Override - public Health getHealth(boolean includeDetails) { - return indicator.getHealth(includeDetails).block(); - } - - @Override - public Health health() { - return indicator.health().block(); - } - - }; - } - - private CompositeHealthContributor adapt(CompositeReactiveHealthContributor composite) { - return new CompositeHealthContributor() { - - @Override - public Iterator> iterator() { - Iterator> iterator = composite.iterator(); - return new Iterator<>() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public NamedContributor next() { - NamedContributor next = iterator.next(); - return NamedContributor.of(next.getName(), adapt(next.getContributor())); - } - - }; - } - - @Override - public HealthContributor getContributor(String name) { - return adapt(composite.getContributor(name)); - } - - }; - } - - Map get() { - return this.adapted; - } - - } - /** * {@link SmartInitializingSingleton} that validates health endpoint group membership, * throwing a {@link NoSuchHealthContributorException} if an included or excluded @@ -264,10 +170,10 @@ private boolean contributorExists(String[] path) { int pathOffset = 0; Object contributor = this.registry; while (pathOffset < path.length) { - if (!(contributor instanceof NamedContributors)) { + if (!(contributor instanceof HealthContributors)) { return false; } - contributor = ((NamedContributors) contributor).getContributor(path[pathOffset]); + contributor = ((HealthContributors) contributor).getContributor(path[pathOffset]); pathOffset++; } return (contributor != null); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java index 76b1458d79c5..d165acc25200 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointReactiveWebExtensionConfiguration.java @@ -16,23 +16,16 @@ package org.springframework.boot.actuate.autoconfigure.health; -import java.util.Collection; - import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; -import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; -import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.endpoint.web.reactive.AdditionalHealthEndpointPathsWebFluxHandlerMapping; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; -import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.health.registry.ReactiveHealthContributorRegistry; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -58,21 +51,4 @@ ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension( properties.getLogging().getSlowIndicatorThreshold()); } - @Configuration(proxyBeanMethods = false) - static class WebFluxAdditionalHealthEndpointPathsConfiguration { - - @Bean - AdditionalHealthEndpointPathsWebFluxHandlerMapping healthEndpointWebFluxHandlerMapping( - WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) { - Collection webEndpoints = webEndpointsSupplier.getEndpoints(); - ExposableWebEndpoint health = webEndpoints.stream() - .filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)) - .findFirst() - .orElse(null); - return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), health, - groups.getAllWithAdditionalPath(WebServerNamespace.SERVER)); - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java index 799c1d193116..9b1dd0ca8ea3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java @@ -16,43 +16,18 @@ package org.springframework.boot.actuate.autoconfigure.health; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; - -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.model.Resource; -import org.glassfish.jersey.servlet.ServletContainer; - -import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; -import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; -import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.endpoint.web.jersey.JerseyHealthEndpointAdditionalPathResourceFactory; -import org.springframework.boot.actuate.endpoint.web.servlet.AdditionalHealthEndpointPathsWebMvcHandlerMapping; -import org.springframework.boot.actuate.health.HealthContributorRegistry; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; import org.springframework.boot.actuate.health.HealthEndpointWebExtension; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.jersey.JerseyProperties; -import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; -import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.boot.health.registry.HealthContributorRegistry; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.DispatcherServlet; /** * Configuration for {@link HealthEndpoint} web extensions. @@ -75,102 +50,4 @@ HealthEndpointWebExtension healthEndpointWebExtension(HealthContributorRegistry properties.getLogging().getSlowIndicatorThreshold()); } - private static ExposableWebEndpoint getHealthEndpoint(WebEndpointsSupplier webEndpointsSupplier) { - Collection webEndpoints = webEndpointsSupplier.getEndpoints(); - return webEndpoints.stream() - .filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)) - .findFirst() - .orElse(null); - } - - @ConditionalOnBean(DispatcherServlet.class) - static class MvcAdditionalHealthEndpointPathsConfiguration { - - @Bean - AdditionalHealthEndpointPathsWebMvcHandlerMapping healthEndpointWebMvcHandlerMapping( - WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) { - ExposableWebEndpoint health = getHealthEndpoint(webEndpointsSupplier); - return new AdditionalHealthEndpointPathsWebMvcHandlerMapping(health, - groups.getAllWithAdditionalPath(WebServerNamespace.SERVER)); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(ResourceConfig.class) - @ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") - static class JerseyAdditionalHealthEndpointPathsConfiguration { - - @Bean - JerseyAdditionalHealthEndpointPathsResourcesRegistrar jerseyAdditionalHealthEndpointPathsResourcesRegistrar( - WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups healthEndpointGroups) { - ExposableWebEndpoint health = getHealthEndpoint(webEndpointsSupplier); - return new JerseyAdditionalHealthEndpointPathsResourcesRegistrar(health, healthEndpointGroups); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(ResourceConfig.class) - @EnableConfigurationProperties(JerseyProperties.class) - static class JerseyInfrastructureConfiguration { - - @Bean - @ConditionalOnMissingBean - JerseyApplicationPath jerseyApplicationPath(JerseyProperties properties, ResourceConfig config) { - return new DefaultJerseyApplicationPath(properties.getApplicationPath(), config); - } - - @Bean - ResourceConfig resourceConfig(ObjectProvider resourceConfigCustomizers) { - ResourceConfig resourceConfig = new ResourceConfig(); - resourceConfigCustomizers.orderedStream().forEach((customizer) -> customizer.customize(resourceConfig)); - return resourceConfig; - } - - @Bean - ServletRegistrationBean jerseyServletRegistration( - JerseyApplicationPath jerseyApplicationPath, ResourceConfig resourceConfig) { - return new ServletRegistrationBean<>(new ServletContainer(resourceConfig), - jerseyApplicationPath.getUrlMapping()); - } - - } - - } - - static class JerseyAdditionalHealthEndpointPathsResourcesRegistrar implements ResourceConfigCustomizer { - - private final ExposableWebEndpoint endpoint; - - private final HealthEndpointGroups groups; - - JerseyAdditionalHealthEndpointPathsResourcesRegistrar(ExposableWebEndpoint endpoint, - HealthEndpointGroups groups) { - this.endpoint = endpoint; - this.groups = groups; - } - - @Override - public void customize(ResourceConfig config) { - register(config); - } - - private void register(ResourceConfig config) { - EndpointMapping mapping = new EndpointMapping(""); - JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory( - WebServerNamespace.SERVER, this.groups); - Collection endpointResources = resourceFactory - .createEndpointResources(mapping, - (this.endpoint != null) ? Collections.singletonList(this.endpoint) : Collections.emptyList()) - .stream() - .filter(Objects::nonNull) - .toList(); - register(endpointResources, config); - } - - private void register(Collection resources, ResourceConfig config) { - config.registerResources(new HashSet<>(resources)); - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/OnEnabledHealthIndicatorCondition.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/OnEnabledHealthIndicatorCondition.java deleted file mode 100644 index 308f620e4f9e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/OnEnabledHealthIndicatorCondition.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.health; - -import org.springframework.boot.actuate.autoconfigure.OnEndpointElementCondition; -import org.springframework.context.annotation.Condition; - -/** - * {@link Condition} that checks if a health indicator is enabled. - * - * @author Stephane Nicoll - */ -class OnEnabledHealthIndicatorCondition extends OnEndpointElementCondition { - - OnEnabledHealthIndicatorCondition() { - super("management.health.", ConditionalOnEnabledHealthIndicator.class); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/ReactiveHealthEndpointConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/ReactiveHealthEndpointConfiguration.java deleted file mode 100644 index 1c1fbffb5a55..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/ReactiveHealthEndpointConfiguration.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.health; - -import java.util.LinkedHashMap; -import java.util.Map; - -import reactor.core.publisher.Flux; - -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthEndpoint; -import org.springframework.boot.actuate.health.HealthEndpointGroups; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Configuration for reactive {@link HealthEndpoint} infrastructure beans. - * - * @author Phillip Webb - * @see HealthEndpointAutoConfiguration - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(Flux.class) -@ConditionalOnBean(HealthEndpoint.class) -class ReactiveHealthEndpointConfiguration { - - @Bean - @ConditionalOnMissingBean - ReactiveHealthContributorRegistry reactiveHealthContributorRegistry( - Map healthContributors, - Map reactiveHealthContributors, HealthEndpointGroups groups) { - Map allContributors = new LinkedHashMap<>(reactiveHealthContributors); - healthContributors.forEach((name, contributor) -> allContributors.computeIfAbsent(name, - (key) -> ReactiveHealthContributor.adapt(contributor))); - return new AutoConfiguredReactiveHealthContributorRegistry(allContributors, groups.getNames()); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java index 4c41b459250f..16f8a7841f01 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.java @@ -16,7 +16,6 @@ package org.springframework.boot.actuate.autoconfigure.info; -import org.springframework.boot.actuate.autoconfigure.ssl.SslHealthIndicatorProperties; import org.springframework.boot.actuate.info.BuildInfoContributor; import org.springframework.boot.actuate.info.EnvironmentInfoContributor; import org.springframework.boot.actuate.info.GitInfoContributor; @@ -50,7 +49,7 @@ * @since 2.0.0 */ @AutoConfiguration(after = ProjectInfoAutoConfiguration.class) -@EnableConfigurationProperties({ InfoContributorProperties.class, SslHealthIndicatorProperties.class }) +@EnableConfigurationProperties(InfoContributorProperties.class) public class InfoContributorAutoConfiguration { /** diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/integration/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/integration/package-info.java deleted file mode 100644 index 49b258993242..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/integration/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Spring Integration concerns. - */ -package org.springframework.boot.actuate.autoconfigure.integration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/package-info.java deleted file mode 100644 index 763dee2d446c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator JDBC concerns. - */ -package org.springframework.boot.actuate.autoconfigure.jdbc; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jms/JmsHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jms/JmsHealthContributorAutoConfiguration.java deleted file mode 100644 index 675dc2ff0fbc..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jms/JmsHealthContributorAutoConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.jms; - -import jakarta.jms.ConnectionFactory; - -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.jms.JmsHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration; -import org.springframework.context.annotation.Bean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for {@link JmsHealthIndicator}. - * - * @author Stephane Nicoll - * @since 2.0.0 - */ -@AutoConfiguration(after = { ActiveMQAutoConfiguration.class, ArtemisAutoConfiguration.class }) -@ConditionalOnClass(ConnectionFactory.class) -@ConditionalOnBean(ConnectionFactory.class) -@ConditionalOnEnabledHealthIndicator("jms") -public class JmsHealthContributorAutoConfiguration - extends CompositeHealthContributorConfiguration { - - public JmsHealthContributorAutoConfiguration() { - super(JmsHealthIndicator::new); - } - - @Bean - @ConditionalOnMissingBean(name = { "jmsHealthIndicator", "jmsHealthContributor" }) - public HealthContributor jmsHealthContributor(ConfigurableListableBeanFactory beanFactory) { - return createContributor(beanFactory, ConnectionFactory.class); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jms/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jms/package-info.java deleted file mode 100644 index 60147502a5e1..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jms/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator JMS concerns. - */ -package org.springframework.boot.actuate.autoconfigure.jms; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ldap/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ldap/package-info.java deleted file mode 100644 index 66d471f2fc50..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ldap/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator LDAP concerns. - */ -package org.springframework.boot.actuate.autoconfigure.ldap; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/liquibase/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/liquibase/package-info.java deleted file mode 100644 index 4104bb7aa22a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/liquibase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Liquibase concerns. - */ -package org.springframework.boot.actuate.autoconfigure.liquibase; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/OpenTelemetryLoggingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/OpenTelemetryLoggingAutoConfiguration.java deleted file mode 100644 index 496e8c1a92a7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/OpenTelemetryLoggingAutoConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.logs.LogRecordProcessor; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; -import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; -import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import io.opentelemetry.sdk.resources.Resource; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry logging. - * - * @author Toshiaki Maki - * @since 3.4.0 - */ -@AutoConfiguration -@ConditionalOnClass({ SdkLoggerProvider.class, OpenTelemetry.class }) -public class OpenTelemetryLoggingAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - BatchLogRecordProcessor batchLogRecordProcessor(ObjectProvider logRecordExporters) { - return BatchLogRecordProcessor.builder(LogRecordExporter.composite(logRecordExporters.orderedStream().toList())) - .build(); - } - - @Bean - @ConditionalOnMissingBean - SdkLoggerProvider otelSdkLoggerProvider(Resource resource, ObjectProvider logRecordProcessors, - ObjectProvider customizers) { - SdkLoggerProviderBuilder builder = SdkLoggerProvider.builder().setResource(resource); - logRecordProcessors.orderedStream().forEach(builder::addLogRecordProcessor); - customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); - return builder.build(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfiguration.java deleted file mode 100644 index 75664310499f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging.otlp; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for OTLP logging. - * - * @author Toshiaki Maki - * @since 3.4.0 - */ -@AutoConfiguration -@ConditionalOnClass({ SdkLoggerProvider.class, OpenTelemetry.class, OtlpHttpLogRecordExporter.class }) -@EnableConfigurationProperties(OtlpLoggingProperties.class) -@Import({ OtlpLoggingConfigurations.ConnectionDetails.class, OtlpLoggingConfigurations.Exporters.class }) -public class OtlpLoggingAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingConfigurations.java deleted file mode 100644 index 78062b101bf8..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingConfigurations.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging.otlp; - -import java.util.Locale; - -import io.opentelemetry.api.metrics.MeterProvider; -import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; -import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.logging.ConditionalOnEnabledLoggingExport; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.Assert; - -/** - * Configurations imported by {@link OtlpLoggingAutoConfiguration}. - * - * @author Toshiaki Maki - */ -final class OtlpLoggingConfigurations { - - @Configuration(proxyBeanMethods = false) - static class ConnectionDetails { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty("management.otlp.logging.endpoint") - OtlpLoggingConnectionDetails otlpLoggingConnectionDetails(OtlpLoggingProperties properties) { - return new PropertiesOtlpLoggingConnectionDetails(properties); - } - - /** - * Adapts {@link OtlpLoggingProperties} to {@link OtlpLoggingConnectionDetails}. - */ - static class PropertiesOtlpLoggingConnectionDetails implements OtlpLoggingConnectionDetails { - - private final OtlpLoggingProperties properties; - - PropertiesOtlpLoggingConnectionDetails(OtlpLoggingProperties properties) { - this.properties = properties; - } - - @Override - public String getUrl(Transport transport) { - Assert.state(transport == this.properties.getTransport(), - "Requested transport %s doesn't match configured transport %s".formatted(transport, - this.properties.getTransport())); - return this.properties.getEndpoint(); - } - - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean({ OtlpGrpcLogRecordExporter.class, OtlpHttpLogRecordExporter.class }) - @ConditionalOnBean(OtlpLoggingConnectionDetails.class) - @ConditionalOnEnabledLoggingExport("otlp") - static class Exporters { - - @Bean - @ConditionalOnProperty(name = "management.otlp.logging.transport", havingValue = "http", matchIfMissing = true) - OtlpHttpLogRecordExporter otlpHttpLogRecordExporter(OtlpLoggingProperties properties, - OtlpLoggingConnectionDetails connectionDetails, ObjectProvider meterProvider) { - OtlpHttpLogRecordExporterBuilder builder = OtlpHttpLogRecordExporter.builder() - .setEndpoint(connectionDetails.getUrl(Transport.HTTP)) - .setTimeout(properties.getTimeout()) - .setConnectTimeout(properties.getConnectTimeout()) - .setCompression(properties.getCompression().name().toLowerCase(Locale.US)); - properties.getHeaders().forEach(builder::addHeader); - meterProvider.ifAvailable(builder::setMeterProvider); - return builder.build(); - } - - @Bean - @ConditionalOnProperty(name = "management.otlp.logging.transport", havingValue = "grpc") - OtlpGrpcLogRecordExporter otlpGrpcLogRecordExporter(OtlpLoggingProperties properties, - OtlpLoggingConnectionDetails connectionDetails, ObjectProvider meterProvider) { - OtlpGrpcLogRecordExporterBuilder builder = OtlpGrpcLogRecordExporter.builder() - .setEndpoint(connectionDetails.getUrl(Transport.GRPC)) - .setTimeout(properties.getTimeout()) - .setConnectTimeout(properties.getConnectTimeout()) - .setCompression(properties.getCompression().name().toLowerCase(Locale.US)); - properties.getHeaders().forEach(builder::addHeader); - meterProvider.ifAvailable(builder::setMeterProvider); - return builder.build(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingConnectionDetails.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingConnectionDetails.java deleted file mode 100644 index ef6aff95e2c3..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingConnectionDetails.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging.otlp; - -import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; - -/** - * Details required to establish a connection to an OpenTelemetry logging service. - * - * @author Toshiaki Maki - * @since 3.4.0 - */ -public interface OtlpLoggingConnectionDetails extends ConnectionDetails { - - /** - * Address to where logs will be published. - * @param transport the transport to use - * @return the address to where logs will be published - */ - String getUrl(Transport transport); - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingProperties.java deleted file mode 100644 index 56bec05324c6..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingProperties.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging.otlp; - -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration properties for exporting logs using OTLP. - * - * @author Jonatan Ivanov - * @since 3.4.0 - */ -@ConfigurationProperties("management.otlp.logging") -public class OtlpLoggingProperties { - - /** - * URL to the OTel collector's HTTP API. - */ - private String endpoint; - - /** - * Call timeout for the OTel Collector to process an exported batch of data. This - * timeout spans the entire call: resolving DNS, connecting, writing the request body, - * server processing, and reading the response body. If the call requires redirects or - * retries all must complete within one timeout period. - */ - private Duration timeout = Duration.ofSeconds(10); - - /** - * Connect timeout for the OTel collector connection. - */ - private Duration connectTimeout = Duration.ofSeconds(10); - - /** - * Transport used to send the logs. - */ - private Transport transport = Transport.HTTP; - - /** - * Method used to compress the payload. - */ - private Compression compression = Compression.NONE; - - /** - * Custom HTTP headers you want to pass to the collector, for example auth headers. - */ - private final Map headers = new HashMap<>(); - - public String getEndpoint() { - return this.endpoint; - } - - public void setEndpoint(String endpoint) { - this.endpoint = endpoint; - } - - public Duration getTimeout() { - return this.timeout; - } - - public void setTimeout(Duration timeout) { - this.timeout = timeout; - } - - public Duration getConnectTimeout() { - return this.connectTimeout; - } - - public void setConnectTimeout(Duration connectTimeout) { - this.connectTimeout = connectTimeout; - } - - public Transport getTransport() { - return this.transport; - } - - public void setTransport(Transport transport) { - this.transport = transport; - } - - public Compression getCompression() { - return this.compression; - } - - public void setCompression(Compression compression) { - this.compression = compression; - } - - public Map getHeaders() { - return this.headers; - } - - public enum Compression { - - /** - * Gzip compression. - */ - GZIP, - - /** - * No compression. - */ - NONE - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/Transport.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/Transport.java deleted file mode 100644 index 67e41e69a712..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/Transport.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging.otlp; - -/** - * Transport used to send OTLP data. - * - * @author Moritz Halbritter - * @since 3.4.0 - */ -public enum Transport { - - /** - * HTTP transport. - */ - HTTP, - - /** - * gRPC transport. - */ - GRPC - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/package-info.java deleted file mode 100644 index 6a6696dd10c7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for exporting logs with OTLP. - */ -package org.springframework.boot.actuate.autoconfigure.logging.otlp; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mail/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mail/package-info.java deleted file mode 100644 index 8bca08d48e5f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mail/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator JavaMail concerns. - */ -package org.springframework.boot.actuate.autoconfigure.mail; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/AutoTimeProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/AutoTimeProperties.java deleted file mode 100644 index a12615400ed9..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/AutoTimeProperties.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics; - -/** - * Nested configuration properties for items that are automatically timed. - * - * @author Tadaya Tsuyukubo - * @author Stephane Nicoll - * @author Phillip Webb - * @since 2.2.0 - */ -public final class AutoTimeProperties { - - /** - * Whether to enable auto-timing. - */ - private boolean enabled = true; - - /** - * Whether to publish percentile histograms. - */ - private boolean percentilesHistogram; - - /** - * Percentiles for which additional time series should be published. - */ - private double[] percentiles; - - /** - * Create an instance that automatically time requests with no percentiles. - */ - public AutoTimeProperties() { - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isPercentilesHistogram() { - return this.percentilesHistogram; - } - - public void setPercentilesHistogram(boolean percentilesHistogram) { - this.percentilesHistogram = percentilesHistogram; - } - - public double[] getPercentiles() { - return this.percentiles; - } - - public void setPercentiles(double[] percentiles) { - this.percentiles = percentiles; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/package-info.java deleted file mode 100644 index 3c6fcc2be718..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for RabbitMQ metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.amqp; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfiguration.java deleted file mode 100644 index f6c5d0f662a3..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfiguration.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.cache; - -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.cache.Cache; -import org.springframework.cache.CacheManager; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for metrics on all available - * {@link Cache caches}. - * - * @author Stephane Nicoll - * @since 2.0.0 - */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, CacheAutoConfiguration.class }) -@ConditionalOnBean(CacheManager.class) -@Import({ CacheMeterBinderProvidersConfiguration.class, CacheMetricsRegistrarConfiguration.class }) -public class CacheMetricsAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/package-info.java deleted file mode 100644 index 1fd8ab3e22cc..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for cache metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.cache; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfiguration.java deleted file mode 100644 index 1d9936cd142c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfiguration.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.data; - -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Data.Repository; -import org.springframework.boot.actuate.autoconfigure.metrics.PropertiesAutoTimer; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.metrics.data.DefaultRepositoryTagsProvider; -import org.springframework.boot.actuate.metrics.data.MetricsRepositoryMethodInvocationListener; -import org.springframework.boot.actuate.metrics.data.RepositoryTagsProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.util.function.SingletonSupplier; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Data Repository metrics. - * - * @author Phillip Webb - * @since 2.5.0 - */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, - SimpleMetricsExportAutoConfiguration.class }) -@ConditionalOnClass(org.springframework.data.repository.Repository.class) -@ConditionalOnBean(MeterRegistry.class) -@EnableConfigurationProperties(MetricsProperties.class) -public class RepositoryMetricsAutoConfiguration { - - private final MetricsProperties properties; - - public RepositoryMetricsAutoConfiguration(MetricsProperties properties) { - this.properties = properties; - } - - @Bean - @ConditionalOnMissingBean(RepositoryTagsProvider.class) - public DefaultRepositoryTagsProvider repositoryTagsProvider() { - return new DefaultRepositoryTagsProvider(); - } - - @Bean - @ConditionalOnMissingBean - public MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocationListener( - ObjectProvider registry, RepositoryTagsProvider tagsProvider) { - Repository properties = this.properties.getData().getRepository(); - return new MetricsRepositoryMethodInvocationListener(registry::getObject, tagsProvider, - properties.getMetricName(), new PropertiesAutoTimer(properties.getAutotime())); - } - - @Bean - public static MetricsRepositoryMethodInvocationListenerBeanPostProcessor metricsRepositoryMethodInvocationListenerBeanPostProcessor( - ObjectProvider metricsRepositoryMethodInvocationListener) { - return new MetricsRepositoryMethodInvocationListenerBeanPostProcessor( - SingletonSupplier.of(metricsRepositoryMethodInvocationListener::getObject)); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/package-info.java deleted file mode 100644 index e6a041cb4389..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data actuator metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.data; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/package-info.java deleted file mode 100644 index b5f2dc4eb5a7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to AppOptics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/package-info.java deleted file mode 100644 index 6739718622f3..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Atlas. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/package-info.java deleted file mode 100644 index d372c3211918..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Datadog. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/package-info.java deleted file mode 100644 index 0d4b10be442d..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Dynatrace. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/package-info.java deleted file mode 100644 index de34b9fbe6aa..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Elastic. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.elastic; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/package-info.java deleted file mode 100644 index 5048c3f71765..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Ganglia. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/package-info.java deleted file mode 100644 index a7a2afe69872..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Graphite. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.graphite; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/package-info.java deleted file mode 100644 index 9d36d9df55bb..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Humio. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/package-info.java deleted file mode 100644 index ef1ee9c35218..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to InfluxDB. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.influx; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/package-info.java deleted file mode 100644 index b00a39303b36..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to JMX. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.jmx; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/package-info.java deleted file mode 100644 index 339db02c7e64..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to KairosDB. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.kairos; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/package-info.java deleted file mode 100644 index 698c59e89e67..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to New Relic. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/package-info.java deleted file mode 100644 index d4c7dba03c04..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to OTLP. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/package-info.java deleted file mode 100644 index a6bf7ff936d3..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for metrics exporter. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/package-info.java deleted file mode 100644 index 21161cbebd96..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Prometheus. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/package-info.java deleted file mode 100644 index aae56789286c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Base properties and adapters used when exporting actuator metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxMetricsExportAutoConfiguration.java deleted file mode 100644 index 141accbea542..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxMetricsExportAutoConfiguration.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx; - -import io.micrometer.core.instrument.Clock; -import io.micrometer.signalfx.SignalFxConfig; -import io.micrometer.signalfx.SignalFxMeterRegistry; - -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to SignalFX. - * - * @author Jon Schneider - * @author Andy Wilkinson - * @since 2.0.0 - * @deprecated since 3.5.0 for removal in 4.0.0 - */ -@AutoConfiguration( - before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, - after = MetricsAutoConfiguration.class) -@ConditionalOnBean(Clock.class) -@ConditionalOnClass(SignalFxMeterRegistry.class) -@ConditionalOnEnabledMetricsExport("signalfx") -@EnableConfigurationProperties(SignalFxProperties.class) -@Deprecated(since = "3.5.0", forRemoval = true) -@SuppressWarnings("removal") -public class SignalFxMetricsExportAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public SignalFxConfig signalfxConfig(SignalFxProperties props) { - return new SignalFxPropertiesConfigAdapter(props); - } - - @Bean - @ConditionalOnMissingBean - public SignalFxMeterRegistry signalFxMeterRegistry(SignalFxConfig config, Clock clock) { - return new SignalFxMeterRegistry(config, clock); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxProperties.java deleted file mode 100644 index 58054919687a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxProperties.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx; - -import java.time.Duration; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; - -/** - * {@link ConfigurationProperties @ConfigurationProperties} for configuring metrics export - * to SignalFX. - * - * @author Jon Schneider - * @author Andy Wilkinson - * @author Stephane Nicoll - * @since 2.0.0 - * @deprecated since 3.5.0 for removal in 4.0.0 - */ -@ConfigurationProperties("management.signalfx.metrics.export") -@Deprecated(since = "3.5.0", forRemoval = true) -public class SignalFxProperties extends StepRegistryProperties { - - /** - * Step size (i.e. reporting frequency) to use. - */ - private Duration step = Duration.ofSeconds(10); - - /** - * SignalFX access token. - */ - private String accessToken; - - /** - * URI to ship metrics to. - */ - private String uri = "https://ingest.signalfx.com"; - - /** - * Uniquely identifies the app instance that is publishing metrics to SignalFx. - * Defaults to the local host name. - */ - private String source; - - /** - * Type of histogram to publish. - */ - private HistogramType publishedHistogramType = HistogramType.DEFAULT; - - @Override - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public Duration getStep() { - return this.step; - } - - @Override - @Deprecated(since = "3.5.0", forRemoval = true) - public void setStep(Duration step) { - this.step = step; - } - - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public String getAccessToken() { - return this.accessToken; - } - - @Deprecated(since = "3.5.0", forRemoval = true) - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public String getUri() { - return this.uri; - } - - @Deprecated(since = "3.5.0", forRemoval = true) - public void setUri(String uri) { - this.uri = uri; - } - - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public String getSource() { - return this.source; - } - - @Deprecated(since = "3.5.0", forRemoval = true) - public void setSource(String source) { - this.source = source; - } - - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public HistogramType getPublishedHistogramType() { - return this.publishedHistogramType; - } - - @Deprecated(since = "3.5.0", forRemoval = true) - public void setPublishedHistogramType(HistogramType publishedHistogramType) { - this.publishedHistogramType = publishedHistogramType; - } - - @Override - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public boolean isEnabled() { - return super.isEnabled(); - } - - @Override - @Deprecated(since = "3.5.0", forRemoval = true) - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - } - - @Override - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public Duration getConnectTimeout() { - return super.getConnectTimeout(); - } - - @Override - @Deprecated(since = "3.5.0", forRemoval = true) - public void setConnectTimeout(Duration connectTimeout) { - super.setConnectTimeout(connectTimeout); - } - - @Override - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public Duration getReadTimeout() { - return super.getReadTimeout(); - } - - @Override - @Deprecated(since = "3.5.0", forRemoval = true) - public void setReadTimeout(Duration readTimeout) { - super.setReadTimeout(readTimeout); - } - - @Override - @DeprecatedConfigurationProperty(since = "3.5.0", reason = "Deprecated in Micrometer 1.15.0") - @Deprecated(since = "3.5.0", forRemoval = true) - public Integer getBatchSize() { - return super.getBatchSize(); - } - - @Override - @Deprecated(since = "3.5.0", forRemoval = true) - public void setBatchSize(Integer batchSize) { - super.setBatchSize(batchSize); - } - - @Deprecated(since = "3.5.0", forRemoval = true) - public enum HistogramType { - - /** - * Default, time-based histogram. - */ - DEFAULT, - - /** - * Cumulative histogram. - */ - CUMULATIVE, - - /** - * Delta histogram. - */ - DELTA - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapter.java deleted file mode 100644 index 11ffa9e07211..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapter.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx; - -import io.micrometer.signalfx.SignalFxConfig; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; - -/** - * Adapter to convert {@link SignalFxProperties} to a {@link SignalFxConfig}. - * - * @author Jon Schneider - * @since 2.0.0 - * @deprecated since 3.5.0 for removal in 4.0.0 - */ -@Deprecated(since = "3.5.0", forRemoval = true) -@SuppressWarnings("removal") -public class SignalFxPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter - implements SignalFxConfig { - - public SignalFxPropertiesConfigAdapter(SignalFxProperties properties) { - super(properties); - accessToken(); // validate that an access token is set - } - - @Override - public String prefix() { - return "management.signalfx.metrics.export"; - } - - @Override - public String accessToken() { - return get(SignalFxProperties::getAccessToken, SignalFxConfig.super::accessToken); - } - - @Override - public String uri() { - return get(SignalFxProperties::getUri, SignalFxConfig.super::uri); - } - - @Override - public String source() { - return get(SignalFxProperties::getSource, SignalFxConfig.super::source); - } - - @Override - public boolean publishCumulativeHistogram() { - return get(this::isPublishCumulativeHistogram, SignalFxConfig.super::publishCumulativeHistogram); - } - - private boolean isPublishCumulativeHistogram(SignalFxProperties properties) { - return SignalFxProperties.HistogramType.CUMULATIVE == properties.getPublishedHistogramType(); - } - - @Override - public boolean publishDeltaHistogram() { - return get(this::isPublishDeltaHistogram, SignalFxConfig.super::publishDeltaHistogram); - } - - private boolean isPublishDeltaHistogram(SignalFxProperties properties) { - return SignalFxProperties.HistogramType.DELTA == properties.getPublishedHistogramType(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/package-info.java deleted file mode 100644 index b295fd6d21f5..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to SignalFX. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/package-info.java deleted file mode 100644 index c6583b9e318e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to a simple in-memory store. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.simple; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/package-info.java deleted file mode 100644 index e5c6b7dadc5c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to Stackdriver. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/package-info.java deleted file mode 100644 index 6c6892fc590f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for exporting actuator metrics to StatsD. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/IntegrationMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/IntegrationMetricsAutoConfiguration.java deleted file mode 100644 index c4b074d6dddf..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/IntegrationMetricsAutoConfiguration.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.integration; - -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Integration's metrics. - * Orders auto-configuration classes to ensure that the {@link MeterRegistry} bean has - * been defined before Spring Integration's Micrometer support queries the bean factory - * for it. - * - * @author Andy Wilkinson - */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }, - before = IntegrationAutoConfiguration.class) -class IntegrationMetricsAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/package-info.java deleted file mode 100644 index 57965e5954ad..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Integration metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.integration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/package-info.java deleted file mode 100644 index 2344f7d02c54..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for JPA metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.jdbc; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/package-info.java deleted file mode 100644 index 8ff53fca4d27..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Jersey actuator metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.jersey; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/package-info.java deleted file mode 100644 index 4253e5340375..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Mongo metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.mongo; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/package-info.java deleted file mode 100644 index 078b31181514..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for JPA metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/package-info.java deleted file mode 100644 index 4416185b6279..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator metrics and Micrometer. - */ -package org.springframework.boot.actuate.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/package-info.java deleted file mode 100644 index 2e1802d8c8c6..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for R2DBC metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.r2dbc; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/package-info.java deleted file mode 100644 index 870cd65c49f9..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Redis metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.redis; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/package-info.java deleted file mode 100644 index 7937a39d642b..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator startup time metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.startup; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/package-info.java deleted file mode 100644 index 0ae742b0d95e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for task execution and scheduling metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.task; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/package-info.java deleted file mode 100644 index 7cc6cdd79a8f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Jetty actuator metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.web.jetty; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/package-info.java deleted file mode 100644 index fc098467e097..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Tomcat actuator metrics. - */ -package org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorAutoConfiguration.java deleted file mode 100644 index 75210369554a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorAutoConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.neo4j; - -import org.neo4j.driver.Driver; - -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.neo4j.Neo4jHealthContributorConfigurations.Neo4jConfiguration; -import org.springframework.boot.actuate.autoconfigure.neo4j.Neo4jHealthContributorConfigurations.Neo4jReactiveConfiguration; -import org.springframework.boot.actuate.neo4j.Neo4jHealthIndicator; -import org.springframework.boot.actuate.neo4j.Neo4jReactiveHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for - * {@link Neo4jReactiveHealthIndicator} and {@link Neo4jHealthIndicator}. - * - * @author Eric Spiegelberg - * @author Stephane Nicoll - * @author Michael J. Simons - * @since 2.0.0 - */ -@AutoConfiguration(after = Neo4jAutoConfiguration.class) -@ConditionalOnClass(Driver.class) -@ConditionalOnBean(Driver.class) -@ConditionalOnEnabledHealthIndicator("neo4j") -@Import({ Neo4jReactiveConfiguration.class, Neo4jConfiguration.class }) -public class Neo4jHealthContributorAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/package-info.java deleted file mode 100644 index fa532b022e40..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Neo4J concerns. - */ -package org.springframework.boot.actuate.autoconfigure.neo4j; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java deleted file mode 100644 index 7d479dbdcdf4..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation; - -import java.util.List; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; -import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler.IgnoredMeters; -import io.micrometer.core.instrument.observation.MeterObservationHandler; -import io.micrometer.observation.GlobalObservationConvention; -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationFilter; -import io.micrometer.observation.ObservationHandler; -import io.micrometer.observation.ObservationPredicate; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.observation.aop.ObservedAspect; -import io.micrometer.tracing.Tracer; -import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; -import io.micrometer.tracing.handler.TracingObservationHandler; -import org.aspectj.weaver.Advice; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for the Micrometer Observation API. - * - * @author Moritz Halbritter - * @author Brian Clozel - * @author Jonatan Ivanov - * @author Vedran Pavic - * @since 3.0.0 - */ -@AutoConfiguration(after = { CompositeMeterRegistryAutoConfiguration.class, MicrometerTracingAutoConfiguration.class }) -@ConditionalOnClass(ObservationRegistry.class) -@EnableConfigurationProperties(ObservationProperties.class) -public class ObservationAutoConfiguration { - - @Bean - static ObservationRegistryPostProcessor observationRegistryPostProcessor( - ObjectProvider> observationRegistryCustomizers, - ObjectProvider observationPredicates, - ObjectProvider> observationConventions, - ObjectProvider> observationHandlers, - ObjectProvider observationHandlerGrouping, - ObjectProvider observationFilters) { - return new ObservationRegistryPostProcessor(observationRegistryCustomizers, observationPredicates, - observationConventions, observationHandlers, observationHandlerGrouping, observationFilters); - } - - @Bean - @ConditionalOnMissingBean - ObservationRegistry observationRegistry() { - return ObservationRegistry.create(); - } - - @Bean - @Order(0) - PropertiesObservationFilterPredicate propertiesObservationFilter(ObservationProperties properties) { - return new PropertiesObservationFilterPredicate(properties); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(MeterRegistry.class) - @ConditionalOnMissingClass("io.micrometer.tracing.Tracer") - static class OnlyMetricsConfiguration { - - @Bean - ObservationHandlerGrouping metricsObservationHandlerGrouping() { - return new ObservationHandlerGrouping(MeterObservationHandler.class); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Tracer.class) - @ConditionalOnMissingClass("io.micrometer.core.instrument.MeterRegistry") - static class OnlyTracingConfiguration { - - @Bean - ObservationHandlerGrouping tracingObservationHandlerGrouping() { - return new ObservationHandlerGrouping(TracingObservationHandler.class); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ MeterRegistry.class, Tracer.class }) - static class MetricsWithTracingConfiguration { - - @Bean - ObservationHandlerGrouping metricsAndTracingObservationHandlerGrouping() { - return new ObservationHandlerGrouping( - List.of(TracingObservationHandler.class, MeterObservationHandler.class)); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnBean(MeterRegistry.class) - @ConditionalOnMissingBean(MeterObservationHandler.class) - static class MeterObservationHandlerConfiguration { - - @ConditionalOnMissingBean(type = "io.micrometer.tracing.Tracer") - @Configuration(proxyBeanMethods = false) - static class OnlyMetricsMeterObservationHandlerConfiguration { - - @Bean - DefaultMeterObservationHandler defaultMeterObservationHandler(MeterRegistry meterRegistry, - ObservationProperties properties) { - return properties.getLongTaskTimer().isEnabled() ? new DefaultMeterObservationHandler(meterRegistry) - : new DefaultMeterObservationHandler(meterRegistry, IgnoredMeters.LONG_TASK_TIMER); - } - - } - - @ConditionalOnBean(Tracer.class) - @Configuration(proxyBeanMethods = false) - static class TracingAndMetricsObservationHandlerConfiguration { - - @Bean - TracingAwareMeterObservationHandler tracingAwareMeterObservationHandler( - MeterRegistry meterRegistry, Tracer tracer, ObservationProperties properties) { - DefaultMeterObservationHandler delegate = properties.getLongTaskTimer().isEnabled() - ? new DefaultMeterObservationHandler(meterRegistry) - : new DefaultMeterObservationHandler(meterRegistry, IgnoredMeters.LONG_TASK_TIMER); - return new TracingAwareMeterObservationHandler<>(delegate, tracer); - } - - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Advice.class) - @ConditionalOnBooleanProperty("management.observations.annotations.enabled") - static class ObservedAspectConfiguration { - - @Bean - @ConditionalOnMissingBean - ObservedAspect observedAspect(ObservationRegistry observationRegistry) { - return new ObservedAspect(observationRegistry); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGrouping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGrouping.java deleted file mode 100644 index 432bf593d31b..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGrouping.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation; - -import java.util.ArrayList; -import java.util.List; - -import io.micrometer.observation.ObservationHandler; -import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; -import io.micrometer.observation.ObservationRegistry.ObservationConfig; - -import org.springframework.util.CollectionUtils; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -/** - * Groups {@link ObservationHandler ObservationHandlers} by type. - * - * @author Andy Wilkinson - * @author Moritz Halbritter - */ -@SuppressWarnings("rawtypes") -class ObservationHandlerGrouping { - - private final List> categories; - - ObservationHandlerGrouping(Class category) { - this(List.of(category)); - } - - ObservationHandlerGrouping(List> categories) { - this.categories = categories; - } - - void apply(List> handlers, ObservationConfig config) { - MultiValueMap, ObservationHandler> groupings = new LinkedMultiValueMap<>(); - List> handlersWithoutCategory = new ArrayList<>(); - for (ObservationHandler handler : handlers) { - Class category = findCategory(handler); - if (category != null) { - groupings.add(category, handler); - } - else { - handlersWithoutCategory.add(handler); - } - } - for (Class category : this.categories) { - List> handlerGroup = groupings.get(category); - if (!CollectionUtils.isEmpty(handlerGroup)) { - config.observationHandler(new FirstMatchingCompositeObservationHandler(handlerGroup)); - } - } - for (ObservationHandler observationHandler : handlersWithoutCategory) { - config.observationHandler(observationHandler); - } - } - - private Class findCategory(ObservationHandler handler) { - for (Class category : this.categories) { - if (category.isInstance(handler)) { - return category; - } - } - return null; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/batch/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/batch/package-info.java deleted file mode 100644 index 3bc569da068e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/batch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Batch observations. - */ -package org.springframework.boot.actuate.autoconfigure.observation.batch; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/package-info.java deleted file mode 100644 index 80c168ab515f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring GraphQL observations. - */ -package org.springframework.boot.actuate.autoconfigure.observation.graphql; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/package-info.java deleted file mode 100644 index 22958ef9d0ca..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for the Micrometer Observation API. - */ -package org.springframework.boot.actuate.autoconfigure.observation; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java deleted file mode 100644 index e88de01e032e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/HttpClientObservationsAutoConfiguration.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.config.MeterFilter; -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; - -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Client; -import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.annotation.Order; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for HTTP client-related - * observations. - * - * @author Jon Schneider - * @author Phillip Webb - * @author Stephane Nicoll - * @author Raheela Aslam - * @author Brian Clozel - * @author Moritz Halbritter - * @since 3.0.0 - */ -@AutoConfiguration(after = { ObservationAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, - RestTemplateAutoConfiguration.class, WebClientAutoConfiguration.class, RestClientAutoConfiguration.class }) -@ConditionalOnClass(Observation.class) -@ConditionalOnBean(ObservationRegistry.class) -@Import({ RestTemplateObservationConfiguration.class, WebClientObservationConfiguration.class, - RestClientObservationConfiguration.class }) -@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class }) -public class HttpClientObservationsAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(MeterRegistry.class) - @ConditionalOnBean(MeterRegistry.class) - static class MeterFilterConfiguration { - - @Bean - @Order(0) - MeterFilter metricsHttpClientUriTagFilter(ObservationProperties observationProperties, - MetricsProperties metricsProperties) { - Client clientProperties = metricsProperties.getWeb().getClient(); - String name = observationProperties.getHttp().getClient().getRequests().getName(); - MeterFilter denyFilter = new OnlyOnceLoggingDenyMeterFilter( - () -> "Reached the maximum number of URI tags for '%s'. Are you using 'uriVariables'?" - .formatted(name)); - return MeterFilter.maximumAllowableTags(name, "uri", clientProperties.getMaxUriTags(), denyFilter); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfiguration.java deleted file mode 100644 index 92d2650cff84..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import io.micrometer.observation.ObservationRegistry; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties; -import org.springframework.boot.actuate.metrics.web.client.ObservationRestClientCustomizer; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.web.client.RestClientCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.observation.ClientRequestObservationConvention; -import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; -import org.springframework.web.client.RestClient; - -/** - * Configure the instrumentation of {@link RestClient}. - * - * @author Moritz Halbritter - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(RestClient.class) -@ConditionalOnBean(RestClient.Builder.class) -class RestClientObservationConfiguration { - - @Bean - RestClientCustomizer observationRestClientCustomizer(ObservationRegistry observationRegistry, - ObjectProvider customConvention, - ObservationProperties observationProperties) { - String name = observationProperties.getHttp().getClient().getRequests().getName(); - ClientRequestObservationConvention observationConvention = customConvention - .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name)); - return new ObservationRestClientCustomizer(observationRegistry, observationConvention); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfiguration.java deleted file mode 100644 index c458c575077d..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import io.micrometer.observation.ObservationRegistry; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties; -import org.springframework.boot.actuate.metrics.web.client.ObservationRestTemplateCustomizer; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.observation.ClientRequestObservationConvention; -import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; -import org.springframework.web.client.RestTemplate; - -/** - * Configure the instrumentation of {@link RestTemplate}. - * - * @author Brian Clozel - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(RestTemplate.class) -@ConditionalOnBean(RestTemplateBuilder.class) -class RestTemplateObservationConfiguration { - - @Bean - ObservationRestTemplateCustomizer observationRestTemplateCustomizer(ObservationRegistry observationRegistry, - ObjectProvider customConvention, - ObservationProperties observationProperties) { - String name = observationProperties.getHttp().getClient().getRequests().getName(); - ClientRequestObservationConvention observationConvention = customConvention - .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name)); - return new ObservationRestTemplateCustomizer(observationRegistry, observationConvention); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfiguration.java deleted file mode 100644 index 8d06b1d6a027..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import io.micrometer.observation.ObservationRegistry; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties; -import org.springframework.boot.actuate.metrics.web.reactive.client.ObservationWebClientCustomizer; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.function.client.ClientRequestObservationConvention; -import org.springframework.web.reactive.function.client.DefaultClientRequestObservationConvention; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * Configure the instrumentation of {@link WebClient}. - * - * @author Brian Clozel - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(WebClient.class) -class WebClientObservationConfiguration { - - @Bean - ObservationWebClientCustomizer observationWebClientCustomizer(ObservationRegistry observationRegistry, - ObjectProvider customConvention, - ObservationProperties observationProperties, MetricsProperties metricsProperties) { - String name = observationProperties.getHttp().getClient().getRequests().getName(); - ClientRequestObservationConvention observationConvention = customConvention - .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name)); - return new ObservationWebClientCustomizer(observationRegistry, observationConvention); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/package-info.java deleted file mode 100644 index a981b52355fc..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for web client observation support. - */ -package org.springframework.boot.actuate.autoconfigure.observation.web.client; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/package-info.java deleted file mode 100644 index ba2f819b5067..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for WebFlux actuator observations. - */ -package org.springframework.boot.actuate.autoconfigure.observation.web.reactive; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/package-info.java deleted file mode 100644 index c9fc6c644e78..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring MVC observation support. - */ -package org.springframework.boot.actuate.autoconfigure.observation.web.servlet; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfiguration.java deleted file mode 100644 index 0be18e4a7b8d..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfiguration.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.opentelemetry; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.metrics.SdkMeterProvider; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.resources.ResourceBuilder; -import io.opentelemetry.sdk.trace.SdkTracerProvider; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.core.env.Environment; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry. - * - * @author Moritz Halbritter - * @since 3.2.0 - */ -@AutoConfiguration -@ConditionalOnClass(OpenTelemetrySdk.class) -@EnableConfigurationProperties(OpenTelemetryProperties.class) -public class OpenTelemetryAutoConfiguration { - - @Bean - @ConditionalOnMissingBean(OpenTelemetry.class) - OpenTelemetrySdk openTelemetry(ObjectProvider tracerProvider, - ObjectProvider propagators, ObjectProvider loggerProvider, - ObjectProvider meterProvider) { - OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder(); - tracerProvider.ifAvailable(builder::setTracerProvider); - propagators.ifAvailable(builder::setPropagators); - loggerProvider.ifAvailable(builder::setLoggerProvider); - meterProvider.ifAvailable(builder::setMeterProvider); - return builder.build(); - } - - @Bean - @ConditionalOnMissingBean - Resource openTelemetryResource(Environment environment, OpenTelemetryProperties properties) { - Resource resource = Resource.getDefault(); - return resource.merge(toResource(environment, properties)); - } - - private Resource toResource(Environment environment, OpenTelemetryProperties properties) { - ResourceBuilder builder = Resource.builder(); - new OpenTelemetryResourceAttributes(environment, properties.getResourceAttributes()).applyTo(builder::put); - return builder.build(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/package-info.java deleted file mode 100644 index 0c0af1dbd119..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for OpenTelemetry. - */ -package org.springframework.boot.actuate.autoconfigure.opentelemetry; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/package-info.java deleted file mode 100644 index 508c063082a5..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Quartz Scheduler concerns. - */ -package org.springframework.boot.actuate.autoconfigure.quartz; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/ConnectionFactoryHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/ConnectionFactoryHealthContributorAutoConfiguration.java deleted file mode 100644 index 03670b216b75..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/ConnectionFactoryHealthContributorAutoConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.r2dbc; - -import io.r2dbc.spi.ConnectionFactory; - -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.actuate.r2dbc.ConnectionFactoryHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; -import org.springframework.context.annotation.Bean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for - * {@link ConnectionFactoryHealthIndicator}. - * - * @author Mark Paluch - * @since 2.3.0 - */ -@AutoConfiguration(after = R2dbcAutoConfiguration.class) -@ConditionalOnClass(ConnectionFactory.class) -@ConditionalOnBean(ConnectionFactory.class) -@ConditionalOnEnabledHealthIndicator("r2dbc") -public class ConnectionFactoryHealthContributorAutoConfiguration - extends CompositeReactiveHealthContributorConfiguration { - - ConnectionFactoryHealthContributorAutoConfiguration() { - super(ConnectionFactoryHealthIndicator::new); - } - - @Bean - @ConditionalOnMissingBean(name = { "r2dbcHealthIndicator", "r2dbcHealthContributor" }) - public ReactiveHealthContributor r2dbcHealthContributor(ConfigurableListableBeanFactory beanFactory) { - return createContributor(beanFactory, ConnectionFactory.class); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/package-info.java deleted file mode 100644 index fae8c5e152ee..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator R2DBC. - */ -package org.springframework.boot.actuate.autoconfigure.r2dbc; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequest.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequest.java deleted file mode 100644 index 6702142749b7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequest.java +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.security.reactive; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; -import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.security.reactive.ApplicationContextServerWebExchangeMatcher; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.context.ApplicationContext; -import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.http.HttpMethod; -import org.springframework.security.web.server.util.matcher.OrServerWebExchangeMatcher; -import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher.MatchResult; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.server.ServerWebExchange; - -/** - * Factory that can be used to create a {@link ServerWebExchangeMatcher} for actuator - * endpoint locations. - * - * @author Madhura Bhave - * @author Phillip Webb - * @author Chris Bono - * @since 2.0.0 - */ -public final class EndpointRequest { - - private static final ServerWebExchangeMatcher EMPTY_MATCHER = (request) -> MatchResult.notMatch(); - - private EndpointRequest() { - } - - /** - * Returns a matcher that includes all {@link Endpoint actuator endpoints}. It also - * includes the links endpoint which is present at the base path of the actuator - * endpoints. The {@link EndpointServerWebExchangeMatcher#excluding(Class...) - * excluding} method can be used to further remove specific endpoints if required. For - * example:

-	 * EndpointRequest.toAnyEndpoint().excluding(ShutdownEndpoint.class)
-	 * 
- * @return the configured {@link ServerWebExchangeMatcher} - */ - public static EndpointServerWebExchangeMatcher toAnyEndpoint() { - return new EndpointServerWebExchangeMatcher(true); - } - - /** - * Returns a matcher that includes the specified {@link Endpoint actuator endpoints}. - * For example:
-	 * EndpointRequest.to(ShutdownEndpoint.class, HealthEndpoint.class)
-	 * 
- * @param endpoints the endpoints to include - * @return the configured {@link ServerWebExchangeMatcher} - */ - public static EndpointServerWebExchangeMatcher to(Class... endpoints) { - return new EndpointServerWebExchangeMatcher(endpoints, false); - } - - /** - * Returns a matcher that includes the specified {@link Endpoint actuator endpoints}. - * For example:
-	 * EndpointRequest.to("shutdown", "health")
-	 * 
- * @param endpoints the endpoints to include - * @return the configured {@link ServerWebExchangeMatcher} - */ - public static EndpointServerWebExchangeMatcher to(String... endpoints) { - return new EndpointServerWebExchangeMatcher(endpoints, false); - } - - /** - * Returns a matcher that matches only on the links endpoint. It can be used when - * security configuration for the links endpoint is different from the other - * {@link Endpoint actuator endpoints}. The - * {@link EndpointServerWebExchangeMatcher#excludingLinks() excludingLinks} method can - * be used in combination with this to remove the links endpoint from - * {@link EndpointRequest#toAnyEndpoint() toAnyEndpoint}. For example: - *
-	 * EndpointRequest.toLinks()
-	 * 
- * @return the configured {@link ServerWebExchangeMatcher} - */ - public static LinksServerWebExchangeMatcher toLinks() { - return new LinksServerWebExchangeMatcher(); - } - - /** - * Returns a matcher that includes additional paths under a {@link WebServerNamespace} - * for the specified {@link Endpoint actuator endpoints}. For example: - *
-	 * EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "health")
-	 * 
- * @param webServerNamespace the web server namespace - * @param endpoints the endpoints to include - * @return the configured {@link RequestMatcher} - * @since 3.4.0 - */ - public static AdditionalPathsEndpointServerWebExchangeMatcher toAdditionalPaths( - WebServerNamespace webServerNamespace, Class... endpoints) { - return new AdditionalPathsEndpointServerWebExchangeMatcher(webServerNamespace, endpoints); - } - - /** - * Returns a matcher that includes additional paths under a {@link WebServerNamespace} - * for the specified {@link Endpoint actuator endpoints}. For example: - *
-	 * EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, HealthEndpoint.class)
-	 * 
- * @param webServerNamespace the web server namespace - * @param endpoints the endpoints to include - * @return the configured {@link RequestMatcher} - * @since 3.4.0 - */ - public static AdditionalPathsEndpointServerWebExchangeMatcher toAdditionalPaths( - WebServerNamespace webServerNamespace, String... endpoints) { - return new AdditionalPathsEndpointServerWebExchangeMatcher(webServerNamespace, endpoints); - } - - /** - * Base class for supported request matchers. - */ - private abstract static class AbstractWebExchangeMatcher extends ApplicationContextServerWebExchangeMatcher { - - private volatile ServerWebExchangeMatcher delegate; - - private volatile ManagementPortType managementPortType; - - AbstractWebExchangeMatcher(Class contextClass) { - super(contextClass); - } - - @Override - protected void initialized(Supplier supplier) { - this.delegate = createDelegate(supplier); - } - - private ServerWebExchangeMatcher createDelegate(Supplier context) { - try { - return createDelegate(context.get()); - } - catch (NoSuchBeanDefinitionException ex) { - return EMPTY_MATCHER; - } - } - - protected abstract ServerWebExchangeMatcher createDelegate(C context); - - protected final List getDelegateMatchers(Set paths, HttpMethod httpMethod) { - return paths.stream() - .map((path) -> getDelegateMatcher(path, httpMethod)) - .collect(Collectors.toCollection(ArrayList::new)); - } - - private PathPatternParserServerWebExchangeMatcher getDelegateMatcher(String path, HttpMethod httpMethod) { - Assert.notNull(path, "'path' must not be null"); - return new PathPatternParserServerWebExchangeMatcher(path + "/**", httpMethod); - } - - @Override - protected Mono matches(ServerWebExchange exchange, Supplier context) { - return this.delegate.matches(exchange); - } - - @Override - protected boolean ignoreApplicationContext(ApplicationContext applicationContext) { - ManagementPortType managementPortType = this.managementPortType; - if (managementPortType == null) { - managementPortType = ManagementPortType.get(applicationContext.getEnvironment()); - this.managementPortType = managementPortType; - } - return ignoreApplicationContext(applicationContext, managementPortType); - } - - protected boolean ignoreApplicationContext(ApplicationContext applicationContext, - ManagementPortType managementPortType) { - return managementPortType == ManagementPortType.DIFFERENT - && !hasWebServerNamespace(applicationContext, WebServerNamespace.MANAGEMENT); - } - - protected final boolean hasWebServerNamespace(ApplicationContext applicationContext, - WebServerNamespace webServerNamespace) { - return WebServerApplicationContext.hasServerNamespace(applicationContext, webServerNamespace.getValue()) - || hasImplicitServerNamespace(applicationContext, webServerNamespace); - } - - private boolean hasImplicitServerNamespace(ApplicationContext applicationContext, - WebServerNamespace webServerNamespace) { - return WebServerNamespace.SERVER.equals(webServerNamespace) - && WebServerApplicationContext.getServerNamespace(applicationContext) == null - && applicationContext.getParent() == null; - } - - protected final String toString(List endpoints, String emptyValue) { - return (!endpoints.isEmpty()) ? endpoints.stream() - .map(this::getEndpointId) - .map(Object::toString) - .collect(Collectors.joining(", ", "[", "]")) : emptyValue; - } - - protected final EndpointId getEndpointId(Object source) { - if (source instanceof EndpointId endpointId) { - return endpointId; - } - if (source instanceof String string) { - return EndpointId.of(string); - } - if (source instanceof Class) { - return getEndpointId((Class) source); - } - throw new IllegalStateException("Unsupported source " + source); - } - - private EndpointId getEndpointId(Class source) { - MergedAnnotation annotation = MergedAnnotations.from(source).get(Endpoint.class); - Assert.state(annotation.isPresent(), () -> "Class " + source + " is not annotated with @Endpoint"); - return EndpointId.of(annotation.getString("id")); - } - - } - - /** - * The {@link ServerWebExchangeMatcher} used to match against {@link Endpoint actuator - * endpoints}. - */ - public static final class EndpointServerWebExchangeMatcher extends AbstractWebExchangeMatcher { - - private final List includes; - - private final List excludes; - - private final boolean includeLinks; - - private final HttpMethod httpMethod; - - private EndpointServerWebExchangeMatcher(boolean includeLinks) { - this(Collections.emptyList(), Collections.emptyList(), includeLinks, null); - } - - private EndpointServerWebExchangeMatcher(Class[] endpoints, boolean includeLinks) { - this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks, null); - } - - private EndpointServerWebExchangeMatcher(String[] endpoints, boolean includeLinks) { - this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks, null); - } - - private EndpointServerWebExchangeMatcher(List includes, List excludes, boolean includeLinks, - HttpMethod httpMethod) { - super(PathMappedEndpoints.class); - this.includes = includes; - this.excludes = excludes; - this.includeLinks = includeLinks; - this.httpMethod = httpMethod; - } - - public EndpointServerWebExchangeMatcher excluding(Class... endpoints) { - List excludes = new ArrayList<>(this.excludes); - excludes.addAll(Arrays.asList((Object[]) endpoints)); - return new EndpointServerWebExchangeMatcher(this.includes, excludes, this.includeLinks, null); - } - - public EndpointServerWebExchangeMatcher excluding(String... endpoints) { - List excludes = new ArrayList<>(this.excludes); - excludes.addAll(Arrays.asList((Object[]) endpoints)); - return new EndpointServerWebExchangeMatcher(this.includes, excludes, this.includeLinks, null); - } - - public EndpointServerWebExchangeMatcher excludingLinks() { - return new EndpointServerWebExchangeMatcher(this.includes, this.excludes, false, null); - } - - /** - * Restricts the matcher to only consider requests with a particular http method. - * @param httpMethod the http method to include - * @return a copy of the matcher further restricted to only match requests with - * the specified http method - */ - public EndpointServerWebExchangeMatcher withHttpMethod(HttpMethod httpMethod) { - return new EndpointServerWebExchangeMatcher(this.includes, this.excludes, this.includeLinks, httpMethod); - } - - @Override - protected ServerWebExchangeMatcher createDelegate(PathMappedEndpoints endpoints) { - Set paths = new LinkedHashSet<>(); - if (this.includes.isEmpty()) { - paths.addAll(endpoints.getAllPaths()); - } - streamPaths(this.includes, endpoints).forEach(paths::add); - streamPaths(this.excludes, endpoints).forEach(paths::remove); - List delegateMatchers = getDelegateMatchers(paths, this.httpMethod); - if (this.includeLinks && StringUtils.hasText(endpoints.getBasePath())) { - delegateMatchers.add(new LinksServerWebExchangeMatcher()); - } - if (delegateMatchers.isEmpty()) { - return EMPTY_MATCHER; - } - return new OrServerWebExchangeMatcher(delegateMatchers); - } - - private Stream streamPaths(List source, PathMappedEndpoints endpoints) { - return source.stream() - .filter(Objects::nonNull) - .map(this::getEndpointId) - .map(endpoints::getPath) - .filter(Objects::nonNull); - } - - @Override - public String toString() { - return String.format("EndpointRequestMatcher includes=%s, excludes=%s, includeLinks=%s", - toString(this.includes, "[*]"), toString(this.excludes, "[]"), this.includeLinks); - } - - } - - /** - * The {@link ServerWebExchangeMatcher} used to match against the links endpoint. - */ - public static final class LinksServerWebExchangeMatcher extends AbstractWebExchangeMatcher { - - private LinksServerWebExchangeMatcher() { - super(WebEndpointProperties.class); - } - - @Override - protected ServerWebExchangeMatcher createDelegate(WebEndpointProperties properties) { - if (StringUtils.hasText(properties.getBasePath())) { - return new OrServerWebExchangeMatcher( - new PathPatternParserServerWebExchangeMatcher(properties.getBasePath()), - new PathPatternParserServerWebExchangeMatcher(properties.getBasePath() + "/")); - } - return EMPTY_MATCHER; - } - - @Override - public String toString() { - return String.format("LinksServerWebExchangeMatcher"); - } - - } - - /** - * The {@link ServerWebExchangeMatcher} used to match against additional paths for - * {@link Endpoint actuator endpoints}. - */ - public static class AdditionalPathsEndpointServerWebExchangeMatcher - extends AbstractWebExchangeMatcher { - - private final WebServerNamespace webServerNamespace; - - private final List endpoints; - - private final HttpMethod httpMethod; - - AdditionalPathsEndpointServerWebExchangeMatcher(WebServerNamespace webServerNamespace, String... endpoints) { - this(webServerNamespace, Arrays.asList((Object[]) endpoints), null); - } - - AdditionalPathsEndpointServerWebExchangeMatcher(WebServerNamespace webServerNamespace, Class... endpoints) { - this(webServerNamespace, Arrays.asList((Object[]) endpoints), null); - } - - private AdditionalPathsEndpointServerWebExchangeMatcher(WebServerNamespace webServerNamespace, - List endpoints, HttpMethod httpMethod) { - super(PathMappedEndpoints.class); - Assert.notNull(webServerNamespace, "'webServerNamespace' must not be null"); - Assert.notNull(endpoints, "'endpoints' must not be null"); - Assert.notEmpty(endpoints, "'endpoints' must not be empty"); - this.webServerNamespace = webServerNamespace; - this.endpoints = endpoints; - this.httpMethod = httpMethod; - } - - /** - * Restricts the matcher to only consider requests with a particular HTTP method. - * @param httpMethod the HTTP method to include - * @return a copy of the matcher further restricted to only match requests with - * the specified HTTP method - * @since 3.5.0 - */ - public AdditionalPathsEndpointServerWebExchangeMatcher withHttpMethod(HttpMethod httpMethod) { - return new AdditionalPathsEndpointServerWebExchangeMatcher(this.webServerNamespace, this.endpoints, - httpMethod); - } - - @Override - protected boolean ignoreApplicationContext(ApplicationContext applicationContext, - ManagementPortType managementPortType) { - return !hasWebServerNamespace(applicationContext, this.webServerNamespace); - } - - @Override - protected ServerWebExchangeMatcher createDelegate(PathMappedEndpoints endpoints) { - Set paths = this.endpoints.stream() - .filter(Objects::nonNull) - .map(this::getEndpointId) - .flatMap((endpointId) -> streamAdditionalPaths(endpoints, endpointId)) - .collect(Collectors.toCollection(LinkedHashSet::new)); - List delegateMatchers = getDelegateMatchers(paths, this.httpMethod); - return (!CollectionUtils.isEmpty(delegateMatchers)) ? new OrServerWebExchangeMatcher(delegateMatchers) - : EMPTY_MATCHER; - } - - private Stream streamAdditionalPaths(PathMappedEndpoints pathMappedEndpoints, EndpointId endpointId) { - return pathMappedEndpoints.getAdditionalPaths(this.webServerNamespace, endpointId).stream(); - } - - @Override - public String toString() { - return String.format("AdditionalPathsEndpointServerWebExchangeMatcher endpoints=%s, webServerNamespace=%s", - toString(this.endpoints, ""), this.webServerNamespace); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/package-info.java deleted file mode 100644 index 9c2d4b4ce03e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator security using WebFlux. - */ -package org.springframework.boot.actuate.autoconfigure.security.reactive; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java deleted file mode 100644 index 772ed58be3b9..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.security.servlet; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import jakarta.servlet.http.HttpServletRequest; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; -import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.context.ApplicationContext; -import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.http.HttpMethod; -import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; -import org.springframework.security.web.util.matcher.OrRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.context.WebApplicationContext; - -/** - * Factory that can be used to create a {@link RequestMatcher} for actuator endpoint - * locations. - * - * @author Madhura Bhave - * @author Phillip Webb - * @author Chris Bono - * @since 2.0.0 - */ -public final class EndpointRequest { - - private static final RequestMatcher EMPTY_MATCHER = (request) -> false; - - private EndpointRequest() { - } - - /** - * Returns a matcher that includes all {@link Endpoint actuator endpoints}. It also - * includes the links endpoint which is present at the base path of the actuator - * endpoints. The {@link EndpointRequestMatcher#excluding(Class...) excluding} method - * can be used to further remove specific endpoints if required. For example: - *
-	 * EndpointRequest.toAnyEndpoint().excluding(ShutdownEndpoint.class)
-	 * 
- * @return the configured {@link RequestMatcher} - */ - public static EndpointRequestMatcher toAnyEndpoint() { - return new EndpointRequestMatcher(true); - } - - /** - * Returns a matcher that includes the specified {@link Endpoint actuator endpoints}. - * For example:
-	 * EndpointRequest.to(ShutdownEndpoint.class, HealthEndpoint.class)
-	 * 
- * @param endpoints the endpoints to include - * @return the configured {@link RequestMatcher} - */ - public static EndpointRequestMatcher to(Class... endpoints) { - return new EndpointRequestMatcher(endpoints, false); - } - - /** - * Returns a matcher that includes the specified {@link Endpoint actuator endpoints}. - * For example:
-	 * EndpointRequest.to("shutdown", "health")
-	 * 
- * @param endpoints the endpoints to include - * @return the configured {@link RequestMatcher} - */ - public static EndpointRequestMatcher to(String... endpoints) { - return new EndpointRequestMatcher(endpoints, false); - } - - /** - * Returns a matcher that matches only on the links endpoint. It can be used when - * security configuration for the links endpoint is different from the other - * {@link Endpoint actuator endpoints}. The - * {@link EndpointRequestMatcher#excludingLinks() excludingLinks} method can be used - * in combination with this to remove the links endpoint from - * {@link EndpointRequest#toAnyEndpoint() toAnyEndpoint}. For example: - *
-	 * EndpointRequest.toLinks()
-	 * 
- * @return the configured {@link RequestMatcher} - */ - public static LinksRequestMatcher toLinks() { - return new LinksRequestMatcher(); - } - - /** - * Returns a matcher that includes additional paths under a {@link WebServerNamespace} - * for the specified {@link Endpoint actuator endpoints}. For example: - *
-	 * EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "health")
-	 * 
- * @param webServerNamespace the web server namespace - * @param endpoints the endpoints to include - * @return the configured {@link RequestMatcher} - * @since 3.4.0 - */ - public static AdditionalPathsEndpointRequestMatcher toAdditionalPaths(WebServerNamespace webServerNamespace, - Class... endpoints) { - return new AdditionalPathsEndpointRequestMatcher(webServerNamespace, endpoints); - } - - /** - * Returns a matcher that includes additional paths under a {@link WebServerNamespace} - * for the specified {@link Endpoint actuator endpoints}. For example: - *
-	 * EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, HealthEndpoint.class)
-	 * 
- * @param webServerNamespace the web server namespace - * @param endpoints the endpoints to include - * @return the configured {@link RequestMatcher} - * @since 3.4.0 - */ - public static AdditionalPathsEndpointRequestMatcher toAdditionalPaths(WebServerNamespace webServerNamespace, - String... endpoints) { - return new AdditionalPathsEndpointRequestMatcher(webServerNamespace, endpoints); - } - - /** - * Base class for supported request matchers. - */ - private abstract static class AbstractRequestMatcher - extends ApplicationContextRequestMatcher { - - private volatile RequestMatcher delegate; - - private volatile ManagementPortType managementPortType; - - AbstractRequestMatcher() { - super(WebApplicationContext.class); - } - - @Override - protected boolean ignoreApplicationContext(WebApplicationContext applicationContext) { - ManagementPortType managementPortType = this.managementPortType; - if (managementPortType == null) { - managementPortType = ManagementPortType.get(applicationContext.getEnvironment()); - this.managementPortType = managementPortType; - } - return ignoreApplicationContext(applicationContext, managementPortType); - } - - protected boolean ignoreApplicationContext(WebApplicationContext applicationContext, - ManagementPortType managementPortType) { - return managementPortType == ManagementPortType.DIFFERENT - && !hasWebServerNamespace(applicationContext, WebServerNamespace.MANAGEMENT); - } - - protected final boolean hasWebServerNamespace(ApplicationContext applicationContext, - WebServerNamespace webServerNamespace) { - return WebServerApplicationContext.hasServerNamespace(applicationContext, webServerNamespace.getValue()) - || hasImplicitServerNamespace(applicationContext, webServerNamespace); - } - - private boolean hasImplicitServerNamespace(ApplicationContext applicationContext, - WebServerNamespace webServerNamespace) { - return WebServerNamespace.SERVER.equals(webServerNamespace) - && WebServerApplicationContext.getServerNamespace(applicationContext) == null - && applicationContext.getParent() == null; - } - - @Override - protected final void initialized(Supplier context) { - this.delegate = createDelegate(context.get()); - } - - @Override - protected final boolean matches(HttpServletRequest request, Supplier context) { - return this.delegate.matches(request); - } - - private RequestMatcher createDelegate(WebApplicationContext context) { - try { - return createDelegate(context, new RequestMatcherFactory()); - } - catch (NoSuchBeanDefinitionException ex) { - return EMPTY_MATCHER; - } - } - - protected abstract RequestMatcher createDelegate(WebApplicationContext context, - RequestMatcherFactory requestMatcherFactory); - - protected final List getDelegateMatchers(RequestMatcherFactory requestMatcherFactory, - RequestMatcherProvider matcherProvider, Set paths, HttpMethod httpMethod) { - return paths.stream() - .map((path) -> requestMatcherFactory.antPath(matcherProvider, httpMethod, path, "/**")) - .collect(Collectors.toCollection(ArrayList::new)); - } - - protected List getLinksMatchers(RequestMatcherFactory requestMatcherFactory, - RequestMatcherProvider matcherProvider, String basePath) { - List linksMatchers = new ArrayList<>(); - linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, basePath)); - linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, basePath, "/")); - return linksMatchers; - } - - protected RequestMatcherProvider getRequestMatcherProvider(WebApplicationContext context) { - try { - return getRequestMatcherProviderBean(context); - } - catch (NoSuchBeanDefinitionException ex) { - return (pattern, method) -> PathPatternRequestMatcher.withDefaults().matcher(method, pattern); - } - } - - private RequestMatcherProvider getRequestMatcherProviderBean(WebApplicationContext context) { - try { - return context.getBean(RequestMatcherProvider.class); - } - catch (NoSuchBeanDefinitionException ex) { - return getAndAdaptDeprecatedRequestMatcherProviderBean(context); - } - } - - @SuppressWarnings("removal") - private RequestMatcherProvider getAndAdaptDeprecatedRequestMatcherProviderBean(WebApplicationContext context) { - org.springframework.boot.autoconfigure.security.servlet.RequestMatcherProvider bean = context - .getBean(org.springframework.boot.autoconfigure.security.servlet.RequestMatcherProvider.class); - return (pattern, method) -> bean.getRequestMatcher(pattern); - } - - protected String toString(List endpoints, String emptyValue) { - return (!endpoints.isEmpty()) ? endpoints.stream() - .map(this::getEndpointId) - .map(Object::toString) - .collect(Collectors.joining(", ", "[", "]")) : emptyValue; - } - - protected EndpointId getEndpointId(Object source) { - if (source instanceof EndpointId endpointId) { - return endpointId; - } - if (source instanceof String string) { - return EndpointId.of(string); - } - if (source instanceof Class sourceClass) { - return getEndpointId(sourceClass); - } - throw new IllegalStateException("Unsupported source " + source); - } - - private EndpointId getEndpointId(Class source) { - MergedAnnotation annotation = MergedAnnotations.from(source).get(Endpoint.class); - Assert.state(annotation.isPresent(), () -> "Class " + source + " is not annotated with @Endpoint"); - return EndpointId.of(annotation.getString("id")); - } - - } - - /** - * The request matcher used to match against {@link Endpoint actuator endpoints}. - */ - public static final class EndpointRequestMatcher extends AbstractRequestMatcher { - - private final List includes; - - private final List excludes; - - private final boolean includeLinks; - - private final HttpMethod httpMethod; - - private EndpointRequestMatcher(boolean includeLinks) { - this(Collections.emptyList(), Collections.emptyList(), includeLinks, null); - } - - private EndpointRequestMatcher(Class[] endpoints, boolean includeLinks) { - this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks, null); - } - - private EndpointRequestMatcher(String[] endpoints, boolean includeLinks) { - this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks, null); - } - - private EndpointRequestMatcher(List includes, List excludes, boolean includeLinks, - HttpMethod httpMethod) { - this.includes = includes; - this.excludes = excludes; - this.includeLinks = includeLinks; - this.httpMethod = httpMethod; - } - - public EndpointRequestMatcher excluding(Class... endpoints) { - List excludes = new ArrayList<>(this.excludes); - excludes.addAll(Arrays.asList((Object[]) endpoints)); - return new EndpointRequestMatcher(this.includes, excludes, this.includeLinks, null); - } - - public EndpointRequestMatcher excluding(String... endpoints) { - List excludes = new ArrayList<>(this.excludes); - excludes.addAll(Arrays.asList((Object[]) endpoints)); - return new EndpointRequestMatcher(this.includes, excludes, this.includeLinks, null); - } - - public EndpointRequestMatcher excludingLinks() { - return new EndpointRequestMatcher(this.includes, this.excludes, false, null); - } - - /** - * Restricts the matcher to only consider requests with a particular HTTP method. - * @param httpMethod the HTTP method to include - * @return a copy of the matcher further restricted to only match requests with - * the specified HTTP method - * @since 3.5.0 - */ - public EndpointRequestMatcher withHttpMethod(HttpMethod httpMethod) { - return new EndpointRequestMatcher(this.includes, this.excludes, this.includeLinks, httpMethod); - } - - @Override - protected RequestMatcher createDelegate(WebApplicationContext context, - RequestMatcherFactory requestMatcherFactory) { - PathMappedEndpoints endpoints = context.getBean(PathMappedEndpoints.class); - RequestMatcherProvider matcherProvider = getRequestMatcherProvider(context); - Set paths = new LinkedHashSet<>(); - if (this.includes.isEmpty()) { - paths.addAll(endpoints.getAllPaths()); - } - streamPaths(this.includes, endpoints).forEach(paths::add); - streamPaths(this.excludes, endpoints).forEach(paths::remove); - List delegateMatchers = getDelegateMatchers(requestMatcherFactory, matcherProvider, paths, - this.httpMethod); - String basePath = endpoints.getBasePath(); - if (this.includeLinks && StringUtils.hasText(basePath)) { - delegateMatchers.addAll(getLinksMatchers(requestMatcherFactory, matcherProvider, basePath)); - } - if (delegateMatchers.isEmpty()) { - return EMPTY_MATCHER; - } - return new OrRequestMatcher(delegateMatchers); - } - - private Stream streamPaths(List source, PathMappedEndpoints endpoints) { - return source.stream() - .filter(Objects::nonNull) - .map(this::getEndpointId) - .map(endpoints::getPath) - .filter(Objects::nonNull); - } - - @Override - public String toString() { - return String.format("EndpointRequestMatcher includes=%s, excludes=%s, includeLinks=%s", - toString(this.includes, "[*]"), toString(this.excludes, "[]"), this.includeLinks); - } - - } - - /** - * The request matcher used to match against the links endpoint. - */ - public static final class LinksRequestMatcher extends AbstractRequestMatcher { - - @Override - protected RequestMatcher createDelegate(WebApplicationContext context, - RequestMatcherFactory requestMatcherFactory) { - WebEndpointProperties properties = context.getBean(WebEndpointProperties.class); - String basePath = properties.getBasePath(); - if (StringUtils.hasText(basePath)) { - return new OrRequestMatcher( - getLinksMatchers(requestMatcherFactory, getRequestMatcherProvider(context), basePath)); - } - return EMPTY_MATCHER; - } - - @Override - public String toString() { - return String.format("LinksRequestMatcher"); - } - - } - - /** - * The request matcher used to match against additional paths for {@link Endpoint - * actuator endpoints}. - */ - public static class AdditionalPathsEndpointRequestMatcher extends AbstractRequestMatcher { - - private final WebServerNamespace webServerNamespace; - - private final List endpoints; - - private final HttpMethod httpMethod; - - AdditionalPathsEndpointRequestMatcher(WebServerNamespace webServerNamespace, String... endpoints) { - this(webServerNamespace, Arrays.asList((Object[]) endpoints), null); - } - - AdditionalPathsEndpointRequestMatcher(WebServerNamespace webServerNamespace, Class... endpoints) { - this(webServerNamespace, Arrays.asList((Object[]) endpoints), null); - } - - private AdditionalPathsEndpointRequestMatcher(WebServerNamespace webServerNamespace, List endpoints, - HttpMethod httpMethod) { - Assert.notNull(webServerNamespace, "'webServerNamespace' must not be null"); - Assert.notNull(endpoints, "'endpoints' must not be null"); - Assert.notEmpty(endpoints, "'endpoints' must not be empty"); - this.webServerNamespace = webServerNamespace; - this.endpoints = endpoints; - this.httpMethod = httpMethod; - } - - /** - * Restricts the matcher to only consider requests with a particular HTTP method. - * @param httpMethod the HTTP method to include - * @return a copy of the matcher further restricted to only match requests with - * the specified HTTP method - * @since 3.5.0 - */ - public AdditionalPathsEndpointRequestMatcher withHttpMethod(HttpMethod httpMethod) { - return new AdditionalPathsEndpointRequestMatcher(this.webServerNamespace, this.endpoints, httpMethod); - } - - @Override - protected boolean ignoreApplicationContext(WebApplicationContext applicationContext, - ManagementPortType managementPortType) { - return !hasWebServerNamespace(applicationContext, this.webServerNamespace); - } - - @Override - protected RequestMatcher createDelegate(WebApplicationContext context, - RequestMatcherFactory requestMatcherFactory) { - PathMappedEndpoints endpoints = context.getBean(PathMappedEndpoints.class); - RequestMatcherProvider matcherProvider = getRequestMatcherProvider(context); - Set paths = this.endpoints.stream() - .filter(Objects::nonNull) - .map(this::getEndpointId) - .flatMap((endpointId) -> streamAdditionalPaths(endpoints, endpointId)) - .collect(Collectors.toCollection(LinkedHashSet::new)); - List delegateMatchers = getDelegateMatchers(requestMatcherFactory, matcherProvider, paths, - this.httpMethod); - return (!CollectionUtils.isEmpty(delegateMatchers)) ? new OrRequestMatcher(delegateMatchers) - : EMPTY_MATCHER; - } - - private Stream streamAdditionalPaths(PathMappedEndpoints pathMappedEndpoints, EndpointId endpointId) { - return pathMappedEndpoints.getAdditionalPaths(this.webServerNamespace, endpointId).stream(); - } - - @Override - public String toString() { - return String.format("AdditionalPathsEndpointRequestMatcher endpoints=%s, webServerNamespace=%s", - toString(this.endpoints, ""), this.webServerNamespace); - } - - } - - /** - * Factory used to create a {@link RequestMatcher}. - */ - private static final class RequestMatcherFactory { - - RequestMatcher antPath(RequestMatcherProvider matcherProvider, HttpMethod httpMethod, String... parts) { - StringBuilder pattern = new StringBuilder(); - for (String part : parts) { - Assert.notNull(part, "'part' must not be null"); - pattern.append(part); - } - return matcherProvider.getRequestMatcher(pattern.toString(), httpMethod); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.java deleted file mode 100644 index 6b2fea12096d..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfiguration.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.security.servlet; - -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; -import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.health.HealthEndpoint; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; -import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientWebSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.core.annotation.Order; -import org.springframework.core.env.Environment; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.ClassUtils; - -import static org.springframework.security.config.Customizer.withDefaults; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Security when actuator is - * on the classpath. It allows unauthenticated access to the {@link HealthEndpoint}. If - * the user specifies their own {@link SecurityFilterChain} bean, this will back-off - * completely and the user should specify all the bits that they want to configure as part - * of the custom security configuration. - * - * @author Madhura Bhave - * @author Hatef Palizgar - * @since 2.1.0 - */ -@AutoConfiguration(before = SecurityAutoConfiguration.class, - after = { HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class, - WebEndpointAutoConfiguration.class, OAuth2ClientWebSecurityAutoConfiguration.class, - OAuth2ResourceServerAutoConfiguration.class, Saml2RelyingPartyAutoConfiguration.class }) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@ConditionalOnDefaultWebSecurity -public class ManagementWebSecurityAutoConfiguration { - - @Bean - @Order(SecurityProperties.BASIC_AUTH_ORDER) - SecurityFilterChain managementSecurityFilterChain(Environment environment, HttpSecurity http) throws Exception { - http.authorizeHttpRequests((requests) -> { - requests.requestMatchers(healthMatcher(), additionalHealthPathsMatcher()).permitAll(); - requests.anyRequest().authenticated(); - }); - if (ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", null)) { - http.cors(withDefaults()); - } - http.formLogin(withDefaults()); - http.httpBasic(withDefaults()); - return http.build(); - } - - private RequestMatcher healthMatcher() { - return EndpointRequest.to(HealthEndpoint.class); - } - - private RequestMatcher additionalHealthPathsMatcher() { - return EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, HealthEndpoint.class); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/RequestMatcherProvider.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/RequestMatcherProvider.java deleted file mode 100644 index c5d99057d464..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/RequestMatcherProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.security.servlet; - -import org.springframework.http.HttpMethod; -import org.springframework.security.web.util.matcher.RequestMatcher; - -/** - * Interface that can be used to provide a {@link RequestMatcher} that can be used with - * Spring Security. - * - * @author Madhura Bhave - * @author Chris Bono - * @since 3.5.0 - */ -@FunctionalInterface -public interface RequestMatcherProvider { - - /** - * Return the {@link RequestMatcher} to be used for the specified pattern and http - * method. - * @param pattern the request pattern - * @param httpMethod the http method - * @return a request matcher - */ - RequestMatcher getRequestMatcher(String pattern, HttpMethod httpMethod); - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/package-info.java deleted file mode 100644 index db127e48f6c6..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator security using Spring MVC. - */ -package org.springframework.boot.actuate.autoconfigure.security.servlet; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/session/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/session/package-info.java deleted file mode 100644 index 8a71fef1c24b..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/session/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for actuator Spring Sessions concerns. - */ -package org.springframework.boot.actuate.autoconfigure.session; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslHealthContributorAutoConfiguration.java index aebba3cba5cc..a66595ab34d5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslHealthContributorAutoConfiguration.java @@ -16,13 +16,14 @@ package org.springframework.boot.actuate.autoconfigure.ssl; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.ssl.SslHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.Health; import org.springframework.boot.info.SslInfo; import org.springframework.boot.ssl.SslBundles; import org.springframework.context.annotation.Bean; @@ -33,7 +34,9 @@ * @author Jonatan Ivanov * @since 3.4.0 */ -@AutoConfiguration(before = HealthContributorAutoConfiguration.class) +@AutoConfiguration( + beforeName = "org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration") +@ConditionalOnClass(Health.class) @ConditionalOnEnabledHealthIndicator("ssl") @EnableConfigurationProperties(SslHealthIndicatorProperties.class) public class SslHealthContributorAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslObservabilityAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslObservabilityAutoConfiguration.java deleted file mode 100644 index 24cb0164e341..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslObservabilityAutoConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.ssl; - -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.info.SslInfo; -import org.springframework.boot.ssl.SslBundles; -import org.springframework.context.annotation.Bean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for SSL observability. - * - * @author Moritz Halbritter - * @since 3.5.0 - */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, - SslAutoConfiguration.class }) -@ConditionalOnClass(MeterRegistry.class) -@ConditionalOnBean({ MeterRegistry.class, SslBundles.class }) -@EnableConfigurationProperties(SslHealthIndicatorProperties.class) -public class SslObservabilityAutoConfiguration { - - @Bean - SslMeterBinder sslMeterBinder(SslInfo sslInfo, SslBundles sslBundles) { - return new SslMeterBinder(sslInfo, sslBundles); - } - - @Bean - @ConditionalOnMissingBean - SslInfo sslInfoProvider(SslBundles sslBundles, SslHealthIndicatorProperties properties) { - return new SslInfo(sslBundles); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthContributorAutoConfiguration.java index 24e5d77c0930..59d50cfe0473 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthContributorAutoConfiguration.java @@ -16,13 +16,14 @@ package org.springframework.boot.actuate.autoconfigure.system; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.system.DiskSpaceHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.Health; import org.springframework.context.annotation.Bean; /** @@ -33,7 +34,9 @@ * @author Andy Wilkinson * @since 2.0.0 */ -@AutoConfiguration(before = HealthContributorAutoConfiguration.class) +@AutoConfiguration( + beforeName = "org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration") +@ConditionalOnClass(Health.class) @ConditionalOnEnabledHealthIndicator("diskspace") @EnableConfigurationProperties(DiskSpaceHealthIndicatorProperties.class) public class DiskSpaceHealthContributorAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java deleted file mode 100644 index 102b9c9541ac..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.tracing; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry tracing. - * - * @author Moritz Halbritter - * @author Marcin Grzejszczak - * @author Yanming Zhou - * @since 3.0.0 - * @deprecated since 3.4.0 in favor of {@link OpenTelemetryTracingAutoConfiguration} - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public class OpenTelemetryAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java deleted file mode 100644 index 1463c8098d42..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for exporting traces with OTLP. - * - * @author Jonatan Ivanov - * @author Moritz Halbritter - * @author Eddú Meléndez - * @since 3.1.0 - * @deprecated since 3.4.0 in favor of {@link OtlpTracingAutoConfiguration} - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public class OtlpAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingConnectionDetails.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingConnectionDetails.java deleted file mode 100644 index 7cf8a54f31db..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingConnectionDetails.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; - -import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; - -/** - * Details required to establish a connection to an OpenTelemetry service. - * - * @author Eddú Meléndez - * @author Moritz Halbritter - * @since 3.2.0 - */ -public interface OtlpTracingConnectionDetails extends ConnectionDetails { - - /** - * Address to where tracing will be published. - * @return the address to where tracing will be published - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #getUrl(Transport)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - default String getUrl() { - return getUrl(Transport.HTTP); - } - - /** - * Address to where tracing will be published. - * @param transport the transport to use - * @return the address to where tracing will be published - * @since 3.4.0 - */ - String getUrl(Transport transport); - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/Transport.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/Transport.java deleted file mode 100644 index c2c963c3b04c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/Transport.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; - -/** - * Transport used to send OTLP data. - * - * @author Moritz Halbritter - * @since 3.4.0 - */ -public enum Transport { - - /** - * HTTP transport. - */ - HTTP, - - /** - * gRPC transport. - */ - GRPC - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/package-info.java deleted file mode 100644 index 673ed2a50025..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for exporting traces with OTLP. - */ -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java deleted file mode 100644 index 97321bb3234f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Micrometer Tracing. - */ -package org.springframework.boot.actuate.autoconfigure.tracing; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/package-info.java deleted file mode 100644 index 54fa9432b4ae..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Prometheus Exemplars with Micrometer Tracing. - */ -package org.springframework.boot.actuate.autoconfigure.tracing.prometheus; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java deleted file mode 100644 index b9adc9ce53b8..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; - -import zipkin2.reporter.Encoding; - -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Zipkin. - *

- * It uses imports on {@link ZipkinConfigurations} to guarantee the correct configuration - * ordering. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@AutoConfiguration(after = RestTemplateAutoConfiguration.class) -@ConditionalOnClass(Encoding.class) -@Import({ SenderConfiguration.class, BraveConfiguration.class, OpenTelemetryConfiguration.class }) -@EnableConfigurationProperties(ZipkinProperties.class) -public class ZipkinAutoConfiguration { - - @Bean - @ConditionalOnMissingBean(ZipkinConnectionDetails.class) - PropertiesZipkinConnectionDetails zipkinConnectionDetails(ZipkinProperties properties) { - return new PropertiesZipkinConnectionDetails(properties); - } - - @Bean - @ConditionalOnMissingBean - Encoding encoding(ZipkinProperties properties) { - return switch (properties.getEncoding()) { - case JSON -> Encoding.JSON; - case PROTO3 -> Encoding.PROTO3; - }; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java deleted file mode 100644 index d43b7c82f8bd..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; - -import java.net.http.HttpClient; -import java.net.http.HttpClient.Builder; - -import brave.Tag; -import brave.Tags; -import brave.handler.MutableSpan; -import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; -import zipkin2.Span; -import zipkin2.reporter.BytesEncoder; -import zipkin2.reporter.BytesMessageSender; -import zipkin2.reporter.Encoding; -import zipkin2.reporter.HttpEndpointSupplier; -import zipkin2.reporter.HttpEndpointSuppliers; -import zipkin2.reporter.SpanBytesEncoder; -import zipkin2.reporter.brave.AsyncZipkinSpanHandler; -import zipkin2.reporter.brave.MutableSpanBytesEncoder; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Configurations for Zipkin. Those are imported by {@link ZipkinAutoConfiguration}. - * - * @author Moritz Halbritter - * @author Stefan Bratanov - * @author Wick Dynex - */ -class ZipkinConfigurations { - - @Configuration(proxyBeanMethods = false) - @Import({ HttpClientSenderConfiguration.class }) - static class SenderConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(HttpClient.class) - @EnableConfigurationProperties(ZipkinProperties.class) - static class HttpClientSenderConfiguration { - - @Bean - @ConditionalOnMissingBean(BytesMessageSender.class) - ZipkinHttpClientSender httpClientSender(ZipkinProperties properties, Encoding encoding, - ObjectProvider customizers, - ObjectProvider connectionDetailsProvider, - ObjectProvider endpointSupplierFactoryProvider) { - ZipkinConnectionDetails connectionDetails = connectionDetailsProvider - .getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties)); - HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider - .getIfAvailable(HttpEndpointSuppliers::constantFactory); - Builder httpClientBuilder = HttpClient.newBuilder().connectTimeout(properties.getConnectTimeout()); - customizers.orderedStream().forEach((customizer) -> customizer.customize(httpClientBuilder)); - return new ZipkinHttpClientSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(), - httpClientBuilder.build(), properties.getReadTimeout()); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(AsyncZipkinSpanHandler.class) - static class BraveConfiguration { - - @Bean - @ConditionalOnMissingBean(value = MutableSpan.class, parameterizedContainer = BytesEncoder.class) - BytesEncoder mutableSpanBytesEncoder(Encoding encoding, - ObjectProvider> throwableTagProvider) { - Tag throwableTag = throwableTagProvider.getIfAvailable(() -> Tags.ERROR); - return MutableSpanBytesEncoder.create(encoding, throwableTag); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(BytesMessageSender.class) - @ConditionalOnEnabledTracing("zipkin") - AsyncZipkinSpanHandler asyncZipkinSpanHandler(BytesMessageSender sender, - BytesEncoder mutableSpanBytesEncoder) { - return AsyncZipkinSpanHandler.newBuilder(sender).build(mutableSpanBytesEncoder); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ ZipkinSpanExporter.class, Span.class }) - static class OpenTelemetryConfiguration { - - @Bean - @ConditionalOnMissingBean(value = Span.class, parameterizedContainer = BytesEncoder.class) - BytesEncoder spanBytesEncoder(Encoding encoding) { - return SpanBytesEncoder.forEncoding(encoding); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(BytesMessageSender.class) - @ConditionalOnEnabledTracing("zipkin") - ZipkinSpanExporter zipkinSpanExporter(BytesMessageSender sender, BytesEncoder spanBytesEncoder) { - return ZipkinSpanExporter.builder().setSender(sender).setEncoder(spanBytesEncoder).build(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java deleted file mode 100644 index 6270fdd48328..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for tracing with Zipkin. - */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/ManagementContextFactory.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/ManagementContextFactory.java index d88a678a9fe5..41a56cf772c2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/ManagementContextFactory.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/ManagementContextFactory.java @@ -72,7 +72,9 @@ public ConfigurableApplicationContext createManagementContext(ApplicationContext public void registerWebServerFactoryBeans(ApplicationContext parentContext, ConfigurableApplicationContext managementContext, AnnotationConfigRegistry registry) { - registry.register(this.autoConfigurationClasses); + if (this.autoConfigurationClasses != null && this.autoConfigurationClasses.length > 0) { + registry.register(this.autoConfigurationClasses); + } registerWebServerFactoryFromParent(parentContext, managementContext); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java deleted file mode 100644 index 29d20495e557..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfiguration.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.exchanges; - -import org.springframework.boot.actuate.web.exchanges.HttpExchange; -import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; -import org.springframework.boot.actuate.web.exchanges.reactive.HttpExchangesWebFilter; -import org.springframework.boot.actuate.web.exchanges.servlet.HttpExchangesFilter; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} to record {@link HttpExchange HTTP - * exchanges}. - * - * @author Dave Syer - * @since 3.0.0 - */ -@AutoConfiguration -@ConditionalOnWebApplication -@ConditionalOnBooleanProperty(name = "management.httpexchanges.recording.enabled", matchIfMissing = true) -@ConditionalOnBean(HttpExchangeRepository.class) -@EnableConfigurationProperties(HttpExchangesProperties.class) -public class HttpExchangesAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = Type.SERVLET) - static class ServletHttpExchangesConfiguration { - - @Bean - @ConditionalOnMissingBean - HttpExchangesFilter httpExchangesFilter(HttpExchangeRepository repository, HttpExchangesProperties properties) { - return new HttpExchangesFilter(repository, properties.getRecording().getInclude()); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = Type.REACTIVE) - static class ReactiveHttpExchangesConfiguration { - - @Bean - @ConditionalOnMissingBean - HttpExchangesWebFilter httpExchangesWebFilter(HttpExchangeRepository repository, - HttpExchangesProperties properties) { - return new HttpExchangesWebFilter(repository, properties.getRecording().getInclude()); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java index 388b1a4b4f6b..0c285099c426 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfiguration.java @@ -32,7 +32,7 @@ * @author Phillip Webb * @since 3.0.0 */ -@AutoConfiguration(after = HttpExchangesAutoConfiguration.class) +@AutoConfiguration @ConditionalOnAvailableEndpoint(HttpExchangesEndpoint.class) public class HttpExchangesEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/package-info.java deleted file mode 100644 index 21fd5ad76295..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Configuration for a Jersey-based management context. - */ -package org.springframework.boot.actuate.autoconfigure.web.jersey; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java index 41119bacac7f..e3bc2311966d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java @@ -20,21 +20,10 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; -import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.FiltersMappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.DispatcherHandler; -import org.springframework.web.servlet.DispatcherServlet; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link MappingsEndpoint}. @@ -47,50 +36,9 @@ public class MappingsEndpointAutoConfiguration { @Bean - public MappingsEndpoint mappingsEndpoint(ApplicationContext applicationContext, + MappingsEndpoint mappingsEndpoint(ApplicationContext applicationContext, ObjectProvider descriptionProviders) { return new MappingsEndpoint(descriptionProviders.orderedStream().toList(), applicationContext); } - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = Type.SERVLET) - static class ServletWebConfiguration { - - @Bean - ServletsMappingDescriptionProvider servletMappingDescriptionProvider() { - return new ServletsMappingDescriptionProvider(); - } - - @Bean - FiltersMappingDescriptionProvider filterMappingDescriptionProvider() { - return new FiltersMappingDescriptionProvider(); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(DispatcherServlet.class) - @ConditionalOnBean(DispatcherServlet.class) - static class SpringMvcConfiguration { - - @Bean - DispatcherServletsMappingDescriptionProvider dispatcherServletMappingDescriptionProvider() { - return new DispatcherServletsMappingDescriptionProvider(); - } - - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = Type.REACTIVE) - @ConditionalOnClass(DispatcherHandler.class) - @ConditionalOnBean(DispatcherHandler.class) - static class ReactiveWebConfiguration { - - @Bean - DispatcherHandlersMappingDescriptionProvider dispatcherHandlerMappingDescriptionProvider() { - return new DispatcherHandlersMappingDescriptionProvider(); - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfiguration.java deleted file mode 100644 index 04f32a59365f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfiguration.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.reactive; - -import java.io.File; -import java.util.Collections; -import java.util.Map; - -import org.apache.catalina.Valve; -import org.apache.catalina.valves.AccessLogValve; -import org.eclipse.jetty.server.CustomRequestLog; -import org.eclipse.jetty.server.RequestLog; -import org.eclipse.jetty.server.RequestLogWriter; -import org.eclipse.jetty.server.Server; - -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory; -import org.springframework.boot.web.server.ConfigurableWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.core.Ordered; -import org.springframework.http.server.reactive.ContextPathCompositeHandler; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.util.StringUtils; -import org.springframework.web.reactive.config.EnableWebFlux; -import org.springframework.web.server.adapter.WebHttpHandlerBuilder; - -/** - * {@link ManagementContextConfiguration @ManagementContextConfiguration} for reactive web - * infrastructure when a separate management context with a web server running on a - * different port is required. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @author Moritz Halbritter - * @since 2.0.0 - */ -@EnableWebFlux -@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) -@ConditionalOnWebApplication(type = Type.REACTIVE) -public class ReactiveManagementChildContextConfiguration { - - @Bean - public ManagementWebServerFactoryCustomizer reactiveManagementWebServerFactoryCustomizer( - ListableBeanFactory beanFactory) { - return new ManagementWebServerFactoryCustomizer<>(beanFactory); - } - - @Bean - public HttpHandler httpHandler(ApplicationContext applicationContext, ManagementServerProperties properties) { - HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build(); - if (StringUtils.hasText(properties.getBasePath())) { - Map handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler); - return new ContextPathCompositeHandler(handlersMap); - } - return httpHandler; - } - - @Bean - @ConditionalOnClass(name = "io.undertow.Undertow") - UndertowAccessLogCustomizer undertowManagementAccessLogCustomizer(ManagementServerProperties properties) { - return new UndertowAccessLogCustomizer(properties); - } - - @Bean - @ConditionalOnClass(name = "org.apache.catalina.valves.AccessLogValve") - TomcatAccessLogCustomizer tomcatManagementAccessLogCustomizer(ManagementServerProperties properties) { - return new TomcatAccessLogCustomizer(properties); - } - - @Bean - @ConditionalOnClass(name = "org.eclipse.jetty.server.Server") - JettyAccessLogCustomizer jettyManagementAccessLogCustomizer(ManagementServerProperties properties) { - return new JettyAccessLogCustomizer(properties); - } - - abstract static class AccessLogCustomizer implements Ordered { - - private final String prefix; - - AccessLogCustomizer(String prefix) { - this.prefix = prefix; - } - - protected String customizePrefix(String existingPrefix) { - if (this.prefix == null) { - return existingPrefix; - } - if (existingPrefix == null) { - return this.prefix; - } - if (existingPrefix.startsWith(this.prefix)) { - return existingPrefix; - } - return this.prefix + existingPrefix; - } - - @Override - public int getOrder() { - return 1; - } - - } - - static class TomcatAccessLogCustomizer extends AccessLogCustomizer - implements WebServerFactoryCustomizer { - - TomcatAccessLogCustomizer(ManagementServerProperties properties) { - super(properties.getTomcat().getAccesslog().getPrefix()); - } - - @Override - public void customize(TomcatReactiveWebServerFactory factory) { - AccessLogValve accessLogValve = findAccessLogValve(factory); - if (accessLogValve == null) { - return; - } - accessLogValve.setPrefix(customizePrefix(accessLogValve.getPrefix())); - } - - private AccessLogValve findAccessLogValve(TomcatReactiveWebServerFactory factory) { - for (Valve engineValve : factory.getEngineValves()) { - if (engineValve instanceof AccessLogValve accessLogValve) { - return accessLogValve; - } - } - return null; - } - - } - - static class UndertowAccessLogCustomizer extends AccessLogCustomizer - implements WebServerFactoryCustomizer { - - UndertowAccessLogCustomizer(ManagementServerProperties properties) { - super(properties.getUndertow().getAccesslog().getPrefix()); - } - - @Override - public void customize(UndertowReactiveWebServerFactory factory) { - factory.setAccessLogPrefix(customizePrefix(factory.getAccessLogPrefix())); - } - - } - - static class JettyAccessLogCustomizer extends AccessLogCustomizer - implements WebServerFactoryCustomizer { - - JettyAccessLogCustomizer(ManagementServerProperties properties) { - super(properties.getJetty().getAccesslog().getPrefix()); - } - - @Override - public void customize(JettyReactiveWebServerFactory factory) { - factory.addServerCustomizers(this::customizeServer); - } - - private void customizeServer(Server server) { - RequestLog requestLog = server.getRequestLog(); - if (requestLog instanceof CustomRequestLog customRequestLog) { - customizeRequestLog(customRequestLog); - } - } - - private void customizeRequestLog(CustomRequestLog requestLog) { - if (requestLog.getWriter() instanceof RequestLogWriter requestLogWriter) { - customizeRequestLogWriter(requestLogWriter); - } - } - - private void customizeRequestLogWriter(RequestLogWriter writer) { - String filename = writer.getFileName(); - if (StringUtils.hasLength(filename)) { - File file = new File(filename); - file = new File(file.getParentFile(), customizePrefix(file.getName())); - writer.setFilename(file.getPath()); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementContextAutoConfiguration.java deleted file mode 100644 index e4b667088818..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementContextAutoConfiguration.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.reactive; - -import reactor.core.publisher.Flux; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.context.annotation.Bean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Reactive-specific management - * context concerns. - * - * @author Phillip Webb - * @since 2.0.0 - */ -@AutoConfiguration -@ConditionalOnClass(Flux.class) -@ConditionalOnWebApplication(type = Type.REACTIVE) -public class ReactiveManagementContextAutoConfiguration { - - @Bean - public static ManagementContextFactory reactiveWebChildContextFactory() { - return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, - ReactiveWebServerFactoryAutoConfiguration.class, - EmbeddedWebServerFactoryCustomizerAutoConfiguration.class); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/package-info.java deleted file mode 100644 index 36e5adafc81e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Configuration for a WebFlux-based management context. - */ -package org.springframework.boot.actuate.autoconfigure.web.reactive; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/AccessLogCustomizer.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/AccessLogCustomizer.java new file mode 100644 index 000000000000..fa1dba1c8047 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/AccessLogCustomizer.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.web.server; + +import org.springframework.boot.web.server.WebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.core.Ordered; + +/** + * Base class for a {@link WebServerFactoryCustomizer} that customizes the web server's + * access log. + * + * @param the {@link WebServerFactory} type that can be customized + * @author Andy Wilkinson + * @since 4.0.0 + */ +public abstract class AccessLogCustomizer + implements WebServerFactoryCustomizer, Ordered { + + private final String prefix; + + protected AccessLogCustomizer(String prefix) { + this.prefix = prefix; + } + + protected String customizePrefix(String existingPrefix) { + if (this.prefix == null) { + return existingPrefix; + } + if (existingPrefix == null) { + return this.prefix; + } + if (existingPrefix.startsWith(this.prefix)) { + return existingPrefix; + } + return this.prefix + existingPrefix; + } + + @Override + public int getOrder() { + return 1; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializer.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializer.java index 85ff85e0c1d9..9a637d57b858 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializer.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializer.java @@ -32,8 +32,8 @@ import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.context.event.ApplicationFailedEvent; -import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; -import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.server.context.ConfigurableWebServerApplicationContext; +import org.springframework.boot.web.server.context.WebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ApplicationEvent; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java index 886942d34f6f..4326c99fe558 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java @@ -48,7 +48,6 @@ */ @AutoConfiguration @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE) -@EnableConfigurationProperties(ManagementServerProperties.class) public class ManagementContextAutoConfiguration { @Configuration(proxyBeanMethods = false) @@ -101,6 +100,7 @@ static class EnableSameManagementContextConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnManagementPort(ManagementPortType.DIFFERENT) + @EnableConfigurationProperties(ManagementServerProperties.class) static class DifferentManagementContextConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementServerProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementServerProperties.java index a6273ded59b9..3f2b9f8aaf97 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementServerProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementServerProperties.java @@ -18,10 +18,10 @@ import java.net.InetAddress; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.util.StringUtils; /** @@ -58,12 +58,6 @@ public class ManagementServerProperties { @NestedConfigurationProperty private Ssl ssl; - private final Jetty jetty = new Jetty(); - - private final Tomcat tomcat = new Tomcat(); - - private final Undertow undertow = new Undertow(); - /** * Returns the management port or {@code null} if the * {@link ServerProperties#getPort() server port} should be used. @@ -108,18 +102,6 @@ public void setSsl(Ssl ssl) { this.ssl = ssl; } - public Jetty getJetty() { - return this.jetty; - } - - public Tomcat getTomcat() { - return this.tomcat; - } - - public Undertow getUndertow() { - return this.undertow; - } - private String cleanBasePath(String basePath) { String candidate = null; if (StringUtils.hasLength(basePath)) { @@ -136,51 +118,4 @@ private String cleanBasePath(String basePath) { return candidate; } - public static class Jetty { - - private final Accesslog accesslog = new Accesslog(); - - public Accesslog getAccesslog() { - return this.accesslog; - } - - } - - public static class Tomcat { - - private final Accesslog accesslog = new Accesslog(); - - public Accesslog getAccesslog() { - return this.accesslog; - } - - } - - public static class Undertow { - - private final Accesslog accesslog = new Accesslog(); - - public Accesslog getAccesslog() { - return this.accesslog; - } - - } - - public static class Accesslog { - - /** - * Management log file name prefix. - */ - private String prefix = "management_"; - - public String getPrefix() { - return this.prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementWebServerFactoryCustomizer.java index d7975d3db924..6b646e6870c2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementWebServerFactoryCustomizer.java @@ -23,12 +23,12 @@ import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.util.LambdaSafe; import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.WebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.core.Ordered; /** @@ -46,15 +46,6 @@ public class ManagementWebServerFactoryCustomizer>[] customizerClasses; - @SafeVarargs - @SuppressWarnings("varargs") - @Deprecated(since = "3.5.0", forRemoval = true) - protected ManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory, - Class>... customizerClasses) { - this.beanFactory = beanFactory; - this.customizerClasses = customizerClasses; - } - /** * Creates a new customizer that will retrieve beans using the given * {@code beanFactory}. diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/OnManagementPortCondition.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/OnManagementPortCondition.java index 31848106d864..90af13a6c248 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/OnManagementPortCondition.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/OnManagementPortCondition.java @@ -21,7 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebApplicationContext; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.AnnotatedTypeMetadata; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementChildContextConfiguration.java deleted file mode 100644 index 8b1d756c02ca..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementChildContextConfiguration.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.servlet; - -import java.io.File; - -import jakarta.servlet.Filter; -import org.apache.catalina.Valve; -import org.apache.catalina.valves.AccessLogValve; -import org.eclipse.jetty.server.CustomRequestLog; -import org.eclipse.jetty.server.RequestLog; -import org.eclipse.jetty.server.RequestLogWriter; -import org.eclipse.jetty.server.Server; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.HierarchicalBeanFactory; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.condition.SearchStrategy; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.security.config.BeanIds; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.util.StringUtils; - -/** - * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Servlet web - * endpoint infrastructure when a separate management context with a web server running on - * a different port is required. - * - * @author Dave Syer - * @author Stephane Nicoll - * @author Andy Wilkinson - * @author Eddú Meléndez - * @author Phillip Webb - * @author Moritz Halbritter - */ -@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) -@ConditionalOnWebApplication(type = Type.SERVLET) -class ServletManagementChildContextConfiguration { - - @Bean - ServletManagementWebServerFactoryCustomizer servletManagementWebServerFactoryCustomizer( - ListableBeanFactory beanFactory) { - return new ServletManagementWebServerFactoryCustomizer(beanFactory); - } - - @Bean - @ConditionalOnClass(name = "io.undertow.Undertow") - UndertowAccessLogCustomizer undertowManagementAccessLogCustomizer(ManagementServerProperties properties) { - return new UndertowAccessLogCustomizer(properties); - } - - @Bean - @ConditionalOnClass(name = "org.apache.catalina.valves.AccessLogValve") - TomcatAccessLogCustomizer tomcatManagementAccessLogCustomizer(ManagementServerProperties properties) { - return new TomcatAccessLogCustomizer(properties); - } - - @Bean - @ConditionalOnClass(name = "org.eclipse.jetty.server.Server") - JettyAccessLogCustomizer jettyManagementAccessLogCustomizer(ManagementServerProperties properties) { - return new JettyAccessLogCustomizer(properties); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ EnableWebSecurity.class, Filter.class }) - @ConditionalOnBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN, search = SearchStrategy.ANCESTORS) - static class ServletManagementContextSecurityConfiguration { - - @Bean - Filter springSecurityFilterChain(HierarchicalBeanFactory beanFactory) { - BeanFactory parent = beanFactory.getParentBeanFactory(); - return parent.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN, Filter.class); - } - - @Bean - @ConditionalOnBean(name = "securityFilterChainRegistration", search = SearchStrategy.ANCESTORS) - DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(HierarchicalBeanFactory beanFactory) { - return beanFactory.getParentBeanFactory() - .getBean("securityFilterChainRegistration", DelegatingFilterProxyRegistrationBean.class); - } - - } - - static class ServletManagementWebServerFactoryCustomizer - extends ManagementWebServerFactoryCustomizer { - - ServletManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory) { - super(beanFactory); - } - - @Override - protected void customize(ConfigurableServletWebServerFactory webServerFactory, - ManagementServerProperties managementServerProperties, ServerProperties serverProperties) { - super.customize(webServerFactory, managementServerProperties, serverProperties); - webServerFactory.setContextPath(getContextPath(managementServerProperties)); - } - - private String getContextPath(ManagementServerProperties managementServerProperties) { - String basePath = managementServerProperties.getBasePath(); - return StringUtils.hasText(basePath) ? basePath : ""; - } - - } - - abstract static class AccessLogCustomizer implements Ordered { - - private final String prefix; - - AccessLogCustomizer(String prefix) { - this.prefix = prefix; - } - - protected String customizePrefix(String existingPrefix) { - if (this.prefix == null) { - return existingPrefix; - } - if (existingPrefix == null) { - return this.prefix; - } - if (existingPrefix.startsWith(this.prefix)) { - return existingPrefix; - } - return this.prefix + existingPrefix; - } - - @Override - public int getOrder() { - return 1; - } - - } - - static class TomcatAccessLogCustomizer extends AccessLogCustomizer - implements WebServerFactoryCustomizer { - - TomcatAccessLogCustomizer(ManagementServerProperties properties) { - super(properties.getTomcat().getAccesslog().getPrefix()); - } - - @Override - public void customize(TomcatServletWebServerFactory factory) { - AccessLogValve accessLogValve = findAccessLogValve(factory); - if (accessLogValve == null) { - return; - } - accessLogValve.setPrefix(customizePrefix(accessLogValve.getPrefix())); - } - - private AccessLogValve findAccessLogValve(TomcatServletWebServerFactory factory) { - for (Valve engineValve : factory.getEngineValves()) { - if (engineValve instanceof AccessLogValve accessLogValve) { - return accessLogValve; - } - } - return null; - } - - } - - static class UndertowAccessLogCustomizer extends AccessLogCustomizer - implements WebServerFactoryCustomizer { - - UndertowAccessLogCustomizer(ManagementServerProperties properties) { - super(properties.getUndertow().getAccesslog().getPrefix()); - } - - @Override - public void customize(UndertowServletWebServerFactory factory) { - factory.setAccessLogPrefix(customizePrefix(factory.getAccessLogPrefix())); - } - - } - - static class JettyAccessLogCustomizer extends AccessLogCustomizer - implements WebServerFactoryCustomizer { - - JettyAccessLogCustomizer(ManagementServerProperties properties) { - super(properties.getJetty().getAccesslog().getPrefix()); - } - - @Override - public void customize(JettyServletWebServerFactory factory) { - factory.addServerCustomizers(this::customizeServer); - } - - private void customizeServer(Server server) { - RequestLog requestLog = server.getRequestLog(); - if (requestLog instanceof CustomRequestLog customRequestLog) { - customizeRequestLog(customRequestLog); - } - } - - private void customizeRequestLog(CustomRequestLog requestLog) { - if (requestLog.getWriter() instanceof RequestLogWriter requestLogWriter) { - customizeRequestLogWriter(requestLogWriter); - } - } - - private void customizeRequestLogWriter(RequestLogWriter writer) { - String filename = writer.getFileName(); - if (StringUtils.hasLength(filename)) { - File file = new File(filename); - file = new File(file.getParentFile(), customizePrefix(file.getName())); - writer.setFilename(file.getPath()); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementContextAutoConfiguration.java deleted file mode 100644 index 5cca4b258064..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementContextAutoConfiguration.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.servlet; - -import jakarta.servlet.Servlet; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.web.servlet.filter.ApplicationContextHeaderFilter; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Servlet-specific management - * context concerns. - * - * @author Phillip Webb - * @since 2.0.0 - */ -@AutoConfiguration -@ConditionalOnClass(Servlet.class) -@ConditionalOnWebApplication(type = Type.SERVLET) -public class ServletManagementContextAutoConfiguration { - - @Bean - public static ManagementContextFactory servletWebChildContextFactory() { - return new ManagementContextFactory(WebApplicationType.SERVLET, ServletWebServerFactory.class, - ServletWebServerFactoryAutoConfiguration.class, - EmbeddedWebServerFactoryCustomizerAutoConfiguration.class); - } - - @Bean - public ManagementServletContext managementServletContext(WebEndpointProperties properties) { - return properties::getBasePath; - } - - // Put Servlets and Filters in their own nested class so they don't force early - // instantiation of ManagementServerProperties. - @Configuration(proxyBeanMethods = false) - @ConditionalOnBooleanProperty("management.server.add-application-context-header") - protected static class ApplicationContextFilterConfiguration { - - @Bean - public ApplicationContextHeaderFilter applicationContextIdFilter(ApplicationContext context) { - return new ApplicationContextHeaderFilter(context); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/package-info.java deleted file mode 100644 index 3c4659cdf655..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator Spring MVC support. - */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 7fe27e35bd91..de489eb9d2d2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -24,12 +24,6 @@ "description": "Whether to skip SSL verification for Cloud Foundry actuator endpoint security calls.", "defaultValue": false }, - { - "name": "management.defaults.metrics.export.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable default metrics exporters.", - "defaultValue": true - }, { "name": "management.endpoint.health.probes.add-additional-paths", "type": "java.lang.Boolean", @@ -105,33 +99,6 @@ "health" ] }, - { - "name": "management.health.cassandra.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Cassandra health check.", - "defaultValue": true - }, - { - "name": "management.health.couchbase.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Couchbase health check.", - "defaultValue": true - }, - { - "name": "management.health.couchbase.timeout", - "type": "java.time.Duration", - "description": "Timeout for getting the Bucket information from the server.", - "defaultValue": "1000ms", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.health.db.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable database health check.", - "defaultValue": true - }, { "name": "management.health.defaults.enabled", "type": "java.lang.Boolean", @@ -144,70 +111,12 @@ "description": "Whether to enable disk space health check.", "defaultValue": true }, - { - "name": "management.health.elasticsearch.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Elasticsearch health check.", - "defaultValue": true - }, - { - "name": "management.health.elasticsearch.indices", - "type": "java.util.List", - "description": "Comma-separated index names.", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.health.elasticsearch.response-timeout", - "type": "java.time.Duration", - "description": "Time to wait for a response from the cluster.", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.health.influxdb.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable InfluxDB health check.", - "defaultValue": true - }, - { - "name": "management.health.jms.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable JMS health check.", - "defaultValue": true - }, - { - "name": "management.health.ldap.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable LDAP health check.", - "defaultValue": true - }, { "name": "management.health.livenessstate.enabled", "type": "java.lang.Boolean", "description": "Whether to enable liveness state health check.", "defaultValue": false }, - { - "name": "management.health.mail.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Mail health check.", - "defaultValue": true - }, - { - "name": "management.health.mongo.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable MongoDB health check.", - "defaultValue": true - }, - { - "name": "management.health.neo4j.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Neo4j health check.", - "defaultValue": true - }, { "name": "management.health.ping.enabled", "type": "java.lang.Boolean", @@ -223,24 +132,12 @@ "replacement": "management.endpoint.health.probes.enabled" } }, - { - "name": "management.health.rabbit.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable RabbitMQ health check.", - "defaultValue": true - }, { "name": "management.health.readinessstate.enabled", "type": "java.lang.Boolean", "description": "Whether to enable readiness state health check.", "defaultValue": false }, - { - "name": "management.health.redis.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Redis health check.", - "defaultValue": true - }, { "name": "management.health.ssl.enabled", "type": "java.lang.Boolean", @@ -310,1751 +207,39 @@ "defaultValue": false }, { - "name": "management.logging.export.enabled", - "type": "java.lang.Boolean", - "description": "Whether auto-configuration of logging is enabled to export logs.", - "defaultValue": true - }, - { - "name": "management.metrics.binders.files.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable files metrics.", - "defaultValue": true, - "deprecation": { - "level": "error", - "replacement": "management.metrics.enable.process.files", - "reason": "Instead, filter 'process.files' metrics." - } - }, - { - "name": "management.metrics.binders.jvm.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable JVM metrics.", - "defaultValue": true, - "deprecation": { - "level": "error", - "replacement": "management.metrics.enable.jvm", - "reason": "Instead, disable JvmMetricsAutoConfiguration or filter 'jvm' metrics." - } - }, - { - "name": "management.metrics.binders.logback.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Logback metrics.", - "defaultValue": true, - "deprecation": { - "level": "error", - "replacement": "management.metrics.enable.logback", - "reason": "Instead, disable LogbackMetricsAutoConfiguration or filter 'logback' metrics." - } - }, - { - "name": "management.metrics.binders.processor.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable processor metrics.", - "defaultValue": true, - "deprecation": { - "level": "error", - "reason": "Instead, filter 'system.cpu' and 'process.cpu' metrics." - } - }, - { - "name": "management.metrics.binders.uptime.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable uptime metrics.", - "defaultValue": true, - "deprecation": { - "level": "error", - "reason": "Instead, filter 'process.uptime' and 'process.start.time' metrics." - } - }, - { - "name": "management.metrics.export.appoptics.api-token", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.api-token" - } - }, - { - "name": "management.metrics.export.appoptics.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.appoptics.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.appoptics.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.appoptics.floor-times", + "name": "management.server.add-application-context-header", "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.floor-times" - } + "description": "Add the \"X-Application-Context\" HTTP header in each response.", + "defaultValue": false }, { - "name": "management.metrics.export.appoptics.host-tag", + "name": "management.server.servlet.context-path", "type": "java.lang.String", "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.host-tag" - } - }, - { - "name": "management.metrics.export.appoptics.num-threads", - "type": "java.lang.Integer", - "deprecation": { + "replacement": "management.server.base-path", "level": "error" } }, { - "name": "management.metrics.export.appoptics.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.appoptics.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.step" - } - }, - { - "name": "management.metrics.export.appoptics.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.appoptics.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.atlas.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.atlas.config-refresh-frequency", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.config-refresh-frequency" - } - }, - { - "name": "management.metrics.export.atlas.config-time-to-live", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.config-time-to-live" - } - }, - { - "name": "management.metrics.export.atlas.config-uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.config-uri" - } - }, - { - "name": "management.metrics.export.atlas.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.atlas.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.atlas.eval-uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.eval-uri" - } - }, - { - "name": "management.metrics.export.atlas.lwc-enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.lwc-enabled" - } - }, - { - "name": "management.metrics.export.atlas.meter-time-to-live", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.meter-time-to-live" - } - }, - { - "name": "management.metrics.export.atlas.num-threads", - "type": "java.lang.Integer", + "name": "management.trace.http.enabled", "deprecation": { + "replacement": "management.httpexchanges.recording.enabled", "level": "error" } }, { - "name": "management.metrics.export.atlas.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.atlas.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.step" - } - }, - { - "name": "management.metrics.export.atlas.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.atlas.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.datadog.api-key", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.api-key" - } - }, - { - "name": "management.metrics.export.datadog.application-key", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.application-key" - } - }, - { - "name": "management.metrics.export.datadog.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.datadog.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.datadog.descriptions", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.descriptions" - } - }, - { - "name": "management.metrics.export.datadog.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.datadog.host-tag", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.host-tag" - } - }, - { - "name": "management.metrics.export.datadog.num-threads", - "type": "java.lang.Integer", + "name": "management.trace.http.include", "deprecation": { + "replacement": "management.httpexchanges.recording.include", "level": "error" } }, { - "name": "management.metrics.export.datadog.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.datadog.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.step" - } - }, - { - "name": "management.metrics.export.datadog.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.datadog.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.defaults.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.defaults.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.dynatrace.api-token", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.api-token" - } - }, - { - "name": "management.metrics.export.dynatrace.batch-size", - "type": "java.lang.Integer", + "name": "management.trace.include", "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.batch-size" + "replacement": "management.httpexchanges.recording.include", + "level": "error" } - }, - { - "name": "management.metrics.export.dynatrace.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.dynatrace.device-id", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.device-id" - } - }, - { - "name": "management.metrics.export.dynatrace.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.dynatrace.group", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.group" - } - }, - { - "name": "management.metrics.export.dynatrace.num-threads", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.dynatrace.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.dynatrace.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.step" - } - }, - { - "name": "management.metrics.export.dynatrace.technology-type", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.technology-type" - } - }, - { - "name": "management.metrics.export.dynatrace.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.dynatrace.v1.device-id", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.v1.device-id" - } - }, - { - "name": "management.metrics.export.dynatrace.v1.group", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.v1.group" - } - }, - { - "name": "management.metrics.export.dynatrace.v1.technology-type", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.v1.technology-type" - } - }, - { - "name": "management.metrics.export.dynatrace.v2.default-dimensions", - "type": "java.util.Map", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.v2.default-dimensions" - } - }, - { - "name": "management.metrics.export.dynatrace.v2.enrich-with-dynatrace-metadata", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.v2.enrich-with-dynatrace-metadata" - } - }, - { - "name": "management.metrics.export.dynatrace.v2.metric-key-prefix", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.dynatrace.metrics.export.v2.metric-key-prefix" - } - }, - { - "name": "management.metrics.export.elastic.api-key-credentials", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.api-key-credentials" - } - }, - { - "name": "management.metrics.export.elastic.auto-create-index", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.auto-create-index" - } - }, - { - "name": "management.metrics.export.elastic.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.elastic.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.elastic.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.elastic.host", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.host" - } - }, - { - "name": "management.metrics.export.elastic.index", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.index" - } - }, - { - "name": "management.metrics.export.elastic.index-date-format", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.index-date-format" - } - }, - { - "name": "management.metrics.export.elastic.index-date-separator", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.index-date-separator" - } - }, - { - "name": "management.metrics.export.elastic.num-threads", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.elastic.password", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.password" - } - }, - { - "name": "management.metrics.export.elastic.pipeline", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.pipeline" - } - }, - { - "name": "management.metrics.export.elastic.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.elastic.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.step" - } - }, - { - "name": "management.metrics.export.elastic.timestamp-field-name", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.timestamp-field-name" - } - }, - { - "name": "management.metrics.export.elastic.user-name", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.elastic.metrics.export.user-name" - } - }, - { - "name": "management.metrics.export.ganglia.addressing-mode", - "type": "info.ganglia.gmetric4j.gmetric.GMetric$UDPAddressingMode", - "deprecation": { - "level": "error", - "replacement": "management.ganglia.metrics.export.addressing-mode" - } - }, - { - "name": "management.metrics.export.ganglia.duration-units", - "type": "java.util.concurrent.TimeUnit", - "deprecation": { - "level": "error", - "replacement": "management.ganglia.metrics.export.duration-units" - } - }, - { - "name": "management.metrics.export.ganglia.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.ganglia.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.ganglia.host", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.ganglia.metrics.export.host" - } - }, - { - "name": "management.metrics.export.ganglia.port", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.ganglia.metrics.export.port" - } - }, - { - "name": "management.metrics.export.ganglia.rate-units", - "type": "java.util.concurrent.TimeUnit", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.ganglia.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.ganglia.metrics.export.step" - } - }, - { - "name": "management.metrics.export.ganglia.time-to-live", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.ganglia.metrics.export.time-to-live" - } - }, - { - "name": "management.metrics.export.graphite.duration-units", - "type": "java.util.concurrent.TimeUnit", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.duration-units" - } - }, - { - "name": "management.metrics.export.graphite.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.graphite.graphite-tags-enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.graphite-tags-enabled" - } - }, - { - "name": "management.metrics.export.graphite.host", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.host" - } - }, - { - "name": "management.metrics.export.graphite.port", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.port" - } - }, - { - "name": "management.metrics.export.graphite.protocol", - "type": "io.micrometer.graphite.GraphiteProtocol", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.protocol" - } - }, - { - "name": "management.metrics.export.graphite.rate-units", - "type": "java.util.concurrent.TimeUnit", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.rate-units" - } - }, - { - "name": "management.metrics.export.graphite.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.step" - } - }, - { - "name": "management.metrics.export.graphite.tags-as-prefix", - "type": "java.lang.String[]", - "deprecation": { - "level": "error", - "replacement": "management.graphite.metrics.export.tags-as-prefix" - } - }, - { - "name": "management.metrics.export.humio.api-token", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.humio.metrics.export.api-token" - } - }, - { - "name": "management.metrics.export.humio.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.humio.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.humio.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.humio.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.humio.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.humio.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.humio.num-threads", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.humio.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.humio.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.humio.repository", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.humio.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.humio.metrics.export.step" - } - }, - { - "name": "management.metrics.export.humio.tags", - "type": "java.util.Map", - "deprecation": { - "level": "error", - "replacement": "management.humio.metrics.export.tags" - } - }, - { - "name": "management.metrics.export.humio.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.humio.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.influx.api-version", - "type": "io.micrometer.influx.InfluxApiVersion", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.api-version" - } - }, - { - "name": "management.metrics.export.influx.auto-create-db", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.auto-create-db" - } - }, - { - "name": "management.metrics.export.influx.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.influx.bucket", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.bucket" - } - }, - { - "name": "management.metrics.export.influx.compressed", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.compressed" - } - }, - { - "name": "management.metrics.export.influx.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.influx.consistency", - "type": "io.micrometer.influx.InfluxConsistency", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.consistency" - } - }, - { - "name": "management.metrics.export.influx.db", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.db" - } - }, - { - "name": "management.metrics.export.influx.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.influx.num-threads", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.influx.org", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.org" - } - }, - { - "name": "management.metrics.export.influx.password", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.password" - } - }, - { - "name": "management.metrics.export.influx.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.influx.retention-duration", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.retention-duration" - } - }, - { - "name": "management.metrics.export.influx.retention-policy", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.retention-policy" - } - }, - { - "name": "management.metrics.export.influx.retention-replication-factor", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.retention-replication-factor" - } - }, - { - "name": "management.metrics.export.influx.retention-shard-duration", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.retention-shard-duration" - } - }, - { - "name": "management.metrics.export.influx.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.step" - } - }, - { - "name": "management.metrics.export.influx.token", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.token" - } - }, - { - "name": "management.metrics.export.influx.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.influx.user-name", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.influx.metrics.export.user-name" - } - }, - { - "name": "management.metrics.export.jmx.domain", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.jmx.metrics.export.domain" - } - }, - { - "name": "management.metrics.export.jmx.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.jmx.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.jmx.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.jmx.metrics.export.step" - } - }, - { - "name": "management.metrics.export.kairos.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.kairos.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.kairos.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.kairos.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.kairos.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.kairos.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.kairos.num-threads", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.kairos.password", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.kairos.metrics.export.password" - } - }, - { - "name": "management.metrics.export.kairos.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.kairos.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.kairos.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.kairos.metrics.export.step" - } - }, - { - "name": "management.metrics.export.kairos.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.kairos.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.kairos.user-name", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.kairos.metrics.export.user-name" - } - }, - { - "name": "management.metrics.export.newrelic.account-id", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.account-id" - } - }, - { - "name": "management.metrics.export.newrelic.api-key", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.api-key" - } - }, - { - "name": "management.metrics.export.newrelic.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.newrelic.client-provider-type", - "type": "io.micrometer.newrelic.ClientProviderType", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.client-provider-type" - } - }, - { - "name": "management.metrics.export.newrelic.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.newrelic.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.newrelic.event-type", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.event-type" - } - }, - { - "name": "management.metrics.export.newrelic.meter-name-event-type-enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.meter-name-event-type-enabled" - } - }, - { - "name": "management.metrics.export.newrelic.num-threads", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.newrelic.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.newrelic.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.step" - } - }, - { - "name": "management.metrics.export.newrelic.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.newrelic.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.prometheus.descriptions", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.descriptions" - } - }, - { - "name": "management.metrics.export.prometheus.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.prometheus.histogram-flavor", - "type": "io.micrometer.prometheus.HistogramFlavor", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.histogram-flavor" - } - }, - { - "name": "management.metrics.export.prometheus.pushgateway.base-url", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.base-url" - } - }, - { - "name": "management.metrics.export.prometheus.pushgateway.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.enabled" - } - }, - { - "name": "management.metrics.export.prometheus.pushgateway.grouping-key", - "type": "java.util.Map", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.grouping-key" - } - }, - { - "name": "management.metrics.export.prometheus.pushgateway.job", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.job" - } - }, - { - "name": "management.metrics.export.prometheus.pushgateway.password", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.password" - } - }, - { - "name": "management.metrics.export.prometheus.pushgateway.push-rate", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.push-rate" - } - }, - { - "name": "management.metrics.export.prometheus.pushgateway.shutdown-operation", - "type": "org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager$ShutdownOperation", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.shutdown-operation" - } - }, - { - "name": "management.metrics.export.prometheus.pushgateway.username", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.username" - } - }, - { - "name": "management.metrics.export.prometheus.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.step" - } - }, - { - "name": "management.metrics.export.signalfx.access-token", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.access-token" - } - }, - { - "name": "management.metrics.export.signalfx.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.signalfx.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.signalfx.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.signalfx.num-threads", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.signalfx.published-histogram-type", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.published-histogram-type" - } - }, - { - "name": "management.metrics.export.signalfx.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.signalfx.source", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.source" - } - }, - { - "name": "management.metrics.export.signalfx.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.step" - } - }, - { - "name": "management.metrics.export.signalfx.uri", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.signalfx.metrics.export.uri" - } - }, - { - "name": "management.metrics.export.simple.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.simple.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.simple.mode", - "type": "io.micrometer.core.instrument.simple.CountingMode", - "deprecation": { - "level": "error", - "replacement": "management.simple.metrics.export.mode" - } - }, - { - "name": "management.metrics.export.simple.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.simple.metrics.export.step" - } - }, - { - "name": "management.metrics.export.stackdriver.batch-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.batch-size" - } - }, - { - "name": "management.metrics.export.stackdriver.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.connect-timeout" - } - }, - { - "name": "management.metrics.export.stackdriver.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.stackdriver.num-threads", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.export.stackdriver.project-id", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.project-id" - } - }, - { - "name": "management.metrics.export.stackdriver.read-timeout", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.read-timeout" - } - }, - { - "name": "management.metrics.export.stackdriver.resource-labels", - "type": "java.util.Map", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.resource-labels" - } - }, - { - "name": "management.metrics.export.stackdriver.resource-type", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.resource-type" - } - }, - { - "name": "management.metrics.export.stackdriver.step", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.step" - } - }, - { - "name": "management.metrics.export.stackdriver.use-semantic-metric-types", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.stackdriver.metrics.export.use-semantic-metric-types" - } - }, - { - "name": "management.metrics.export.statsd.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.statsd.metrics.export.enabled" - } - }, - { - "name": "management.metrics.export.statsd.flavor", - "type": "io.micrometer.statsd.StatsdFlavor", - "deprecation": { - "level": "error", - "replacement": "management.statsd.metrics.export.flavor" - } - }, - { - "name": "management.metrics.export.statsd.host", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.statsd.metrics.export.host" - } - }, - { - "name": "management.metrics.export.statsd.max-packet-length", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.statsd.metrics.export.max-packet-length" - } - }, - { - "name": "management.metrics.export.statsd.polling-frequency", - "type": "java.time.Duration", - "deprecation": { - "level": "error", - "replacement": "management.statsd.metrics.export.polling-frequency" - } - }, - { - "name": "management.metrics.export.statsd.port", - "type": "java.lang.Integer", - "deprecation": { - "level": "error", - "replacement": "management.statsd.metrics.export.port" - } - }, - { - "name": "management.metrics.export.statsd.protocol", - "type": "io.micrometer.statsd.StatsdProtocol", - "deprecation": { - "level": "error", - "replacement": "management.statsd.metrics.export.protocol" - } - }, - { - "name": "management.metrics.export.statsd.publish-unchanged-meters", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "replacement": "management.statsd.metrics.export.publish-unchanged-meters" - } - }, - { - "name": "management.metrics.export.statsd.queue-size", - "deprecation": { - "level": "error" - } - }, - { - "name": "management.metrics.graphql.autotime.enabled", - "description": "Whether to automatically time web client requests.", - "defaultValue": true, - "deprecation": { - "level": "error", - "reason": "Requests are timed automatically." - } - }, - { - "name": "management.metrics.graphql.autotime.percentiles", - "description": "Computed non-aggregable percentiles to publish.", - "deprecation": { - "level": "error", - "reason": "Should be configured globally via management.metrics.distribution.percentiles." - } - }, - { - "name": "management.metrics.graphql.autotime.percentiles-histogram", - "description": "Whether percentile histograms should be published.", - "defaultValue": false, - "deprecation": { - "level": "error", - "reason": "Should be configured globally via management.metrics.distribution.percentiles-histogram." - } - }, - { - "name": "management.metrics.mongo.command.enabled", - "description": "Whether to enable Mongo client command metrics.", - "defaultValue": true - }, - { - "name": "management.metrics.mongo.connectionpool.enabled", - "description": "Whether to enable Mongo connection pool metrics.", - "defaultValue": true - }, - { - "name": "management.metrics.system.diskspace.paths", - "type": "java.util.List", - "defaultValue": [ - "." - ] - }, - { - "name": "management.metrics.web.client.request.autotime.enabled", - "description": "Whether to automatically time web client requests.", - "defaultValue": true, - "deprecation": { - "level": "error", - "reason": "Requests are timed automatically." - } - }, - { - "name": "management.metrics.web.client.request.autotime.percentiles", - "description": "Computed non-aggregable percentiles to publish.", - "deprecation": { - "level": "error", - "reason": "Should be configured globally via management.metrics.distribution.percentiles." - } - }, - { - "name": "management.metrics.web.client.request.autotime.percentiles-histogram", - "description": "Whether percentile histograms should be published.", - "defaultValue": false, - "deprecation": { - "level": "error", - "reason": "Should be configured globally via management.metrics.distribution.percentiles-histogram." - } - }, - { - "name": "management.metrics.web.client.request.metric-name", - "type": "java.lang.String", - "deprecation": { - "replacement": "management.observations.http.client.requests.name", - "level": "error" - } - }, - { - "name": "management.metrics.web.client.requests-metric-name", - "type": "java.lang.String", - "deprecation": { - "replacement": "management.observations.http.client.requests.name", - "level": "error" - } - }, - { - "name": "management.metrics.web.server.auto-time-requests", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "management.metrics.web.server.request.autotime.enabled", - "level": "error" - } - }, - { - "name": "management.metrics.web.server.request.autotime.enabled", - "description": "Whether to automatically time web server requests.", - "defaultValue": true, - "deprecation": { - "level": "error", - "reason": "Requests are timed automatically." - } - }, - { - "name": "management.metrics.web.server.request.autotime.percentiles", - "description": "Computed non-aggregable percentiles to publish.", - "deprecation": { - "level": "error", - "reason": "Should be configured globally via management.metrics.distribution.percentiles." - } - }, - { - "name": "management.metrics.web.server.request.autotime.percentiles-histogram", - "description": "Whether percentile histograms should be published.", - "defaultValue": false, - "deprecation": { - "level": "error", - "reason": "Should be configured globally via management.metrics.distribution.percentiles-histogram." - } - }, - { - "name": "management.metrics.web.server.request.ignore-trailing-slash", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error", - "reason": "Not needed anymore, direct instrumentation in Spring MVC." - } - }, - { - "name": "management.metrics.web.server.request.metric-name", - "type": "java.lang.String", - "deprecation": { - "replacement": "management.observations.http.server.requests.name", - "level": "error" - } - }, - { - "name": "management.metrics.web.server.requests-metric-name", - "type": "java.lang.String", - "deprecation": { - "replacement": "management.observations.http.server.requests.name", - "level": "error" - } - }, - { - "name": "management.observations.annotations.enabled", - "type": "java.lang.Boolean", - "description": "Whether auto-configuration of Micrometer annotations is enabled.", - "defaultValue": false - }, - { - "name": "management.otlp.logging.export.enabled", - "type": "java.lang.Boolean", - "description": "Whether auto-configuration of logging is enabled to export OTLP logs." - }, - { - "name": "management.otlp.tracing.export.enabled", - "type": "java.lang.Boolean", - "description": "Whether auto-configuration of tracing is enabled to export OTLP traces." - }, - { - "name": "management.promethus.metrics.export.pushgateway.base-url", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "replacement": "management.prometheus.metrics.export.pushgateway.address" - } - }, - { - "name": "management.server.add-application-context-header", - "type": "java.lang.Boolean", - "description": "Add the \"X-Application-Context\" HTTP header in each response.", - "defaultValue": false - }, - { - "name": "management.server.servlet.context-path", - "type": "java.lang.String", - "deprecation": { - "replacement": "management.server.base-path", - "level": "error" - } - }, - { - "name": "management.trace.http.enabled", - "deprecation": { - "replacement": "management.httpexchanges.recording.enabled", - "level": "error" - } - }, - { - "name": "management.trace.http.include", - "deprecation": { - "replacement": "management.httpexchanges.recording.include", - "level": "error" - } - }, - { - "name": "management.trace.include", - "deprecation": { - "replacement": "management.httpexchanges.recording.include", - "level": "error" - } - }, - { - "name": "management.tracing.enabled", - "type": "java.lang.Boolean", - "description": "Whether auto-configuration of tracing is enabled to export and propagate traces.", - "defaultValue": true - }, - { - "name": "management.tracing.propagation.consume", - "defaultValue": [ - "W3C", - "B3", - "B3_MULTI" - ] - }, - { - "name": "management.tracing.propagation.produce", - "defaultValue": [ - "W3C" - ] - }, - { - "name": "management.zipkin.tracing.encoding", - "defaultValue": [ - "JSON" - ] - }, - { - "name": "management.zipkin.tracing.export.enabled", - "type": "java.lang.Boolean", - "description": "Whether auto-configuration of tracing is enabled to export Zipkin traces." } ], "hints": [ diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener deleted file mode 100644 index 284014dde279..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryEventPublisherBeansTestExecutionListener diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories index 143d99335558..6c182b95249d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1,16 +1,3 @@ -# Endpoint Exposure Outcome Contributors -org.springframework.boot.actuate.autoconfigure.endpoint.condition.EndpointExposureOutcomeContributor=\ -org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryEndpointExposureOutcomeContributor - # Failure Analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ -org.springframework.boot.actuate.autoconfigure.health.NoSuchHealthContributorFailureAnalyzer,\ -org.springframework.boot.actuate.autoconfigure.metrics.ValidationFailureAnalyzer - -# Environment Post Processors -org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.boot.actuate.autoconfigure.tracing.LogCorrelationEnvironmentPostProcessor - -# Application Listeners -org.springframework.context.ApplicationListener=\ -org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryEventPublisherBeansApplicationListener +org.springframework.boot.actuate.autoconfigure.health.NoSuchHealthContributorFailureAnalyzer diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/aot.factories deleted file mode 100644 index e5251df8307a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/aot.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.aot.hint.RuntimeHintsRegistrar=\ -org.springframework.boot.actuate.autoconfigure.metrics.ServiceLevelObjectiveBoundary$ServiceLevelObjectiveBoundaryHints diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports deleted file mode 100644 index 136ca5970386..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports +++ /dev/null @@ -1,10 +0,0 @@ -org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration -org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration -org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration -org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration -org.springframework.boot.actuate.autoconfigure.security.servlet.SecurityRequestMatchersManagementContextConfiguration -org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration -org.springframework.boot.actuate.autoconfigure.web.jersey.JerseyChildManagementContextConfiguration -org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration -org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration -org.springframework.boot.actuate.autoconfigure.web.servlet.WebMvcEndpointChildContextConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index ff22848cf1a3..ac80acd90ec7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,122 +1,28 @@ -org.springframework.boot.actuate.autoconfigure.amqp.RabbitHealthContributorAutoConfiguration org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration org.springframework.boot.actuate.autoconfigure.audit.AuditEventsEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.availability.AvailabilityHealthContributorAutoConfiguration org.springframework.boot.actuate.autoconfigure.availability.AvailabilityProbesAutoConfiguration org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.cache.CachesEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.cassandra.CassandraHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.cassandra.CassandraReactiveHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.ReactiveCloudFoundryActuatorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryActuatorAutoConfiguration org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.context.properties.ConfigurationPropertiesReportEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.couchbase.CouchbaseHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.couchbase.CouchbaseReactiveHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.data.elasticsearch.ElasticsearchReactiveHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.data.mongo.MongoHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.data.mongo.MongoReactiveHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.data.redis.RedisHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.data.redis.RedisReactiveHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticsearchRestHealthContributorAutoConfiguration org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.endpoint.jackson.JacksonEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.flyway.FlywayEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.hazelcast.HazelcastHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.integration.IntegrationGraphEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.jms.JmsHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.ldap.LdapHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.liquibase.LiquibaseEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.logging.LogFileWebEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.logging.LoggersEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.logging.OpenTelemetryLoggingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.mail.MailHealthContributorAutoConfiguration org.springframework.boot.actuate.autoconfigure.management.HeapDumpWebEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.management.ThreadDumpEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.JvmMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.KafkaMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.Log4J2MetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.LogbackMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.MetricsAspectsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.MetricsEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.SystemMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.amqp.RabbitMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.data.RepositoryMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics.AppOpticsMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.datadog.DatadogMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace.DynatraceMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.elastic.ElasticMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.GangliaMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.humio.HumioMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.influx.InfluxMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.kairos.KairosMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic.NewRelicMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx.SignalFxMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver.StackdriverMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.integration.IntegrationMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.jersey.JerseyServerMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.mongo.MongoMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.r2dbc.ConnectionPoolMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.redis.LettuceMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.startup.StartupTimeMetricsListenerAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.task.TaskExecutorMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.web.jetty.JettyMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat.TomcatMetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.neo4j.Neo4jHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration -org.springframework.boot.actuate.autoconfigure.observation.batch.BatchObservationAutoConfiguration -org.springframework.boot.actuate.autoconfigure.observation.batch.BatchObservationAutoConfiguration -org.springframework.boot.actuate.autoconfigure.observation.graphql.GraphQlObservationAutoConfiguration -org.springframework.boot.actuate.autoconfigure.observation.graphql.GraphQlObservationAutoConfiguration -org.springframework.boot.actuate.autoconfigure.observation.web.client.HttpClientObservationsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.observation.web.reactive.WebFluxObservationAutoConfiguration -org.springframework.boot.actuate.autoconfigure.observation.web.servlet.WebMvcObservationAutoConfiguration -org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryAutoConfiguration -org.springframework.boot.actuate.autoconfigure.quartz.QuartzEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.r2dbc.ConnectionFactoryHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.r2dbc.R2dbcObservationAutoConfiguration org.springframework.boot.actuate.autoconfigure.sbom.SbomEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.scheduling.ScheduledTasksEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.scheduling.ScheduledTasksObservabilityAutoConfiguration -org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration -org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration -org.springframework.boot.actuate.autoconfigure.session.SessionsEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.ssl.SslHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.ssl.SslObservabilityAutoConfiguration org.springframework.boot.actuate.autoconfigure.startup.StartupEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.NoopTracerAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.prometheus.PrometheusExemplarsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration -org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration -org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements deleted file mode 100644 index 86a848dac233..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration=org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpAutoConfiguration=org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java deleted file mode 100644 index 85220fbe4f0e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.amqp; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.MeterBinder; -import org.junit.jupiter.api.Test; - -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.amqp.RabbitMetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Integration test to check that {@link RabbitMetricsAutoConfiguration} does not cause a - * dependency cycle when used with {@link MeterBinder}. - * - * @author Phillip Webb - * @see gh-30636 - */ -class RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests { - - @Test - void doesNotFormCycle() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class); - context.getBean(TestService.class); - context.close(); - } - - @Configuration - @Import({ TestService.class, RabbitAutoConfiguration.class, MetricsAutoConfiguration.class, - SimpleMetricsExportAutoConfiguration.class, RabbitMetricsAutoConfiguration.class }) - static class TestConfig { - - } - - static class TestService implements MeterBinder { - - TestService(RabbitTemplate rabbitTemplate) { - } - - @Override - public void bindTo(MeterRegistry registry) { - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java index 390ce9f778ef..f13f1291e097 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java @@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration; import org.springframework.boot.availability.ApplicationAvailability; +import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -60,6 +61,13 @@ void probesWhenPropertyEnabledAddsBeans() { .run(this::hasProbesBeans); } + @Test + void probesWhenPropertyEnabledButNoHealthDependencyDoesNotAddBeans() { + this.contextRunner.withPropertyValues("management.endpoint.health.probes.enabled=true") + .withClassLoader(new FilteredClassLoader("org.springframework.boot.health")) + .run(this::doesNotHaveProbeBeans); + } + @Test void probesWhenKubernetesAndPropertyDisabledAddsNotBeans() { this.contextRunner diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryReactiveHealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryReactiveHealthEndpointWebExtensionTests.java deleted file mode 100644 index 93a4374291c7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryReactiveHealthEndpointWebExtensionTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.endpoint.ApiVersion; -import org.springframework.boot.actuate.health.CompositeHealth; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthComponent; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; -import org.springframework.security.core.userdetails.User; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link CloudFoundryReactiveHealthEndpointWebExtension}. - * - * @author Madhura Bhave - */ -class CloudFoundryReactiveHealthEndpointWebExtensionTests { - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withPropertyValues("VCAP_APPLICATION={}") - .withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class, - WebFluxAutoConfiguration.class, JacksonAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ReactiveCloudFoundryActuatorAutoConfigurationTests.WebClientCustomizerConfig.class, - WebClientAutoConfiguration.class, ManagementContextAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class, - ReactiveCloudFoundryActuatorAutoConfiguration.class)) - .withUserConfiguration(TestHealthIndicator.class, UserDetailsServiceConfiguration.class); - - @Test - void healthComponentsAlwaysPresent() { - this.contextRunner.run((context) -> { - CloudFoundryReactiveHealthEndpointWebExtension extension = context - .getBean(CloudFoundryReactiveHealthEndpointWebExtension.class); - HealthComponent body = extension.health(ApiVersion.V3).block(Duration.ofSeconds(30)).getBody(); - HealthComponent health = ((CompositeHealth) body).getComponents().entrySet().iterator().next().getValue(); - assertThat(((Health) health).getDetails()).containsEntry("spring", "boot"); - }); - } - - private static final class TestHealthIndicator implements HealthIndicator { - - @Override - public Health health() { - return Health.up().withDetail("spring", "boot").build(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UserDetailsServiceConfiguration { - - @Bean - MapReactiveUserDetailsService userDetailsService() { - return new MapReactiveUserDetailsService( - User.withUsername("alice").password("secret").roles("admin").build()); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java deleted file mode 100644 index 3a96362756c4..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.io.IOException; -import java.time.Duration; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import javax.net.ssl.SSLException; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.assertj.core.api.InstanceOfAssertFactories; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import reactor.netty.http.HttpResources; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryInfoEndpointWebExtension; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.endpoint.ApiVersion; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; -import org.springframework.boot.actuate.endpoint.web.WebOperation; -import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.jks.JksSslStoreBundle; -import org.springframework.boot.ssl.jks.JksSslStoreDetails; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.ResponseEntity; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.web.server.MockServerWebExchange; -import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.web.server.SecurityWebFilterChain; -import org.springframework.security.web.server.WebFilterChainProxy; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ReactiveCloudFoundryActuatorAutoConfiguration}. - * - * @author Madhura Bhave - * @author Moritz Halbritter - */ -class ReactiveCloudFoundryActuatorAutoConfigurationTests { - - private static final String V2_JSON = ApiVersion.V2.getProducedMimeType().toString(); - - private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString(); - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class, WebFluxAutoConfiguration.class, - JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, WebClientCustomizerConfig.class, - WebClientAutoConfiguration.class, ManagementContextAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class, - InfoContributorAutoConfiguration.class, InfoEndpointAutoConfiguration.class, - ProjectInfoAutoConfiguration.class, ReactiveCloudFoundryActuatorAutoConfiguration.class)) - .withUserConfiguration(UserDetailsServiceConfiguration.class); - - private static final String BASE_PATH = "/cloudfoundryapplication"; - - @AfterEach - void close() { - HttpResources.reset(); - } - - @Test - void cloudFoundryPlatformActive() { - this.contextRunner - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> { - CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context); - assertThat(handlerMapping).extracting("endpointMapping.path").isEqualTo("/cloudfoundryapplication"); - assertThat(handlerMapping) - .extracting("corsConfiguration", InstanceOfAssertFactories.type(CorsConfiguration.class)) - .satisfies((corsConfiguration) -> { - assertThat(corsConfiguration.getAllowedOrigins()).contains("*"); - assertThat(corsConfiguration.getAllowedMethods()) - .containsAll(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name())); - assertThat(corsConfiguration.getAllowedHeaders()) - .containsAll(Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type")); - }); - }); - } - - @Test - void cloudfoundryapplicationProducesActuatorMediaType() { - this.contextRunner - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> { - WebTestClient webTestClient = WebTestClient.bindToApplicationContext(context).build(); - webTestClient.get().uri("/cloudfoundryapplication").header("Content-Type", V2_JSON + ";charset=UTF-8"); - }); - } - - @Test - void cloudFoundryPlatformActiveSetsApplicationId() { - this.contextRunner - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> assertThat(getHandlerMapping(context)).extracting("securityInterceptor.applicationId") - .isEqualTo("my-app-id")); - } - - @Test - void cloudFoundryPlatformActiveSetsCloudControllerUrl() { - this.contextRunner - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> assertThat(getHandlerMapping(context)) - .extracting("securityInterceptor.cloudFoundrySecurityService.cloudControllerUrl") - .isEqualTo("https://my-cloud-controller.com")); - } - - @Test - void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() { - this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id") - .run((context) -> assertThat(context.getBean("cloudFoundryWebFluxEndpointHandlerMapping", - CloudFoundryWebFluxEndpointHandlerMapping.class)) - .extracting("securityInterceptor.cloudFoundrySecurityService") - .isNull()); - } - - @Test - @SuppressWarnings("unchecked") - void cloudFoundryPathsIgnoredBySpringSecurity() { - this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new) - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> { - assertThat(context.getBean(WebFilterChainProxy.class)) - .extracting("filters", InstanceOfAssertFactories.list(SecurityWebFilterChain.class)) - .satisfies((filters) -> { - Boolean cfBaseRequestMatches = getMatches(filters, BASE_PATH); - Boolean cfBaseWithTrailingSlashRequestMatches = getMatches(filters, BASE_PATH + "/"); - Boolean cfRequestMatches = getMatches(filters, BASE_PATH + "/test"); - Boolean cfRequestWithAdditionalPathMatches = getMatches(filters, BASE_PATH + "/test/a"); - Boolean otherCfRequestMatches = getMatches(filters, BASE_PATH + "/other-path"); - Boolean otherRequestMatches = getMatches(filters, "/some-other-path"); - assertThat(cfBaseRequestMatches).isTrue(); - assertThat(cfBaseWithTrailingSlashRequestMatches).isTrue(); - assertThat(cfRequestMatches).isTrue(); - assertThat(cfRequestWithAdditionalPathMatches).isTrue(); - assertThat(otherCfRequestMatches).isFalse(); - assertThat(otherRequestMatches).isFalse(); - otherRequestMatches = filters.get(1) - .matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build())) - .block(Duration.ofSeconds(30)); - assertThat(otherRequestMatches).isTrue(); - }); - }); - } - - private static Boolean getMatches(List filters, String urlTemplate) { - return filters.get(0) - .matches(MockServerWebExchange.from(MockServerHttpRequest.get(urlTemplate).build())) - .block(Duration.ofSeconds(30)); - } - - @Test - void cloudFoundryPlatformInactive() { - this.contextRunner - .run((context) -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping")).isFalse()); - } - - @Test - void cloudFoundryManagementEndpointsDisabled() { - this.contextRunner.withPropertyValues("VCAP_APPLICATION=---", "management.cloudfoundry.enabled:false") - .run((context) -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping")).isFalse()); - } - - @Test - void allEndpointsAvailableUnderCloudFoundryWithoutEnablingWebIncludes() { - this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new) - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> { - CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context); - Collection endpoints = handlerMapping.getEndpoints(); - List endpointIds = endpoints.stream().map(ExposableWebEndpoint::getEndpointId).toList(); - assertThat(endpointIds).contains(EndpointId.of("test")); - }); - } - - @Test - void endpointPathCustomizationIsNotApplied() { - this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new) - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> { - CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context); - Collection endpoints = handlerMapping.getEndpoints(); - ExposableWebEndpoint endpoint = endpoints.stream() - .filter((candidate) -> EndpointId.of("test").equals(candidate.getEndpointId())) - .findFirst() - .get(); - assertThat(endpoint.getOperations()).hasSize(1); - WebOperation operation = endpoint.getOperations().iterator().next(); - assertThat(operation.getRequestPredicate().getPath()).isEqualTo("test"); - }); - } - - @Test - void healthEndpointInvokerShouldBeCloudFoundryWebExtension() { - this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class)) - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> { - Collection endpoints = getHandlerMapping(context).getEndpoints(); - ExposableWebEndpoint endpoint = endpoints.iterator().next(); - assertThat(endpoint.getOperations()).hasSize(2); - WebOperation webOperation = findOperationWithRequestPath(endpoint, "health"); - assertThat(webOperation).extracting("invoker") - .extracting("target") - .isInstanceOf(CloudFoundryReactiveHealthEndpointWebExtension.class); - }); - } - - @Test - @WithResource(name = "git.properties", content = """ - #Generated by Git-Commit-Id-Plugin - #Thu May 23 09:26:42 BST 2013 - git.commit.id.abbrev=e02a4f3 - git.commit.user.email=dsyer@vmware.com - git.commit.message.full=Update Spring - git.commit.id=e02a4f3b6f452cdbf6dd311f1362679eb4c31ced - git.commit.message.short=Update Spring - git.commit.user.name=Dave Syer - git.build.user.name=Dave Syer - git.build.user.email=dsyer@vmware.com - git.branch=develop - git.commit.time=2013-04-24T08\\:42\\:13+0100 - git.build.time=2013-05-23T09\\:26\\:42+0100 - """) - @SuppressWarnings("unchecked") - void gitFullDetailsAlwaysPresent() { - this.contextRunner.withPropertyValues("VCAP_APPLICATION:---").run((context) -> { - CloudFoundryInfoEndpointWebExtension extension = context - .getBean(CloudFoundryInfoEndpointWebExtension.class); - Map git = (Map) extension.info().get("git"); - Map commit = (Map) git.get("commit"); - assertThat(commit).hasSize(4); - }); - } - - @Test - @WithPackageResources("test.jks") - void skipSslValidation() throws IOException { - JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails("JKS", null, "classpath:test.jks", "secret"); - SslBundle sslBundle = SslBundle.of(new JksSslStoreBundle(keyStoreDetails, keyStoreDetails)); - try (MockWebServer server = new MockWebServer()) { - server.useHttps(sslBundle.createSslContext().getSocketFactory(), false); - server.enqueue(new MockResponse().setResponseCode(204)); - server.start(); - this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class)) - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com", - "management.cloudfoundry.skip-ssl-validation:true") - .run((context) -> assertThat(getHandlerMapping(context)) - .extracting("securityInterceptor.cloudFoundrySecurityService.webClient", - InstanceOfAssertFactories.type(WebClient.class)) - .satisfies((webClient) -> { - ResponseEntity response = webClient.get() - .uri(server.url("/").uri()) - .retrieve() - .toBodilessEntity() - .block(Duration.ofSeconds(30)); - assertThat(response.getStatusCode()).isEqualTo(HttpStatusCode.valueOf(204)); - })); - } - } - - @Test - @WithPackageResources("test.jks") - void sslValidationNotSkippedByDefault() throws IOException { - JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails("JKS", null, "classpath:test.jks", "secret"); - SslBundle sslBundle = SslBundle.of(new JksSslStoreBundle(keyStoreDetails, keyStoreDetails)); - try (MockWebServer server = new MockWebServer()) { - server.useHttps(sslBundle.createSslContext().getSocketFactory(), false); - server.enqueue(new MockResponse().setResponseCode(204)); - server.start(); - this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class)) - .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com") - .run((context) -> assertThat(getHandlerMapping(context)) - .extracting("securityInterceptor.cloudFoundrySecurityService.webClient", - InstanceOfAssertFactories.type(WebClient.class)) - .satisfies((webClient) -> assertThatExceptionOfType(RuntimeException.class) - .isThrownBy(() -> webClient.get() - .uri(server.url("/").uri()) - .retrieve() - .toBodilessEntity() - .block(Duration.ofSeconds(30))) - .withCauseInstanceOf(SSLException.class))); - } - } - - private CloudFoundryWebFluxEndpointHandlerMapping getHandlerMapping(ApplicationContext context) { - return context.getBean("cloudFoundryWebFluxEndpointHandlerMapping", - CloudFoundryWebFluxEndpointHandlerMapping.class); - } - - private WebOperation findOperationWithRequestPath(ExposableWebEndpoint endpoint, String requestPath) { - for (WebOperation operation : endpoint.getOperations()) { - WebOperationRequestPredicate predicate = operation.getRequestPredicate(); - if (predicate.getPath().equals(requestPath) && predicate.getProduces().contains(V3_JSON)) { - return operation; - } - } - throw new IllegalStateException( - "No operation found with request path " + requestPath + " from " + endpoint.getOperations()); - } - - @Endpoint(id = "test") - static class TestEndpoint { - - @ReadOperation - String hello() { - return "hello world"; - } - - } - - @Configuration(proxyBeanMethods = false) - static class WebClientCustomizerConfig { - - @Bean - WebClientCustomizer webClientCustomizer() { - return mock(WebClientCustomizer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UserDetailsServiceConfiguration { - - @Bean - MapReactiveUserDetailsService userDetailsService() { - return new MapReactiveUserDetailsService( - User.withUsername("alice").password("secret").roles("admin").build()); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityInterceptorTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityInterceptorTests.java deleted file mode 100644 index ce7e41d04a00..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityInterceptorTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.time.Duration; -import java.util.Base64; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.web.server.MockServerWebExchange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; - -/** - * Tests for {@link CloudFoundrySecurityInterceptor}. - * - * @author Madhura Bhave - */ -@ExtendWith(MockitoExtension.class) -class ReactiveCloudFoundrySecurityInterceptorTests { - - @Mock - private ReactiveTokenValidator tokenValidator; - - @Mock - private ReactiveCloudFoundrySecurityService securityService; - - private CloudFoundrySecurityInterceptor interceptor; - - @BeforeEach - void setup() { - this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, this.securityService, "my-app-id"); - } - - @Test - void preHandleWhenRequestIsPreFlightShouldBeOk() { - MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.options("/a") - .header(HttpHeaders.ORIGIN, "https://example.com") - .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET") - .build()); - StepVerifier.create(this.interceptor.preHandle(request, "/a")) - .consumeNextWith((response) -> assertThat(response.getStatus()).isEqualTo(HttpStatus.OK)) - .expectComplete() - .verify(Duration.ofSeconds(30)); - } - - @Test - void preHandleWhenTokenIsMissingShouldReturnMissingAuthorization() { - MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a").build()); - StepVerifier.create(this.interceptor.preHandle(request, "/a")) - .consumeNextWith( - (response) -> assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus())) - .expectComplete() - .verify(Duration.ofSeconds(30)); - } - - @Test - void preHandleWhenTokenIsNotBearerShouldReturnMissingAuthorization() { - MockServerWebExchange request = MockServerWebExchange - .from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build()); - StepVerifier.create(this.interceptor.preHandle(request, "/a")) - .consumeNextWith( - (response) -> assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus())) - .expectComplete() - .verify(Duration.ofSeconds(30)); - } - - @Test - void preHandleWhenApplicationIdIsNullShouldReturnError() { - this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, this.securityService, null); - MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a") - .header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()) - .build()); - StepVerifier.create(this.interceptor.preHandle(request, "/a")) - .consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason()) - .isEqualTo(Reason.SERVICE_UNAVAILABLE)) - .verify(); - } - - @Test - void preHandleWhenCloudFoundrySecurityServiceIsNullShouldReturnError() { - this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, null, "my-app-id"); - MockServerWebExchange request = MockServerWebExchange - .from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build()); - StepVerifier.create(this.interceptor.preHandle(request, "/a")) - .consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason()) - .isEqualTo(Reason.SERVICE_UNAVAILABLE)) - .verify(); - } - - @Test - void preHandleWhenAccessIsNotAllowedShouldReturnAccessDenied() { - given(this.securityService.getAccessLevel(mockAccessToken(), "my-app-id")) - .willReturn(Mono.just(AccessLevel.RESTRICTED)); - given(this.tokenValidator.validate(any())).willReturn(Mono.empty()); - MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a") - .header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()) - .build()); - StepVerifier.create(this.interceptor.preHandle(request, "/a")) - .consumeNextWith((response) -> assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus())) - .expectComplete() - .verify(Duration.ofSeconds(30)); - } - - @Test - void preHandleSuccessfulWithFullAccess() { - String accessToken = mockAccessToken(); - given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(Mono.just(AccessLevel.FULL)); - given(this.tokenValidator.validate(any())).willReturn(Mono.empty()); - MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/a") - .header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()) - .build()); - StepVerifier.create(this.interceptor.preHandle(exchange, "/a")).consumeNextWith((response) -> { - assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); - assertThat((AccessLevel) exchange.getAttribute("cloudFoundryAccessLevel")).isEqualTo(AccessLevel.FULL); - }).expectComplete().verify(Duration.ofSeconds(30)); - } - - @Test - void preHandleSuccessfulWithRestrictedAccess() { - String accessToken = mockAccessToken(); - given(this.securityService.getAccessLevel(accessToken, "my-app-id")) - .willReturn(Mono.just(AccessLevel.RESTRICTED)); - given(this.tokenValidator.validate(any())).willReturn(Mono.empty()); - MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/info") - .header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()) - .build()); - StepVerifier.create(this.interceptor.preHandle(exchange, "info")).consumeNextWith((response) -> { - assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); - assertThat((AccessLevel) exchange.getAttribute("cloudFoundryAccessLevel")) - .isEqualTo(AccessLevel.RESTRICTED); - }).expectComplete().verify(Duration.ofSeconds(30)); - } - - private String mockAccessToken() { - return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu" - + "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ." - + Base64.getEncoder().encodeToString("signature".getBytes()); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityServiceTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityServiceTests.java deleted file mode 100644 index d1c8dd1a33da..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityServiceTests.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.util.function.Consumer; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.test.StepVerifier; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.http.HttpHeaders; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ReactiveCloudFoundrySecurityService}. - * - * @author Madhura Bhave - */ -class ReactiveCloudFoundrySecurityServiceTests { - - private static final String CLOUD_CONTROLLER = "/my-cloud-controller.com"; - - private static final String CLOUD_CONTROLLER_PERMISSIONS = CLOUD_CONTROLLER + "/v2/apps/my-app-id/permissions"; - - private static final String UAA_URL = "https://my-cloud-controller.com/uaa"; - - private ReactiveCloudFoundrySecurityService securityService; - - private MockWebServer server; - - @BeforeEach - void setup() { - this.server = new MockWebServer(); - WebClient.Builder builder = WebClient.builder().baseUrl(this.server.url("/").toString()); - this.securityService = new ReactiveCloudFoundrySecurityService(builder, CLOUD_CONTROLLER, false); - } - - @AfterEach - void shutdown() throws Exception { - this.server.shutdown(); - } - - @Test - void getAccessLevelWhenSpaceDeveloperShouldReturnFull() throws Exception { - String responseBody = "{\"read_sensitive_data\": true,\"read_basic_data\": true}"; - prepareResponse((response) -> response.setBody(responseBody).setHeader("Content-Type", "application/json")); - StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) - .consumeNextWith((accessLevel) -> assertThat(accessLevel).isEqualTo(AccessLevel.FULL)) - .expectComplete() - .verify(); - expectRequest((request) -> { - assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); - assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); - }); - } - - @Test - void getAccessLevelWhenNotSpaceDeveloperShouldReturnRestricted() throws Exception { - String responseBody = "{\"read_sensitive_data\": false,\"read_basic_data\": true}"; - prepareResponse((response) -> response.setBody(responseBody).setHeader("Content-Type", "application/json")); - StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) - .consumeNextWith((accessLevel) -> assertThat(accessLevel).isEqualTo(AccessLevel.RESTRICTED)) - .expectComplete() - .verify(); - expectRequest((request) -> { - assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); - assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); - }); - } - - @Test - void getAccessLevelWhenTokenIsNotValidShouldThrowException() throws Exception { - prepareResponse((response) -> response.setResponseCode(401)); - StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) - .consumeErrorWith((throwable) -> { - assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) - .isEqualTo(Reason.INVALID_TOKEN); - }) - .verify(); - expectRequest((request) -> { - assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); - assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); - }); - } - - @Test - void getAccessLevelWhenForbiddenShouldThrowException() throws Exception { - prepareResponse((response) -> response.setResponseCode(403)); - StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) - .consumeErrorWith((throwable) -> { - assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) - .isEqualTo(Reason.ACCESS_DENIED); - }) - .verify(); - expectRequest((request) -> { - assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); - assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); - }); - } - - @Test - void getAccessLevelWhenCloudControllerIsNotReachableThrowsException() throws Exception { - prepareResponse((response) -> response.setResponseCode(500)); - StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) - .consumeErrorWith((throwable) -> { - assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) - .isEqualTo(Reason.SERVICE_UNAVAILABLE); - }) - .verify(); - expectRequest((request) -> { - assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); - assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); - }); - } - - @Test - void fetchTokenKeysWhenSuccessfulShouldReturnListOfKeysFromUAA() throws Exception { - String tokenKeyValue = """ - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO - rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7 - fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB - LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO - kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo - jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI - JwIDAQAB - -----END PUBLIC KEY-----"""; - prepareResponse((response) -> { - response.setBody("{\"token_endpoint\":\"/my-uaa.com\"}"); - response.setHeader("Content-Type", "application/json"); - }); - String responseBody = "{\"keys\" : [ {\"kid\":\"test-key\",\"value\" : \"" + tokenKeyValue.replace("\n", "\\n") - + "\"} ]}"; - prepareResponse((response) -> { - response.setBody(responseBody); - response.setHeader("Content-Type", "application/json"); - }); - StepVerifier.create(this.securityService.fetchTokenKeys()) - .consumeNextWith((tokenKeys) -> assertThat(tokenKeys.get("test-key")).isEqualTo(tokenKeyValue)) - .expectComplete() - .verify(); - expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info")); - expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys")); - } - - @Test - void fetchTokenKeysWhenNoKeysReturnedFromUAA() throws Exception { - prepareResponse((response) -> { - response.setBody("{\"token_endpoint\":\"/my-uaa.com\"}"); - response.setHeader("Content-Type", "application/json"); - }); - String responseBody = "{\"keys\": []}"; - prepareResponse((response) -> { - response.setBody(responseBody); - response.setHeader("Content-Type", "application/json"); - }); - StepVerifier.create(this.securityService.fetchTokenKeys()) - .consumeNextWith((tokenKeys) -> assertThat(tokenKeys).isEmpty()) - .expectComplete() - .verify(); - expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info")); - expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys")); - } - - @Test - void fetchTokenKeysWhenUnsuccessfulShouldThrowException() throws Exception { - prepareResponse((response) -> { - response.setBody("{\"token_endpoint\":\"/my-uaa.com\"}"); - response.setHeader("Content-Type", "application/json"); - }); - prepareResponse((response) -> response.setResponseCode(500)); - StepVerifier.create(this.securityService.fetchTokenKeys()) - .consumeErrorWith((throwable) -> assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) - .isEqualTo(Reason.SERVICE_UNAVAILABLE)) - .verify(); - expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info")); - expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys")); - } - - @Test - void getUaaUrlShouldCallCloudControllerInfoOnlyOnce() throws Exception { - prepareResponse((response) -> { - response.setBody("{\"token_endpoint\":\"" + UAA_URL + "\"}"); - response.setHeader("Content-Type", "application/json"); - }); - StepVerifier.create(this.securityService.getUaaUrl()) - .consumeNextWith((uaaUrl) -> assertThat(uaaUrl).isEqualTo(UAA_URL)) - .expectComplete() - .verify(); - expectRequest((request) -> assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER + "/info")); - expectRequestCount(1); - } - - @Test - void getUaaUrlWhenCloudControllerUrlIsNotReachableShouldThrowException() throws Exception { - prepareResponse((response) -> response.setResponseCode(500)); - StepVerifier.create(this.securityService.getUaaUrl()).consumeErrorWith((throwable) -> { - assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) - .isEqualTo(Reason.SERVICE_UNAVAILABLE); - }).verify(); - expectRequest((request) -> assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER + "/info")); - } - - private void prepareResponse(Consumer consumer) { - MockResponse response = new MockResponse(); - consumer.accept(response); - this.server.enqueue(response); - } - - private void expectRequest(Consumer consumer) throws InterruptedException { - consumer.accept(this.server.takeRequest()); - } - - private void expectRequestCount(int count) { - assertThat(count).isEqualTo(this.server.getRequestCount()); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidatorTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidatorTests.java deleted file mode 100644 index d97ad702a465..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveTokenValidatorTests.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.Signature; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.time.Duration; -import java.util.Base64; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; -import reactor.test.publisher.PublisherProbe; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Tests for {@link ReactiveTokenValidator}. - * - * @author Madhura Bhave - */ -@ExtendWith(MockitoExtension.class) -class ReactiveTokenValidatorTests { - - private static final byte[] DOT = ".".getBytes(); - - @Mock - private ReactiveCloudFoundrySecurityService securityService; - - private ReactiveTokenValidator tokenValidator; - - private static final String VALID_KEY = """ - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO - rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7 - fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB - LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO - kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo - jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI - JwIDAQAB - -----END PUBLIC KEY-----"""; - - private static final String INVALID_KEY = """ - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzYuc22QSst/dS7geYYK - 5l5kLxU0tayNdixkEQ17ix+CUcUbKIsnyftZxaCYT46rQtXgCaYRdJcbB3hmyrOa - vkhTpX79xJZnQmfuamMbZBqitvscxW9zRR9tBUL6vdi/0rpoUwPMEh8+Bw7CgYR0 - FK0DhWYBNDfe9HKcyZEv3max8Cdq18htxjEsdYO0iwzhtKRXomBWTdhD5ykd/fAC - VTr4+KEY+IeLvubHVmLUhbE5NgWXxrRpGasDqzKhCTmsa2Ysf712rl57SlH0Wz/M - r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s - YwIDAQAB - -----END PUBLIC KEY-----"""; - - private static final Map INVALID_KEYS = new ConcurrentHashMap<>(); - - private static final Map VALID_KEYS = new ConcurrentHashMap<>(); - - @BeforeEach - void setup() { - VALID_KEYS.put("valid-key", VALID_KEY); - INVALID_KEYS.put("invalid-key", INVALID_KEY); - this.tokenValidator = new ReactiveTokenValidator(this.securityService); - } - - @Test - void validateTokenWhenKidValidationFailsTwiceShouldThrowException() throws Exception { - PublisherProbe> fetchTokenKeys = PublisherProbe.of(Mono.just(VALID_KEYS)); - ReflectionTestUtils.setField(this.tokenValidator, "cachedTokenKeys", VALID_KEYS); - given(this.securityService.fetchTokenKeys()).willReturn(fetchTokenKeys.mono()); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{\"alg\": \"RS256\", \"kid\": \"invalid-key\",\"typ\": \"JWT\"}"; - String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .consumeErrorWith((ex) -> { - assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_KEY_ID); - }) - .verify(); - assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS); - fetchTokenKeys.assertWasSubscribed(); - } - - @Test - void validateTokenWhenKidValidationSucceedsInTheSecondAttempt() throws Exception { - PublisherProbe> fetchTokenKeys = PublisherProbe.of(Mono.just(VALID_KEYS)); - ReflectionTestUtils.setField(this.tokenValidator, "cachedTokenKeys", INVALID_KEYS); - given(this.securityService.fetchTokenKeys()).willReturn(fetchTokenKeys.mono()); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .expectComplete() - .verify(Duration.ofSeconds(30)); - assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS); - fetchTokenKeys.assertWasSubscribed(); - } - - @Test - void validateTokenWhenCacheIsEmptyShouldFetchTokenKeys() throws Exception { - PublisherProbe> fetchTokenKeys = PublisherProbe.of(Mono.just(VALID_KEYS)); - given(this.securityService.fetchTokenKeys()).willReturn(fetchTokenKeys.mono()); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .expectComplete() - .verify(Duration.ofSeconds(30)); - assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS); - fetchTokenKeys.assertWasSubscribed(); - } - - @Test - void validateTokenWhenCacheEmptyAndInvalidKeyShouldThrowException() throws Exception { - PublisherProbe> fetchTokenKeys = PublisherProbe.of(Mono.just(VALID_KEYS)); - given(this.securityService.fetchTokenKeys()).willReturn(fetchTokenKeys.mono()); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{\"alg\": \"RS256\", \"kid\": \"invalid-key\",\"typ\": \"JWT\"}"; - String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .consumeErrorWith((ex) -> { - assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_KEY_ID); - }) - .verify(); - assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS); - fetchTokenKeys.assertWasSubscribed(); - } - - @Test - void validateTokenWhenCacheValidShouldNotFetchTokenKeys() throws Exception { - PublisherProbe> fetchTokenKeys = PublisherProbe.empty(); - ReflectionTestUtils.setField(this.tokenValidator, "cachedTokenKeys", VALID_KEYS); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .expectComplete() - .verify(Duration.ofSeconds(30)); - fetchTokenKeys.assertWasNotSubscribed(); - } - - @Test - void validateTokenWhenSignatureInvalidShouldThrowException() throws Exception { - Map KEYS = Collections.singletonMap("valid-key", INVALID_KEY); - given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(KEYS)); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .consumeErrorWith((ex) -> { - assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_SIGNATURE); - }) - .verify(); - } - - @Test - void validateTokenWhenTokenAlgorithmIsNotRS256ShouldThrowException() throws Exception { - given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(VALID_KEYS)); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{ \"alg\": \"HS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .consumeErrorWith((ex) -> { - assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) ex).getReason()) - .isEqualTo(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM); - }) - .verify(); - } - - @Test - void validateTokenWhenExpiredShouldThrowException() throws Exception { - given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(VALID_KEYS)); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; - String claims = "{ \"jti\": \"0236399c350c47f3ae77e67a75e75e7d\", \"exp\": 1477509977, \"scope\": [\"actuator.read\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .consumeErrorWith((ex) -> { - assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.TOKEN_EXPIRED); - }) - .verify(); - } - - @Test - void validateTokenWhenIssuerIsNotValidShouldThrowException() throws Exception { - given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(VALID_KEYS)); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("https://other-uaa.com")); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\", \"scope\": [\"actuator.read\"]}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .consumeErrorWith((ex) -> { - assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_ISSUER); - }) - .verify(); - } - - @Test - void validateTokenWhenAudienceIsNotValidShouldThrowException() throws Exception { - given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(VALID_KEYS)); - given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}"; - StepVerifier - .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .consumeErrorWith((ex) -> { - assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); - assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_AUDIENCE); - }) - .verify(); - } - - private String getSignedToken(byte[] header, byte[] claims) throws Exception { - PrivateKey privateKey = getPrivateKey(); - Signature signature = Signature.getInstance("SHA256WithRSA"); - signature.initSign(privateKey); - byte[] content = dotConcat(Base64.getUrlEncoder().encode(header), Base64.getEncoder().encode(claims)); - signature.update(content); - byte[] crypto = signature.sign(); - byte[] token = dotConcat(Base64.getUrlEncoder().encode(header), Base64.getUrlEncoder().encode(claims), - Base64.getUrlEncoder().encode(crypto)); - return new String(token, StandardCharsets.UTF_8); - } - - private PrivateKey getPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException { - String signingKey = """ - -----BEGIN PRIVATE KEY----- - MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDSbn2Xa72IOcxu - tcd+qQ6ufZ1VDe98EmpwO4VQrTd37U9kZtWU0KqeSkgnyzIWmlbyWOdbB4/v4uJa - lGjPQjt9hvd3xOOFXzpj33sWXgMGvGAzopMk64T+7GegOFlDXguA5TZyReM7M51O - ycYwpAEsKXS+lxcG0UsxpJum/WjOLyHsMnJVnoScVBlRYZ2BMyEOuap69/H3lT/X - pzlYEM6SrAifsaWvL2f1K7HKBt/yDkDOlZy6xmAMsghnslNSV0FvypTZrQOXia8t - k6fjA+iN+P0LDZAgKxzn4/B/bV8/6HN/7VZJEdudi/y5qdE7SBnx6QZqCEz/YfqC - olujacgnAgMBAAECggEAc9X2tJ/OWWrXqinOg160gkELloJxTi8lAFsDbAGuAwpT - JcWl1KF5CmGBjsY/8ElNi2J9GJL1HOwcBhikCVNARD1DhF6RkB13mvquWwWtTMvt - eP8JWM19DIc+E+hw2rCuTGngqs7l4vTqpzBTNPtS2eiIJ1IsjsgvSEiAlk/wnW48 - 11cf6SQMQcT3HNTWrS+yLycEuWKb6Khh8RpD9D+i8w2+IspWz5lTP7BrKCUNsLOx - 6+5T52HcaZ9z3wMnDqfqIKWl3h8M+q+HFQ4EN5BPWYV4fF7EOx7+Qf2fKDFPoTjC - VTWzDRNAA1xPqwdF7IdPVOXCdaUJDOhHeXZGaTNSwQKBgQDxb9UiR/Jh1R3muL7I - neIt1gXa0O+SK7NWYl4DkArYo7V81ztxI8r+xKEeu5zRZZkpaJHxOnd3VfADascw - UfALvxGxN2z42lE6zdhrmxZ3ma+akQFsv7NyXcBT00sdW+xmOiCaAj0cgxNOXiV3 - sYOwUy3SqUIPO2obpb+KC5ALHwKBgQDfH+NSQ/jn89oVZ3lzUORa+Z+aL1TGsgzs - p7IG0MTEYiR9/AExYUwJab0M4PDXhumeoACMfkCFALNVhpch2nXZv7X5445yRgfD - ONY4WknecuA0rfCLTruNWnQ3RR+BXmd9jD/5igd9hEIawz3V+jCHvAtzI8/CZIBt - AArBs5kp+QKBgQCdxwN1n6baIDemK10iJWtFoPO6h4fH8h8EeMwPb/ZmlLVpnA4Q - Zd+mlkDkoJ5eiRKKaPfWuOqRZeuvj/wTq7g/NOIO+bWQ+rrSvuqLh5IrHpgPXmub - 8bsHJhUlspMH4KagN6ROgOAG3fGj6Qp7KdpxRCpR3KJ66czxvGNrhxre6QKBgB+s - MCGiYnfSprd5G8VhyziazKwfYeJerfT+DQhopDXYVKPJnQW8cQW5C8wDNkzx6sHI - pqtK1K/MnKhcVaHJmAcT7qoNQlA4Xqu4qrgPIQNBvU/dDRNJVthG6c5aspEzrG8m - 9IHgtRV9K8EOy/1O6YqrB9kNUVWf3JccdWpvqyNJAoGAORzJiQCOk4egbdcozDTo - 4Tg4qk/03qpTy5k64DxkX1nJHu8V/hsKwq9Af7Fj/iHy2Av54BLPlBaGPwMi2bzB - gYjmUomvx/fqOTQks9Rc4PIMB43p6Rdj0sh+52SKPDR2eHbwsmpuQUXnAs20BPPI - J/OOn5zOs8yf26os0q3+JUM= - -----END PRIVATE KEY-----"""; - String privateKey = signingKey.replace("-----BEGIN PRIVATE KEY-----\n", ""); - privateKey = privateKey.replace("-----END PRIVATE KEY-----", ""); - privateKey = privateKey.replace("\n", ""); - byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(privateKey); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePrivate(keySpec); - } - - private byte[] dotConcat(byte[]... bytes) throws IOException { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - for (int i = 0; i < bytes.length; i++) { - if (i > 0) { - StreamUtils.copy(DOT, result); - } - StreamUtils.copy(bytes[i], result); - } - return result.toByteArray(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryHealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryHealthEndpointWebExtensionTests.java deleted file mode 100644 index 2b97c062de4e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryHealthEndpointWebExtensionTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.actuate.endpoint.ApiVersion; -import org.springframework.boot.actuate.health.CompositeHealth; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthComponent; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link CloudFoundryHealthEndpointWebExtension}. - * - * @author Madhura Bhave - */ -class CloudFoundryHealthEndpointWebExtensionTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withPropertyValues("VCAP_APPLICATION={}") - .withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class, - JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - RestTemplateAutoConfiguration.class, ManagementContextAutoConfiguration.class, - ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class, - WebEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class, - HealthEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class)) - .withUserConfiguration(TestHealthIndicator.class); - - @Test - void healthComponentsAlwaysPresent() { - this.contextRunner.run((context) -> { - CloudFoundryHealthEndpointWebExtension extension = context - .getBean(CloudFoundryHealthEndpointWebExtension.class); - HealthComponent body = extension.health(ApiVersion.V3).getBody(); - HealthComponent health = ((CompositeHealth) body).getComponents().entrySet().iterator().next().getValue(); - assertThat(((Health) health).getDetails()).containsEntry("spring", "boot"); - }); - } - - private static final class TestHealthIndicator implements HealthIndicator { - - @Override - public Health health() { - return Health.up().withDetail("spring", "boot").build(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptorTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptorTests.java deleted file mode 100644 index 509cec2aada0..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityInterceptorTests.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; - -import java.util.Base64; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockHttpServletRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.assertArg; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; - -/** - * Tests for {@link CloudFoundrySecurityInterceptor}. - * - * @author Madhura Bhave - */ -@ExtendWith(MockitoExtension.class) -class CloudFoundrySecurityInterceptorTests { - - @Mock - private TokenValidator tokenValidator; - - @Mock - private CloudFoundrySecurityService securityService; - - private CloudFoundrySecurityInterceptor interceptor; - - private MockHttpServletRequest request; - - @BeforeEach - void setup() { - this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, this.securityService, "my-app-id"); - this.request = new MockHttpServletRequest(); - } - - @Test - void preHandleWhenRequestIsPreFlightShouldReturnTrue() { - this.request.setMethod("OPTIONS"); - this.request.addHeader(HttpHeaders.ORIGIN, "https://example.com"); - this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); - SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); - assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); - } - - @Test - void preHandleWhenTokenIsMissingShouldReturnFalse() { - SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); - assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus()); - } - - @Test - void preHandleWhenTokenIsNotBearerShouldReturnFalse() { - this.request.addHeader("Authorization", mockAccessToken()); - SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); - assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus()); - } - - @Test - void preHandleWhenApplicationIdIsNullShouldReturnFalse() { - this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, this.securityService, null); - this.request.addHeader("Authorization", "bearer " + mockAccessToken()); - SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); - assertThat(response.getStatus()).isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus()); - } - - @Test - void preHandleWhenCloudFoundrySecurityServiceIsNullShouldReturnFalse() { - this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, null, "my-app-id"); - this.request.addHeader("Authorization", "bearer " + mockAccessToken()); - SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); - assertThat(response.getStatus()).isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus()); - } - - @Test - void preHandleWhenAccessIsNotAllowedShouldReturnFalse() { - String accessToken = mockAccessToken(); - this.request.addHeader("Authorization", "bearer " + accessToken); - given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(AccessLevel.RESTRICTED); - SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); - assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus()); - } - - @Test - void preHandleSuccessfulWithFullAccess() { - String accessToken = mockAccessToken(); - this.request.addHeader("Authorization", "Bearer " + accessToken); - given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(AccessLevel.FULL); - SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); - then(this.tokenValidator).should().validate(assertArg((token) -> assertThat(token).hasToString(accessToken))); - assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); - assertThat(this.request.getAttribute("cloudFoundryAccessLevel")).isEqualTo(AccessLevel.FULL); - } - - @Test - void preHandleSuccessfulWithRestrictedAccess() { - String accessToken = mockAccessToken(); - this.request.addHeader("Authorization", "Bearer " + accessToken); - given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(AccessLevel.RESTRICTED); - SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("info")); - then(this.tokenValidator).should().validate(assertArg((token) -> assertThat(token).hasToString(accessToken))); - assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); - assertThat(this.request.getAttribute("cloudFoundryAccessLevel")).isEqualTo(AccessLevel.RESTRICTED); - } - - private String mockAccessToken() { - return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu" - + "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ." - + Base64.getEncoder().encodeToString("signature".getBytes()); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityServiceTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityServiceTests.java deleted file mode 100644 index df23f85cd336..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundrySecurityServiceTests.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; - -import java.util.Map; -import java.util.function.Consumer; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.header; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withServerError; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withUnauthorizedRequest; - -/** - * Tests for {@link CloudFoundrySecurityService}. - * - * @author Madhura Bhave - */ -class CloudFoundrySecurityServiceTests { - - private static final String CLOUD_CONTROLLER = "https://my-cloud-controller.com"; - - private static final String CLOUD_CONTROLLER_PERMISSIONS = CLOUD_CONTROLLER + "/v2/apps/my-app-id/permissions"; - - private static final String UAA_URL = "https://my-uaa.com"; - - private CloudFoundrySecurityService securityService; - - private MockRestServiceServer server; - - @BeforeEach - void setup() { - MockServerRestTemplateCustomizer mockServerCustomizer = new MockServerRestTemplateCustomizer(); - RestTemplateBuilder builder = new RestTemplateBuilder(mockServerCustomizer); - this.securityService = new CloudFoundrySecurityService(builder, CLOUD_CONTROLLER, false); - this.server = mockServerCustomizer.getServer(); - } - - @Test - void skipSslValidationWhenTrue() { - RestTemplateBuilder builder = new RestTemplateBuilder(); - this.securityService = new CloudFoundrySecurityService(builder, CLOUD_CONTROLLER, true); - RestTemplate restTemplate = (RestTemplate) ReflectionTestUtils.getField(this.securityService, "restTemplate"); - assertThat(restTemplate.getRequestFactory()).isInstanceOf(SkipSslVerificationHttpRequestFactory.class); - } - - @Test - void doNotSkipSslValidationWhenFalse() { - RestTemplateBuilder builder = new RestTemplateBuilder(); - this.securityService = new CloudFoundrySecurityService(builder, CLOUD_CONTROLLER, false); - RestTemplate restTemplate = (RestTemplate) ReflectionTestUtils.getField(this.securityService, "restTemplate"); - assertThat(restTemplate.getRequestFactory()).isNotInstanceOf(SkipSslVerificationHttpRequestFactory.class); - } - - @Test - void getAccessLevelWhenSpaceDeveloperShouldReturnFull() { - String responseBody = "{\"read_sensitive_data\": true,\"read_basic_data\": true}"; - this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) - .andExpect(header("Authorization", "bearer my-access-token")) - .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); - AccessLevel accessLevel = this.securityService.getAccessLevel("my-access-token", "my-app-id"); - this.server.verify(); - assertThat(accessLevel).isEqualTo(AccessLevel.FULL); - } - - @Test - void getAccessLevelWhenNotSpaceDeveloperShouldReturnRestricted() { - String responseBody = "{\"read_sensitive_data\": false,\"read_basic_data\": true}"; - this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) - .andExpect(header("Authorization", "bearer my-access-token")) - .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); - AccessLevel accessLevel = this.securityService.getAccessLevel("my-access-token", "my-app-id"); - this.server.verify(); - assertThat(accessLevel).isEqualTo(AccessLevel.RESTRICTED); - } - - @Test - void getAccessLevelWhenTokenIsNotValidShouldThrowException() { - this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) - .andExpect(header("Authorization", "bearer my-access-token")) - .andRespond(withUnauthorizedRequest()); - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id")) - .satisfies(reasonRequirement(Reason.INVALID_TOKEN)); - } - - @Test - void getAccessLevelWhenForbiddenShouldThrowException() { - this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) - .andExpect(header("Authorization", "bearer my-access-token")) - .andRespond(withStatus(HttpStatus.FORBIDDEN)); - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id")) - .satisfies(reasonRequirement(Reason.ACCESS_DENIED)); - } - - @Test - void getAccessLevelWhenCloudControllerIsNotReachableThrowsException() { - this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) - .andExpect(header("Authorization", "bearer my-access-token")) - .andRespond(withServerError()); - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id")) - .satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE)); - } - - @Test - void fetchTokenKeysWhenSuccessfulShouldReturnListOfKeysFromUAA() { - this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")) - .andRespond(withSuccess("{\"token_endpoint\":\"https://my-uaa.com\"}", MediaType.APPLICATION_JSON)); - String tokenKeyValue = """ - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO - rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7 - fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB - LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO - kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo - jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI - JwIDAQAB - -----END PUBLIC KEY-----"""; - String responseBody = "{\"keys\" : [ {\"kid\":\"test-key\",\"value\" : \"" + tokenKeyValue.replace("\n", "\\n") - + "\"} ]}"; - this.server.expect(requestTo(UAA_URL + "/token_keys")) - .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); - Map tokenKeys = this.securityService.fetchTokenKeys(); - this.server.verify(); - assertThat(tokenKeys).containsEntry("test-key", tokenKeyValue); - } - - @Test - void fetchTokenKeysWhenNoKeysReturnedFromUAA() { - this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")) - .andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON)); - String responseBody = "{\"keys\": []}"; - this.server.expect(requestTo(UAA_URL + "/token_keys")) - .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); - Map tokenKeys = this.securityService.fetchTokenKeys(); - this.server.verify(); - assertThat(tokenKeys).isEmpty(); - } - - @Test - void fetchTokenKeysWhenUnsuccessfulShouldThrowException() { - this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")) - .andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON)); - this.server.expect(requestTo(UAA_URL + "/token_keys")).andRespond(withServerError()); - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy(() -> this.securityService.fetchTokenKeys()) - .satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE)); - } - - @Test - void getUaaUrlShouldCallCloudControllerInfoOnlyOnce() { - this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")) - .andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON)); - String uaaUrl = this.securityService.getUaaUrl(); - this.server.verify(); - assertThat(uaaUrl).isEqualTo(UAA_URL); - // Second call should not need to hit server - uaaUrl = this.securityService.getUaaUrl(); - assertThat(uaaUrl).isEqualTo(UAA_URL); - } - - @Test - void getUaaUrlWhenCloudControllerUrlIsNotReachableShouldThrowException() { - this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")).andRespond(withServerError()); - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy(() -> this.securityService.getUaaUrl()) - .satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE)); - } - - private Consumer reasonRequirement(Reason reason) { - return (ex) -> assertThat(ex.getReason()).isEqualTo(reason); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/TokenValidatorTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/TokenValidatorTests.java deleted file mode 100644 index ec6ef3b61a35..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/TokenValidatorTests.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.Signature; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.Base64; -import java.util.Collections; -import java.util.Map; -import java.util.function.Consumer; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.Token; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.never; - -/** - * Tests for {@link TokenValidator}. - * - * @author Madhura Bhave - */ -@ExtendWith(MockitoExtension.class) -class TokenValidatorTests { - - private static final byte[] DOT = ".".getBytes(); - - @Mock - private CloudFoundrySecurityService securityService; - - private TokenValidator tokenValidator; - - private static final String VALID_KEY = """ - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO - rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7 - fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB - LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO - kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo - jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI - JwIDAQAB - -----END PUBLIC KEY-----"""; - - private static final String INVALID_KEY = """ - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzYuc22QSst/dS7geYYK - 5l5kLxU0tayNdixkEQ17ix+CUcUbKIsnyftZxaCYT46rQtXgCaYRdJcbB3hmyrOa - vkhTpX79xJZnQmfuamMbZBqitvscxW9zRR9tBUL6vdi/0rpoUwPMEh8+Bw7CgYR0 - FK0DhWYBNDfe9HKcyZEv3max8Cdq18htxjEsdYO0iwzhtKRXomBWTdhD5ykd/fAC - VTr4+KEY+IeLvubHVmLUhbE5NgWXxrRpGasDqzKhCTmsa2Ysf712rl57SlH0Wz/M - r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s - YwIDAQAB - -----END PUBLIC KEY-----"""; - - private static final Map INVALID_KEYS = Collections.singletonMap("invalid-key", INVALID_KEY); - - private static final Map VALID_KEYS = Collections.singletonMap("valid-key", VALID_KEY); - - @BeforeEach - void setup() { - this.tokenValidator = new TokenValidator(this.securityService); - } - - @Test - void validateTokenWhenKidValidationFailsTwiceShouldThrowException() { - ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", INVALID_KEYS); - given(this.securityService.fetchTokenKeys()).willReturn(INVALID_KEYS); - String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy( - () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .satisfies(reasonRequirement(Reason.INVALID_KEY_ID)); - } - - @Test - void validateTokenWhenKidValidationSucceedsInTheSecondAttempt() throws Exception { - ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", INVALID_KEYS); - given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); - given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))); - then(this.securityService).should().fetchTokenKeys(); - } - - @Test - void validateTokenShouldFetchTokenKeysIfNull() throws Exception { - given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); - given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))); - then(this.securityService).should().fetchTokenKeys(); - } - - @Test - void validateTokenWhenValidShouldNotFetchTokenKeys() throws Exception { - ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", VALID_KEYS); - given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))); - then(this.securityService).should(never()).fetchTokenKeys(); - } - - @Test - void validateTokenWhenSignatureInvalidShouldThrowException() { - ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", - Collections.singletonMap("valid-key", INVALID_KEY)); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy( - () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .satisfies(reasonRequirement(Reason.INVALID_SIGNATURE)); - } - - @Test - void validateTokenWhenTokenAlgorithmIsNotRS256ShouldThrowException() { - String header = "{ \"alg\": \"HS256\", \"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy( - () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .satisfies(reasonRequirement(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM)); - } - - @Test - void validateTokenWhenExpiredShouldThrowException() { - given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); - given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; - String claims = "{ \"jti\": \"0236399c350c47f3ae77e67a75e75e7d\", \"exp\": 1477509977, \"scope\": [\"actuator.read\"]}"; - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy( - () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .satisfies(reasonRequirement(Reason.TOKEN_EXPIRED)); - } - - @Test - void validateTokenWhenIssuerIsNotValidShouldThrowException() { - given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); - given(this.securityService.getUaaUrl()).willReturn("https://other-uaa.com"); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\", \"scope\": [\"actuator.read\"]}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\"}"; - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy( - () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .satisfies(reasonRequirement(Reason.INVALID_ISSUER)); - } - - @Test - void validateTokenWhenAudienceIsNotValidShouldThrowException() { - given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); - given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); - String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; - String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}"; - assertThatExceptionOfType(CloudFoundryAuthorizationException.class) - .isThrownBy( - () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) - .satisfies(reasonRequirement(Reason.INVALID_AUDIENCE)); - } - - private String getSignedToken(byte[] header, byte[] claims) throws Exception { - PrivateKey privateKey = getPrivateKey(); - Signature signature = Signature.getInstance("SHA256WithRSA"); - signature.initSign(privateKey); - byte[] content = dotConcat(Base64.getUrlEncoder().encode(header), Base64.getEncoder().encode(claims)); - signature.update(content); - byte[] crypto = signature.sign(); - byte[] token = dotConcat(Base64.getUrlEncoder().encode(header), Base64.getUrlEncoder().encode(claims), - Base64.getUrlEncoder().encode(crypto)); - return new String(token, StandardCharsets.UTF_8); - } - - private PrivateKey getPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException { - String signingKey = """ - -----BEGIN PRIVATE KEY----- - MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDSbn2Xa72IOcxu - tcd+qQ6ufZ1VDe98EmpwO4VQrTd37U9kZtWU0KqeSkgnyzIWmlbyWOdbB4/v4uJa - lGjPQjt9hvd3xOOFXzpj33sWXgMGvGAzopMk64T+7GegOFlDXguA5TZyReM7M51O - ycYwpAEsKXS+lxcG0UsxpJum/WjOLyHsMnJVnoScVBlRYZ2BMyEOuap69/H3lT/X - pzlYEM6SrAifsaWvL2f1K7HKBt/yDkDOlZy6xmAMsghnslNSV0FvypTZrQOXia8t - k6fjA+iN+P0LDZAgKxzn4/B/bV8/6HN/7VZJEdudi/y5qdE7SBnx6QZqCEz/YfqC - olujacgnAgMBAAECggEAc9X2tJ/OWWrXqinOg160gkELloJxTi8lAFsDbAGuAwpT - JcWl1KF5CmGBjsY/8ElNi2J9GJL1HOwcBhikCVNARD1DhF6RkB13mvquWwWtTMvt - eP8JWM19DIc+E+hw2rCuTGngqs7l4vTqpzBTNPtS2eiIJ1IsjsgvSEiAlk/wnW48 - 11cf6SQMQcT3HNTWrS+yLycEuWKb6Khh8RpD9D+i8w2+IspWz5lTP7BrKCUNsLOx - 6+5T52HcaZ9z3wMnDqfqIKWl3h8M+q+HFQ4EN5BPWYV4fF7EOx7+Qf2fKDFPoTjC - VTWzDRNAA1xPqwdF7IdPVOXCdaUJDOhHeXZGaTNSwQKBgQDxb9UiR/Jh1R3muL7I - neIt1gXa0O+SK7NWYl4DkArYo7V81ztxI8r+xKEeu5zRZZkpaJHxOnd3VfADascw - UfALvxGxN2z42lE6zdhrmxZ3ma+akQFsv7NyXcBT00sdW+xmOiCaAj0cgxNOXiV3 - sYOwUy3SqUIPO2obpb+KC5ALHwKBgQDfH+NSQ/jn89oVZ3lzUORa+Z+aL1TGsgzs - p7IG0MTEYiR9/AExYUwJab0M4PDXhumeoACMfkCFALNVhpch2nXZv7X5445yRgfD - ONY4WknecuA0rfCLTruNWnQ3RR+BXmd9jD/5igd9hEIawz3V+jCHvAtzI8/CZIBt - AArBs5kp+QKBgQCdxwN1n6baIDemK10iJWtFoPO6h4fH8h8EeMwPb/ZmlLVpnA4Q - Zd+mlkDkoJ5eiRKKaPfWuOqRZeuvj/wTq7g/NOIO+bWQ+rrSvuqLh5IrHpgPXmub - 8bsHJhUlspMH4KagN6ROgOAG3fGj6Qp7KdpxRCpR3KJ66czxvGNrhxre6QKBgB+s - MCGiYnfSprd5G8VhyziazKwfYeJerfT+DQhopDXYVKPJnQW8cQW5C8wDNkzx6sHI - pqtK1K/MnKhcVaHJmAcT7qoNQlA4Xqu4qrgPIQNBvU/dDRNJVthG6c5aspEzrG8m - 9IHgtRV9K8EOy/1O6YqrB9kNUVWf3JccdWpvqyNJAoGAORzJiQCOk4egbdcozDTo - 4Tg4qk/03qpTy5k64DxkX1nJHu8V/hsKwq9Af7Fj/iHy2Av54BLPlBaGPwMi2bzB - gYjmUomvx/fqOTQks9Rc4PIMB43p6Rdj0sh+52SKPDR2eHbwsmpuQUXnAs20BPPI - J/OOn5zOs8yf26os0q3+JUM= - -----END PRIVATE KEY-----"""; - String privateKey = signingKey.replace("-----BEGIN PRIVATE KEY-----\n", ""); - privateKey = privateKey.replace("-----END PRIVATE KEY-----", ""); - privateKey = privateKey.replace("\n", ""); - byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(privateKey); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePrivate(keySpec); - } - - private byte[] dotConcat(byte[]... bytes) throws IOException { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - for (int i = 0; i < bytes.length; i++) { - if (i > 0) { - StreamUtils.copy(DOT, result); - } - StreamUtils.copy(bytes[i], result); - } - return result.toByteArray(); - } - - private Consumer reasonRequirement(Reason reason) { - return (ex) -> assertThat(ex.getReason()).isEqualTo(reason); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/condition/ConditionsReportEndpointTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/condition/ConditionsReportEndpointTests.java index c986622b2501..645b9ec9ccc4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/condition/ConditionsReportEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/condition/ConditionsReportEndpointTests.java @@ -19,7 +19,6 @@ import java.util.Arrays; import java.util.Collections; -import jakarta.annotation.PostConstruct; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpoint.ContextConditionsDescriptor; @@ -66,10 +65,10 @@ static class Config { Config(ConfigurableApplicationContext context) { this.context = context; + setupAutoConfigurationReport(); } - @PostConstruct - void setupAutoConfigurationReport() { + private void setupAutoConfigurationReport() { ConditionEvaluationReport report = ConditionEvaluationReport.get(this.context.getBeanFactory()); report.recordEvaluationCandidates(Arrays.asList("a", "b")); report.recordConditionEvaluation("a", mock(Condition.class), mock(ConditionOutcome.class)); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpointTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpointTests.java index fb5637614dfb..f4c0eb9e8b3c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnAvailableEndpointTests.java @@ -229,12 +229,6 @@ void outcomeWithNoEndpointReferenceShouldFail() { }); } - @Test - void outcomeOnCloudFoundryShouldMatchAll() { - this.contextRunner.withPropertyValues("VCAP_APPLICATION:---") - .run((context) -> assertThat(context).hasBean("info").hasBean("health").hasBean("spring").hasBean("test")); - } - @Test // gh-21044 void outcomeWhenIncludeAllShouldMatchDashedEndpoint() { this.contextRunner.withUserConfiguration(DashedEndpointConfiguration.class) @@ -279,21 +273,6 @@ void whenBothDefaultAccessAndDefaultEnabledAreConfiguredThenThrows() { .isInstanceOf(MutuallyExclusiveConfigurationPropertiesException.class)); } - @Test - void whenDisabledAndAccessibleByDefaultEndpointIsNotAvailable() { - this.contextRunner.withUserConfiguration(DisabledButAccessibleEndpointConfiguration.class) - .withPropertyValues("management.endpoints.web.exposure.include=*") - .run((context) -> assertThat(context).doesNotHaveBean(DisabledButAccessibleEndpoint.class)); - } - - @Test - void whenDisabledAndAccessibleByDefaultEndpointCanBeAvailable() { - this.contextRunner.withUserConfiguration(DisabledButAccessibleEndpointConfiguration.class) - .withPropertyValues("management.endpoints.web.exposure.include=*", - "management.endpoints.access.default=unrestricted") - .run((context) -> assertThat(context).hasSingleBean(DisabledButAccessibleEndpoint.class)); - } - @Test @WithTestEndpointOutcomeExposureContributor void exposureOutcomeContributorCanMakeEndpointAvailable() { @@ -331,12 +310,6 @@ static class DashedEndpoint { } - @SuppressWarnings({ "deprecation", "removal" }) - @Endpoint(id = "disabledbutaccessible", enableByDefault = false) - static class DisabledButAccessibleEndpoint { - - } - @EndpointExtension(endpoint = SpringEndpoint.class, filter = TestFilter.class) static class SpringEndpointExtension { @@ -436,15 +409,4 @@ String unexposed() { } - @Configuration(proxyBeanMethods = false) - static class DisabledButAccessibleEndpointConfiguration { - - @Bean - @ConditionalOnAvailableEndpoint - DisabledButAccessibleEndpoint disabledButAccessible() { - return new DisabledButAccessibleEndpoint(); - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointAccessIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointAccessIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointAccessIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointAccessIntegrationTests.java index f5516d3dee11..d220a977dce8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointAccessIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointAccessIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integrationtest; +package org.springframework.boot.actuate.autoconfigure.endpoint.jmx; import javax.management.MBeanOperationInfo; import javax.management.MBeanServer; @@ -23,16 +23,15 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration; import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpoint; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.util.StringUtils; @@ -47,11 +46,10 @@ class JmxEndpointAccessIntegrationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, EndpointAutoConfiguration.class, - JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class, - HttpExchangesAutoConfiguration.class)) + JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class)) .withUserConfiguration(CustomJmxEndpoint.class) .withPropertyValues("spring.jmx.enabled=true") - .withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)); + .withConfiguration(AutoConfigurations.of(BeansEndpointAutoConfiguration.class)); @Test void accessIsUnrestrictedByDefault() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointIntegrationTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointIntegrationTests.java index f3759191df5c..7ac74867d917 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integrationtest; +package org.springframework.boot.actuate.autoconfigure.endpoint.jmx; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; @@ -28,13 +28,15 @@ import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository; +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -52,18 +54,18 @@ class JmxEndpointIntegrationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, EndpointAutoConfiguration.class, - JmxEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class, - HttpExchangesAutoConfiguration.class)) + JmxEndpointAutoConfiguration.class, HealthContributorRegistryAutoConfiguration.class, + HealthContributorAutoConfiguration.class)) .withUserConfiguration(HttpExchangeRepositoryConfiguration.class, AuditEventRepositoryConfiguration.class) .withPropertyValues("spring.jmx.enabled=true") - .withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)); + .withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class, + BeansEndpointAutoConfiguration.class, ShutdownEndpointAutoConfiguration.class)); @Test void jmxEndpointsExposeHealthByDefault() { this.contextRunner.run((context) -> { MBeanServer mBeanServer = context.getBean(MBeanServer.class); - checkEndpointMBeans(mBeanServer, new String[] { "health" }, new String[] { "beans", "conditions", - "configprops", "env", "info", "mappings", "threaddump", "httpexchanges", "shutdown" }); + checkEndpointMBeans(mBeanServer, new String[] { "health" }, new String[] { "beans", "shutdown" }); }); } @@ -73,8 +75,7 @@ void jmxEndpointsAreExposedWhenLazyInitializationIsEnabled() { .withBean(LazyInitializationBeanFactoryPostProcessor.class, LazyInitializationBeanFactoryPostProcessor::new) .run((context) -> { MBeanServer mBeanServer = context.getBean(MBeanServer.class); - checkEndpointMBeans(mBeanServer, new String[] { "beans", "conditions", "configprops", "env", "health", - "info", "mappings", "threaddump", "httpexchanges" }, new String[] { "shutdown" }); + checkEndpointMBeans(mBeanServer, new String[] { "beans", "health" }, new String[] { "shutdown" }); }); } @@ -82,8 +83,7 @@ void jmxEndpointsAreExposedWhenLazyInitializationIsEnabled() { void jmxEndpointsCanBeExcluded() { this.contextRunner.withPropertyValues("management.endpoints.jmx.exposure.exclude:*").run((context) -> { MBeanServer mBeanServer = context.getBean(MBeanServer.class); - checkEndpointMBeans(mBeanServer, new String[0], new String[] { "beans", "conditions", "configprops", "env", - "health", "mappings", "shutdown", "threaddump", "httpexchanges" }); + checkEndpointMBeans(mBeanServer, new String[0], new String[] { "beans", "health", "shutdown" }); }); } @@ -92,8 +92,7 @@ void jmxEndpointsCanBeExcluded() { void singleJmxEndpointCanBeExposed() { this.contextRunner.withPropertyValues("management.endpoints.jmx.exposure.include=beans").run((context) -> { MBeanServer mBeanServer = context.getBean(MBeanServer.class); - checkEndpointMBeans(mBeanServer, new String[] { "beans" }, new String[] { "conditions", "configprops", - "env", "health", "mappings", "shutdown", "threaddump", "httpexchanges" }); + checkEndpointMBeans(mBeanServer, new String[] { "beans" }, new String[] { "health", "shutdown" }); }); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java deleted file mode 100644 index d844f6b558b1..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.endpoint.web; - -import java.util.Collections; - -import org.glassfish.jersey.server.ResourceConfig; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.endpoint.Access; -import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; -import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar; -import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.web.servlet.DispatcherServlet; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ServletEndpointManagementContextConfiguration}. - * - * @author Phillip Webb - * @author Madhura Bhave - */ -@SuppressWarnings("removal") -class ServletEndpointManagementContextConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withUserConfiguration(TestConfig.class); - - @Test - void contextShouldContainServletEndpointRegistrar() { - FilteredClassLoader classLoader = new FilteredClassLoader(ResourceConfig.class); - this.contextRunner.withClassLoader(classLoader).run((context) -> { - assertThat(context).hasSingleBean(ServletEndpointRegistrar.class); - ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class); - assertThat(bean).hasFieldOrPropertyWithValue("basePath", "/test/actuator"); - }); - } - - @Test - void contextWhenJerseyShouldContainServletEndpointRegistrar() { - FilteredClassLoader classLoader = new FilteredClassLoader(DispatcherServlet.class); - this.contextRunner.withClassLoader(classLoader).run((context) -> { - assertThat(context).hasSingleBean(ServletEndpointRegistrar.class); - ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class); - assertThat(bean).hasFieldOrPropertyWithValue("basePath", "/jersey/actuator"); - }); - } - - @Test - void contextWhenNoServletBasedShouldNotContainServletEndpointRegistrar() { - new ApplicationContextRunner().withUserConfiguration(TestConfig.class) - .run((context) -> assertThat(context).doesNotHaveBean(ServletEndpointRegistrar.class)); - } - - @Configuration(proxyBeanMethods = false) - @Import(ServletEndpointManagementContextConfiguration.class) - @EnableConfigurationProperties(WebEndpointProperties.class) - static class TestConfig { - - @Bean - ServletEndpointsSupplier servletEndpointsSupplier() { - return Collections::emptyList; - } - - @Bean - DispatcherServletPath dispatcherServletPath() { - return () -> "/test"; - } - - @Bean - JerseyApplicationPath jerseyApplicationPath() { - return () -> "/jersey"; - } - - @Bean - EndpointAccessResolver endpointAccessResolver() { - return (endpointId, defaultAccess) -> Access.UNRESTRICTED; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointsAutoConfigurationIntegrationTests.java new file mode 100644 index 000000000000..aba4576745ed --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointsAutoConfigurationIntegrationTests.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.endpoint.web; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.actuate.health.HealthEndpointWebExtension; +import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.context.annotation.UserConfigurations; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for the auto-configuration of web endpoints. + * + * @author Andy Wilkinson + */ +class WebEndpointsAutoConfigurationIntegrationTests { + + @Test + void healthEndpointWebExtensionIsAutoConfigured() { + servletWebRunner().run((context) -> context.getBean(WebEndpointTestApplication.class)); + servletWebRunner().run((context) -> assertThat(context).hasSingleBean(HealthEndpointWebExtension.class)); + } + + @Test + void healthEndpointReactiveWebExtensionIsAutoConfigured() { + reactiveWebRunner() + .run((context) -> assertThat(context).hasSingleBean(ReactiveHealthEndpointWebExtension.class)); + } + + private WebApplicationContextRunner servletWebRunner() { + return new WebApplicationContextRunner() + .withConfiguration(UserConfigurations.of(WebEndpointTestApplication.class)) + .withPropertyValues("management.defaults.metrics.export.enabled=false"); + } + + private ReactiveWebApplicationContextRunner reactiveWebRunner() { + return new ReactiveWebApplicationContextRunner() + .withConfiguration(UserConfigurations.of(WebEndpointTestApplication.class)) + .withPropertyValues("management.defaults.metrics.export.enabled=false"); + } + + @EnableAutoConfiguration + @SpringBootConfiguration + static class WebEndpointTestApplication { + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java deleted file mode 100644 index 4278dac3d8d7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey; - -import java.util.Set; - -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.model.Resource; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.DispatcherServlet; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for web endpoints running on Jersey. - * - * @author Andy Wilkinson - */ -class JerseyWebEndpointIntegrationTests { - - @Test - void whenJerseyIsConfiguredToUseAFilterThenResourceRegistrationSucceeds() { - new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration( - AutoConfigurations.of(JerseySameManagementContextConfiguration.class, JerseyAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, EndpointAutoConfiguration.class, - WebEndpointAutoConfiguration.class, JerseyWebEndpointManagementContextConfiguration.class)) - .withUserConfiguration(ResourceConfigConfiguration.class) - .withClassLoader(new FilteredClassLoader(DispatcherServlet.class)) - .withPropertyValues("spring.jersey.type=filter", "server.port=0") - .run((context) -> { - assertThat(context).hasNotFailed(); - Set resources = context.getBean(ResourceConfig.class).getResources(); - assertThat(resources).hasSize(1); - Resource resource = resources.iterator().next(); - assertThat(resource.getPath()).isEqualTo("/actuator"); - }); - } - - @Configuration(proxyBeanMethods = false) - static class ResourceConfigConfiguration { - - @Bean - ResourceConfig resourceConfig() { - return new ResourceConfig(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthContributorRegistryTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthContributorRegistryTests.java deleted file mode 100644 index daab69fe6fa0..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthContributorRegistryTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.health; - -import java.util.Arrays; -import java.util.Collections; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthContributorRegistry; - -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link AutoConfiguredHealthContributorRegistry}. - * - * @author Phillip Webb - */ -class AutoConfiguredHealthContributorRegistryTests { - - @Test - void createWhenContributorsClashesWithGroupNameThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new AutoConfiguredHealthContributorRegistry( - Collections.singletonMap("boot", mock(HealthContributor.class)), Arrays.asList("spring", "boot"))) - .withMessage("HealthContributor with name \"boot\" clashes with group"); - } - - @Test - void registerContributorWithGroupNameThrowsException() { - HealthContributorRegistry registry = new AutoConfiguredHealthContributorRegistry(Collections.emptyMap(), - Arrays.asList("spring", "boot")); - assertThatIllegalStateException() - .isThrownBy(() -> registry.registerContributor("spring", mock(HealthContributor.class))) - .withMessage("HealthContributor with name \"spring\" clashes with group"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsTests.java index 169c23fd4b44..5b3715a3356b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroupsTests.java @@ -31,10 +31,10 @@ import org.springframework.boot.actuate.health.HttpCodeStatusMapper; import org.springframework.boot.actuate.health.SimpleHttpCodeStatusMapper; import org.springframework.boot.actuate.health.SimpleStatusAggregator; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.actuate.health.StatusAggregator; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredReactiveHealthContributorRegistryTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredReactiveHealthContributorRegistryTests.java deleted file mode 100644 index 372d29e259bb..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredReactiveHealthContributorRegistryTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.health; - -import java.util.Arrays; -import java.util.Collections; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry; - -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link AutoConfiguredReactiveHealthContributorRegistry}. - * - * @author Phillip Webb - */ -class AutoConfiguredReactiveHealthContributorRegistryTests { - - @Test - void createWhenContributorsClashesWithGroupNameThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new AutoConfiguredReactiveHealthContributorRegistry( - Collections.singletonMap("boot", mock(ReactiveHealthContributor.class)), - Arrays.asList("spring", "boot"))) - .withMessage("ReactiveHealthContributor with name \"boot\" clashes with group"); - } - - @Test - void registerContributorWithGroupNameThrowsException() { - ReactiveHealthContributorRegistry registry = new AutoConfiguredReactiveHealthContributorRegistry( - Collections.emptyMap(), Arrays.asList("spring", "boot")); - assertThatIllegalStateException() - .isThrownBy(() -> registry.registerContributor("spring", mock(ReactiveHealthContributor.class))) - .withMessage("ReactiveHealthContributor with name \"spring\" clashes with group"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfigurationTests.java deleted file mode 100644 index 60288ed3592c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfigurationTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.health; - -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfigurationTests.TestHealthIndicator; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.boot.actuate.health.HealthContributor; - -/** - * Tests for {@link CompositeHealthContributorConfiguration}. - * - * @author Phillip Webb - */ -class CompositeHealthContributorConfigurationTests - extends AbstractCompositeHealthContributorConfigurationTests { - - @Override - protected AbstractCompositeHealthContributorConfiguration newComposite() { - return new TestCompositeHealthContributorConfiguration(); - } - - static class TestCompositeHealthContributorConfiguration - extends CompositeHealthContributorConfiguration { - - TestCompositeHealthContributorConfiguration() { - super(TestHealthIndicator::new); - } - - } - - static class TestHealthIndicator extends AbstractHealthIndicator { - - TestHealthIndicator(TestBean testBean) { - } - - @Override - protected void doHealthCheck(Builder builder) throws Exception { - builder.up(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfigurationTests.java deleted file mode 100644 index 8602ee9c003c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfigurationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.health; - -import reactor.core.publisher.Mono; - -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfigurationTests.TestReactiveHealthIndicator; -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; - -/** - * Tests for {@link CompositeReactiveHealthContributorConfiguration}. - * - * @author Phillip Webb - */ -class CompositeReactiveHealthContributorConfigurationTests extends - AbstractCompositeHealthContributorConfigurationTests { - - @Override - protected AbstractCompositeHealthContributorConfiguration newComposite() { - return new TestCompositeReactiveHealthContributorConfiguration(); - } - - static class TestCompositeReactiveHealthContributorConfiguration - extends CompositeReactiveHealthContributorConfiguration { - - TestCompositeReactiveHealthContributorConfiguration() { - super(TestReactiveHealthIndicator::new); - } - - } - - static class TestReactiveHealthIndicator extends AbstractReactiveHealthIndicator { - - TestReactiveHealthIndicator(TestBean testBean) { - } - - @Override - protected Mono doHealthCheck(Builder builder) { - return Mono.just(builder.up().build()); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java index 775315813372..8a678d1f494c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java @@ -24,45 +24,41 @@ import reactor.core.publisher.Mono; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.WithTestEndpointOutcomeExposureContributor; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointConfiguration.HealthEndpointGroupMembershipValidator.NoSuchHealthContributorException; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointReactiveWebExtensionConfiguration.WebFluxAdditionalHealthEndpointPathsConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointWebExtensionConfiguration.JerseyAdditionalHealthEndpointPathsConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointWebExtensionConfiguration.MvcAdditionalHealthEndpointPathsConfiguration; import org.springframework.boot.actuate.endpoint.ApiVersion; import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; -import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.DefaultHealthContributorRegistry; -import org.springframework.boot.actuate.health.DefaultReactiveHealthContributorRegistry; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthComponent; -import org.springframework.boot.actuate.health.HealthContributorRegistry; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; import org.springframework.boot.actuate.health.HealthEndpointGroupsPostProcessor; import org.springframework.boot.actuate.health.HealthEndpointWebExtension; -import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.HttpCodeStatusMapper; -import org.springframework.boot.actuate.health.NamedContributor; -import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.actuate.health.StatusAggregator; -import org.springframework.boot.actuate.health.SystemHealth; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributors; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributors; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Status; +import org.springframework.boot.health.registry.DefaultHealthContributorRegistry; +import org.springframework.boot.health.registry.DefaultReactiveHealthContributorRegistry; +import org.springframework.boot.health.registry.HealthContributorRegistry; +import org.springframework.boot.health.registry.ReactiveHealthContributorRegistry; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.DispatcherServlet; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -81,14 +77,14 @@ class HealthEndpointAutoConfigurationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withUserConfiguration(HealthIndicatorsConfiguration.class) - .withConfiguration( - AutoConfigurations.of(HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthContributorAutoConfiguration.class)); private final ReactiveWebApplicationContextRunner reactiveContextRunner = new ReactiveWebApplicationContextRunner() .withUserConfiguration(HealthIndicatorsConfiguration.class) - .withConfiguration( - AutoConfigurations.of(HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class, - WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthContributorAutoConfiguration.class, + WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)); @Test void runWhenHealthEndpointIsDisabledDoesNotCreateBeans() { @@ -96,9 +92,7 @@ void runWhenHealthEndpointIsDisabledDoesNotCreateBeans() { assertThat(context).doesNotHaveBean(StatusAggregator.class); assertThat(context).doesNotHaveBean(HttpCodeStatusMapper.class); assertThat(context).doesNotHaveBean(HealthEndpointGroups.class); - assertThat(context).doesNotHaveBean(HealthContributorRegistry.class); assertThat(context).doesNotHaveBean(HealthEndpoint.class); - assertThat(context).doesNotHaveBean(ReactiveHealthContributorRegistry.class); assertThat(context).doesNotHaveBean(HealthEndpointWebExtension.class); assertThat(context).doesNotHaveBean(ReactiveHealthEndpointWebExtension.class); }); @@ -199,7 +193,7 @@ void runWhenHasHealthEndpointGroupsBeanDoesNotCreateAdditionalHealthEndpointGrou void runCreatesHealthContributorRegistryContainingHealthBeans() { this.contextRunner.run((context) -> { HealthContributorRegistry registry = context.getBean(HealthContributorRegistry.class); - Object[] names = registry.stream().map(NamedContributor::getName).toArray(); + Object[] names = registry.stream().map(HealthContributors.Entry::name).toArray(); assertThat(names).containsExactlyInAnyOrder("simple", "additional", "ping", "reactive"); }); } @@ -209,7 +203,7 @@ void runWhenNoReactorCreatesHealthContributorRegistryContainingHealthBeans() { ClassLoader classLoader = new FilteredClassLoader(Mono.class, Flux.class); this.contextRunner.withClassLoader(classLoader).run((context) -> { HealthContributorRegistry registry = context.getBean(HealthContributorRegistry.class); - Object[] names = registry.stream().map(NamedContributor::getName).toArray(); + Object[] names = registry.stream().map(HealthContributors.Entry::name).toArray(); assertThat(names).containsExactlyInAnyOrder("simple", "additional", "ping"); }); } @@ -218,7 +212,7 @@ void runWhenNoReactorCreatesHealthContributorRegistryContainingHealthBeans() { void runWhenHasHealthContributorRegistryBeanDoesNotCreateAdditionalRegistry() { this.contextRunner.withUserConfiguration(HealthContributorRegistryConfiguration.class).run((context) -> { HealthContributorRegistry registry = context.getBean(HealthContributorRegistry.class); - Object[] names = registry.stream().map(NamedContributor::getName).toArray(); + Object[] names = registry.stream().map(HealthContributors.Entry::name).toArray(); assertThat(names).isEmpty(); }); } @@ -244,7 +238,7 @@ void runWhenHasHealthEndpointBeanDoesNotCreateAdditionalHealthEndpoint() { void runCreatesReactiveHealthContributorRegistryContainingAdaptedBeans() { this.reactiveContextRunner.run((context) -> { ReactiveHealthContributorRegistry registry = context.getBean(ReactiveHealthContributorRegistry.class); - Object[] names = registry.stream().map(NamedContributor::getName).toArray(); + Object[] names = registry.stream().map(ReactiveHealthContributors.Entry::name).toArray(); assertThat(names).containsExactlyInAnyOrder("simple", "additional", "reactive", "ping"); }); } @@ -254,7 +248,7 @@ void runWhenHasReactiveHealthContributorRegistryBeanDoesNotCreateAdditionalReact this.reactiveContextRunner.withUserConfiguration(ReactiveHealthContributorRegistryConfiguration.class) .run((context) -> { ReactiveHealthContributorRegistry registry = context.getBean(ReactiveHealthContributorRegistry.class); - Object[] names = registry.stream().map(NamedContributor::getName).toArray(); + Object[] names = registry.stream().map(ReactiveHealthContributors.Entry::name).toArray(); assertThat(names).isEmpty(); }); } @@ -263,7 +257,7 @@ void runWhenHasReactiveHealthContributorRegistryBeanDoesNotCreateAdditionalReact void runCreatesHealthEndpointWebExtension() { this.contextRunner.run((context) -> { HealthEndpointWebExtension webExtension = context.getBean(HealthEndpointWebExtension.class); - WebEndpointResponse response = webExtension.health(ApiVersion.V3, + WebEndpointResponse response = webExtension.health(ApiVersion.V3, WebServerNamespace.SERVER, SecurityContext.NONE, true, "simple"); Health health = (Health) response.getBody(); assertThat(response.getStatus()).isEqualTo(200); @@ -275,7 +269,7 @@ void runCreatesHealthEndpointWebExtension() { void runWhenHasHealthEndpointWebExtensionBeanDoesNotCreateExtraHealthEndpointWebExtension() { this.contextRunner.withUserConfiguration(HealthEndpointWebExtensionConfiguration.class).run((context) -> { HealthEndpointWebExtension webExtension = context.getBean(HealthEndpointWebExtension.class); - WebEndpointResponse response = webExtension.health(ApiVersion.V3, + WebEndpointResponse response = webExtension.health(ApiVersion.V3, WebServerNamespace.SERVER, SecurityContext.NONE, true, "simple"); assertThat(response).isNull(); }); @@ -285,7 +279,7 @@ void runWhenHasHealthEndpointWebExtensionBeanDoesNotCreateExtraHealthEndpointWeb void runCreatesReactiveHealthEndpointWebExtension() { this.reactiveContextRunner.run((context) -> { ReactiveHealthEndpointWebExtension webExtension = context.getBean(ReactiveHealthEndpointWebExtension.class); - Mono> response = webExtension.health(ApiVersion.V3, + Mono> response = webExtension.health(ApiVersion.V3, WebServerNamespace.SERVER, SecurityContext.NONE, true, "simple"); Health health = (Health) (response.block().getBody()); assertThat(health.getDetails()).containsEntry("counter", 42); @@ -298,7 +292,7 @@ void runWhenHasReactiveHealthEndpointWebExtensionBeanDoesNotCreateExtraReactiveH .run((context) -> { ReactiveHealthEndpointWebExtension webExtension = context .getBean(ReactiveHealthEndpointWebExtension.class); - Mono> response = webExtension.health(ApiVersion.V3, + Mono> response = webExtension.health(ApiVersion.V3, WebServerNamespace.SERVER, SecurityContext.NONE, true, "simple"); assertThat(response).isNull(); }); @@ -319,12 +313,12 @@ void runWhenHasHealthEndpointGroupsPostProcessorPerformsProcessing() { void runWithIndicatorsInParentContextFindsIndicators() { new ApplicationContextRunner().withUserConfiguration(HealthIndicatorsConfiguration.class) .run((parent) -> new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, - HealthEndpointAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthContributorAutoConfiguration.class)) .withParent(parent) .run((context) -> { - HealthComponent health = context.getBean(HealthEndpoint.class).health(); - Map components = ((SystemHealth) health).getComponents(); + ContributedHealth health = context.getBean(HealthEndpoint.class).health(); + Map components = ((CompositeHealth) health).getComponents(); assertThat(components).containsKeys("additional", "ping", "simple"); })); } @@ -333,68 +327,22 @@ void runWithIndicatorsInParentContextFindsIndicators() { void runWithReactiveContextAndIndicatorsInParentContextFindsIndicators() { new ApplicationContextRunner().withUserConfiguration(HealthIndicatorsConfiguration.class) .run((parent) -> new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, - HealthEndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - EndpointAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthContributorAutoConfiguration.class, + WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)) .withParent(parent) .run((context) -> { - HealthComponent health = context.getBean(HealthEndpoint.class).health(); - Map components = ((SystemHealth) health).getComponents(); + ContributedHealth health = context.getBean(HealthEndpoint.class).health(); + Map components = ((CompositeHealth) health).getComponents(); assertThat(components).containsKeys("additional", "ping", "simple"); })); } @Test - @WithTestEndpointOutcomeExposureContributor - void additionalHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() { - this.contextRunner - .withConfiguration(AutoConfigurations.of(DispatcherServletAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)) - .withPropertyValues("management.endpoints.web.exposure.exclude=*", - "management.endpoints.test.exposure.include=*") - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context).hasSingleBean(HealthEndpoint.class); - assertThat(context).hasSingleBean(HealthEndpointWebExtension.class); - assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty(); - assertThat(context).hasSingleBean(MvcAdditionalHealthEndpointPathsConfiguration.class); - }); - } - - @Test - @WithTestEndpointOutcomeExposureContributor - void additionalJerseyHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)) - .withClassLoader( - new FilteredClassLoader(Thread.currentThread().getContextClassLoader(), DispatcherServlet.class)) - .withPropertyValues("management.endpoints.web.exposure.exclude=*", - "management.endpoints.test.exposure.include=*") - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context).hasSingleBean(HealthEndpoint.class); - assertThat(context).hasSingleBean(HealthEndpointWebExtension.class); - assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty(); - assertThat(context).hasSingleBean(JerseyAdditionalHealthEndpointPathsConfiguration.class); - }); - } - - @Test - @WithTestEndpointOutcomeExposureContributor - void additionalReactiveHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() { - this.reactiveContextRunner - .withConfiguration( - AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)) - .withPropertyValues("management.endpoints.web.exposure.exclude=*", - "management.endpoints.test.exposure.include=*") - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context).hasSingleBean(HealthEndpoint.class); - assertThat(context).hasSingleBean(ReactiveHealthEndpointWebExtension.class); - assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty(); - assertThat(context).hasSingleBean(WebFluxAdditionalHealthEndpointPathsConfiguration.class); - }); + void runWithClashingGroupNameThrowsException() { + this.contextRunner.withPropertyValues("management.endpoint.health.group.ping.include=*") + .run((context) -> assertThat(context).getFailure() + .hasMessageContaining("HealthContributor with name \"ping\" clashes with group")); } @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/NoSuchHealthContributorFailureAnalyzerTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/NoSuchHealthContributorFailureAnalyzerTests.java index 692c7c85a309..05e55c0a18d3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/NoSuchHealthContributorFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/NoSuchHealthContributorFailureAnalyzerTests.java @@ -23,6 +23,7 @@ import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointConfiguration.HealthEndpointGroupMembershipValidator.NoSuchHealthContributorException; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.diagnostics.FailureAnalysis; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -34,8 +35,8 @@ */ class NoSuchHealthContributorFailureAnalyzerTests { - private final ApplicationContextRunner runner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class)); + private final ApplicationContextRunner runner = new ApplicationContextRunner().withConfiguration(AutoConfigurations + .of(HealthEndpointAutoConfiguration.class, HealthContributorRegistryAutoConfiguration.class)); @Test void analyzesMissingRequiredConfiguration() throws Throwable { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java index 2192293d86ef..5ec5129364f4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfigurationTests.java @@ -16,13 +16,11 @@ package org.springframework.boot.actuate.autoconfigure.info; -import java.time.Duration; import java.util.Map; import java.util.Properties; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.ssl.SslHealthIndicatorProperties; import org.springframework.boot.actuate.info.BuildInfoContributor; import org.springframework.boot.actuate.info.EnvironmentInfoContributor; import org.springframework.boot.actuate.info.GitInfoContributor; @@ -197,24 +195,6 @@ void sslInfoContributor() { }); } - @Test - void sslInfoContributorWithWarningThreshold() { - this.contextRunner.withConfiguration(AutoConfigurations.of(SslAutoConfiguration.class)) - .withPropertyValues("management.info.ssl.enabled=true", "server.ssl.bundle=ssltest", - "spring.ssl.bundle.jks.ssltest.keystore.location=classpath:test.jks", - "management.health.ssl.certificate-validity-warning-threshold=1d") - .run((context) -> { - assertThat(context).hasSingleBean(SslInfoContributor.class); - assertThat(context).hasSingleBean(SslInfo.class); - assertThat(context).hasSingleBean(SslHealthIndicatorProperties.class); - assertThat(context.getBean(SslHealthIndicatorProperties.class).getCertificateValidityWarningThreshold()) - .isEqualTo(Duration.ofDays(1)); - Map content = invokeContributor(context.getBean(SslInfoContributor.class)); - assertThat(content).containsKey("ssl"); - assertThat(content.get("ssl")).isInstanceOf(SslInfo.class); - }); - } - @Test void customSslInfo() { this.contextRunner.withUserConfiguration(CustomSslInfoConfiguration.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/ControllerEndpointWebFluxIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/ControllerEndpointWebFluxIntegrationTests.java deleted file mode 100644 index 44afc4144316..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/ControllerEndpointWebFluxIntegrationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; -import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext; -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.test.context.TestSecurityContextHolder; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.bind.annotation.GetMapping; - -/** - * Integration tests for the Actuator's WebFlux {@link ControllerEndpoint controller - * endpoints}. - * - * @author Phillip Webb - */ -@SuppressWarnings("removal") -class ControllerEndpointWebFluxIntegrationTests { - - private AnnotationConfigReactiveWebApplicationContext context; - - @AfterEach - void close() { - TestSecurityContextHolder.clearContext(); - this.context.close(); - } - - @Test - void endpointsCanBeAccessed() { - TestSecurityContextHolder.getContext() - .setAuthentication(new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR")); - this.context = new AnnotationConfigReactiveWebApplicationContext(); - this.context.register(DefaultConfiguration.class, ExampleController.class); - TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context); - this.context.refresh(); - WebTestClient webClient = WebTestClient.bindToApplicationContext(this.context).build(); - webClient.get().uri("/actuator/example").exchange().expectStatus().isOk(); - } - - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ReactiveManagementContextAutoConfiguration.class, AuditAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, WebFluxAutoConfiguration.class, - ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class }) - static class DefaultConfiguration { - - } - - @RestControllerEndpoint(id = "example") - static class ExampleController { - - @GetMapping("/") - String example() { - return "Example"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/ControllerEndpointWebMvcIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/ControllerEndpointWebMvcIntegrationTests.java deleted file mode 100644 index ce9640e61d3a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/ControllerEndpointWebMvcIntegrationTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockServletContext; -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.test.context.TestSecurityContextHolder; -import org.springframework.test.web.servlet.assertj.MockMvcTester; -import org.springframework.test.web.servlet.setup.MockMvcConfigurer; -import org.springframework.web.bind.annotation.GetMapping; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; - -/** - * Integration tests for the Actuator's MVC - * {@link org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint - * controller endpoints}. - * - * @author Phillip Webb - * @author Andy Wilkinson - */ -class ControllerEndpointWebMvcIntegrationTests { - - private AnnotationConfigServletWebApplicationContext context; - - @AfterEach - void close() { - TestSecurityContextHolder.clearContext(); - this.context.close(); - } - - @Test - void endpointsAreSecureByDefault() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(SecureConfiguration.class, ExampleController.class); - MockMvcTester mvc = createSecureMockMvcTester(); - assertThat(mvc.get().uri("/actuator/example").accept(MediaType.APPLICATION_JSON)) - .hasStatus(HttpStatus.UNAUTHORIZED); - } - - @Test - void endpointsCanBeAccessed() { - TestSecurityContextHolder.getContext() - .setAuthentication(new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR")); - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(SecureConfiguration.class, ExampleController.class); - TestPropertyValues - .of("management.endpoints.web.base-path:/management", "management.endpoints.web.exposure.include=*") - .applyTo(this.context); - MockMvcTester mvc = createSecureMockMvcTester(); - assertThat(mvc.get().uri("/management/example")).hasStatusOk(); - } - - private MockMvcTester createSecureMockMvcTester() { - return doCreateMockMvcTester(springSecurity()); - } - - private MockMvcTester doCreateMockMvcTester(MockMvcConfigurer... configurers) { - this.context.setServletContext(new MockServletContext()); - this.context.refresh(); - return MockMvcTester.from(this.context, (builder) -> { - for (MockMvcConfigurer configurer : configurers) { - builder.apply(configurer); - } - return builder.build(); - }); - } - - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ServletManagementContextAutoConfiguration.class, AuditAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class, - ManagementContextAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - BeansEndpointAutoConfiguration.class }) - static class DefaultConfiguration { - - } - - @Import(DefaultConfiguration.class) - @ImportAutoConfiguration({ SecurityAutoConfiguration.class }) - static class SecureConfiguration { - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "example") - @SuppressWarnings("removal") - static class ExampleController { - - @GetMapping("/") - String example() { - return "Example"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/EndpointAutoConfigurationClasses.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/EndpointAutoConfigurationClasses.java deleted file mode 100644 index 716c3ab7de3f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/EndpointAutoConfigurationClasses.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.boot.actuate.autoconfigure.audit.AuditEventsEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.context.properties.ConfigurationPropertiesReportEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.management.ThreadDumpEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration; -import org.springframework.util.ClassUtils; - -/** - * A list of all endpoint auto-configuration classes for use in tests. - */ -final class EndpointAutoConfigurationClasses { - - static final Class[] ALL; - - static { - List> all = new ArrayList<>(); - all.add(AuditEventsEndpointAutoConfiguration.class); - all.add(BeansEndpointAutoConfiguration.class); - all.add(ConditionsReportEndpointAutoConfiguration.class); - all.add(ConfigurationPropertiesReportEndpointAutoConfiguration.class); - all.add(ShutdownEndpointAutoConfiguration.class); - all.add(EnvironmentEndpointAutoConfiguration.class); - all.add(HealthEndpointAutoConfiguration.class); - all.add(InfoEndpointAutoConfiguration.class); - all.add(ThreadDumpEndpointAutoConfiguration.class); - all.add(HttpExchangesEndpointAutoConfiguration.class); - all.add(MappingsEndpointAutoConfiguration.class); - ALL = ClassUtils.toClassArray(all); - } - - private EndpointAutoConfigurationClasses() { - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/EndpointObjectMapperConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/EndpointObjectMapperConfiguration.java deleted file mode 100644 index c56810311e40..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/EndpointObjectMapperConfiguration.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.jsontype.TypeSerializer; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; - -import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; - -/** - * {@link Configuration @Configuration} that creates an {@link EndpointObjectMapper} that - * reverses all strings. - * - * @author Phillip Webb - */ -@Configuration -@SuppressWarnings("removal") -class EndpointObjectMapperConfiguration { - - @Bean - EndpointObjectMapper endpointObjectMapper() { - SimpleModule module = new SimpleModule(); - module.addSerializer(String.class, new ReverseStringSerializer()); - ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(module).build(); - return () -> objectMapper; - } - - static class ReverseStringSerializer extends StdScalarSerializer { - - ReverseStringSerializer() { - super(String.class, false); - } - - @Override - public boolean isEmpty(SerializerProvider prov, Object value) { - return ((String) value).isEmpty(); - } - - @Override - public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException { - serialize(value, gen); - } - - @Override - public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, - TypeSerializer typeSer) throws IOException { - serialize(value, gen); - } - - private void serialize(Object value, JsonGenerator gen) throws IOException { - StringBuilder builder = new StringBuilder((String) value); - gen.writeString(builder.reverse().toString()); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyEndpointIntegrationTests.java deleted file mode 100644 index 9c07f76cca0e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyEndpointIntegrationTests.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.glassfish.jersey.server.ResourceConfig; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.servlet.DispatcherServlet; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for the Jersey actuator endpoints. - * - * @author Andy Wilkinson - * @author Madhura Bhave - */ -class JerseyEndpointIntegrationTests { - - @Test - void linksAreProvidedToAllEndpointTypes() { - testJerseyEndpoints(new Class[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class }); - } - - @Test - void linksPageIsNotAvailableWhenDisabled() { - getContextRunner(new Class[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class }) - .withPropertyValues("management.endpoints.web.discovery.enabled:false") - .run((context) -> { - int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) - .getWebServer() - .getPort(); - WebTestClient client = WebTestClient.bindToServer() - .baseUrl("http://localhost:" + port) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - client.get().uri("/actuator").exchange().expectStatus().isNotFound(); - }); - } - - @Test - void actuatorEndpointsWhenUserProvidedResourceConfigBeanNotAvailable() { - testJerseyEndpoints(new Class[] { EndpointsConfiguration.class }); - } - - @Test - void actuatorEndpointsWhenSecurityAvailable() { - WebApplicationContextRunner contextRunner = getContextRunner( - new Class[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class }, - getAutoconfigurations(SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class)); - contextRunner.run((context) -> { - int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) - .getWebServer() - .getPort(); - WebTestClient client = WebTestClient.bindToServer() - .baseUrl("http://localhost:" + port) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - client.get().uri("/actuator").exchange().expectStatus().isUnauthorized(); - }); - } - - @Test - void endpointObjectMapperCanBeApplied() { - WebApplicationContextRunner contextRunner = getContextRunner(new Class[] { EndpointsConfiguration.class, - ResourceConfigConfiguration.class, EndpointObjectMapperConfiguration.class }); - contextRunner.run((context) -> { - int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) - .getWebServer() - .getPort(); - WebTestClient client = WebTestClient.bindToServer() - .baseUrl("http://localhost:" + port) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - client.get().uri("/actuator/beans").exchange().expectStatus().isOk().expectBody().consumeWith((result) -> { - String json = new String(result.getResponseBody(), StandardCharsets.UTF_8); - assertThat(json).contains("\"scope\":\"notelgnis\""); - }); - }); - } - - protected void testJerseyEndpoints(Class[] userConfigurations) { - getContextRunner(userConfigurations).run((context) -> { - int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) - .getWebServer() - .getPort(); - WebTestClient client = WebTestClient.bindToServer() - .baseUrl("http://localhost:" + port) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - client.get() - .uri("/actuator") - .exchange() - .expectStatus() - .isOk() - .expectBody() - .jsonPath("_links.beans") - .isNotEmpty() - .jsonPath("_links.restcontroller") - .doesNotExist() - .jsonPath("_links.controller") - .doesNotExist(); - }); - } - - WebApplicationContextRunner getContextRunner(Class[] userConfigurations, - Class... additionalAutoConfigurations) { - FilteredClassLoader classLoader = new FilteredClassLoader(DispatcherServlet.class); - return new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(classLoader) - .withConfiguration(AutoConfigurations.of(getAutoconfigurations(additionalAutoConfigurations))) - .withUserConfiguration(userConfigurations) - .withPropertyValues("management.endpoints.web.exposure.include:*", "server.port:0"); - } - - private Class[] getAutoconfigurations(Class... additional) { - List> autoconfigurations = new ArrayList<>(Arrays.asList(JacksonAutoConfiguration.class, - JerseyAutoConfiguration.class, EndpointAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)); - autoconfigurations.addAll(Arrays.asList(additional)); - return autoconfigurations.toArray(new Class[0]); - } - - @org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint(id = "controller") - @SuppressWarnings("removal") - static class TestControllerEndpoint { - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "restcontroller") - @SuppressWarnings("removal") - static class TestRestControllerEndpoint { - - } - - @Configuration(proxyBeanMethods = false) - static class EndpointsConfiguration { - - @Bean - TestControllerEndpoint testControllerEndpoint() { - return new TestControllerEndpoint(); - } - - @Bean - TestRestControllerEndpoint testRestControllerEndpoint() { - return new TestRestControllerEndpoint(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ResourceConfigConfiguration { - - @Bean - ResourceConfig testResourceConfig() { - return new ResourceConfig(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyHealthEndpointAdditionalPathIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyHealthEndpointAdditionalPathIntegrationTests.java deleted file mode 100644 index 110f1221cb17..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyHealthEndpointAdditionalPathIntegrationTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.web.context.ConfigurableWebApplicationContext; -import org.springframework.web.servlet.DispatcherServlet; - -/** - * Integration tests for health groups on an additional path on Jersey. - * - * @author Madhura Bhave - */ -class JerseyHealthEndpointAdditionalPathIntegrationTests extends - AbstractHealthEndpointAdditionalPathIntegrationTests { - - JerseyHealthEndpointAdditionalPathIntegrationTests() { - super(new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, - EndpointAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class, - WebEndpointAutoConfiguration.class, JerseyAutoConfiguration.class, - ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - HealthEndpointAutoConfiguration.class, DiskSpaceHealthContributorAutoConfiguration.class)) - .withInitializer(new ServerPortInfoApplicationContextInitializer()) - .withClassLoader(new FilteredClassLoader(DispatcherServlet.class)) - .withPropertyValues("server.port=0")); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java deleted file mode 100644 index a8494655effe..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration; -import org.springframework.boot.actuate.health.HealthEndpointWebExtension; -import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; -import org.springframework.boot.context.annotation.UserConfigurations; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for the auto-configuration of web endpoints. - * - * @author Andy Wilkinson - */ -class WebEndpointsAutoConfigurationIntegrationTests { - - @Test - void healthEndpointWebExtensionIsAutoConfigured() { - servletWebRunner().run((context) -> context.getBean(WebEndpointTestApplication.class)); - servletWebRunner().run((context) -> assertThat(context).hasSingleBean(HealthEndpointWebExtension.class)); - } - - @Test - @ClassPathExclusions({ "spring-security-oauth2-client-*.jar", "spring-security-oauth2-resource-server-*.jar" }) - void healthEndpointReactiveWebExtensionIsAutoConfigured() { - reactiveWebRunner() - .run((context) -> assertThat(context).hasSingleBean(ReactiveHealthEndpointWebExtension.class)); - } - - private WebApplicationContextRunner servletWebRunner() { - return new WebApplicationContextRunner() - .withConfiguration(UserConfigurations.of(WebEndpointTestApplication.class)) - .withPropertyValues("management.tracing.enabled=false", "management.defaults.metrics.export.enabled=false"); - } - - private ReactiveWebApplicationContextRunner reactiveWebRunner() { - return new ReactiveWebApplicationContextRunner() - .withConfiguration(UserConfigurations.of(WebEndpointTestApplication.class)) - .withPropertyValues("management.tracing.enabled=false", "management.defaults.metrics.export.enabled=false"); - } - - @EnableAutoConfiguration(exclude = { FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class, - CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class, Neo4jDataAutoConfiguration.class, - Neo4jRepositoriesAutoConfiguration.class, MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, - MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, - RepositoryRestMvcAutoConfiguration.class, HazelcastAutoConfiguration.class, - ElasticsearchDataAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, BraveAutoConfiguration.class, - OpenTelemetryTracingAutoConfiguration.class }) - @SpringBootConfiguration - static class WebEndpointTestApplication { - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointIntegrationTests.java deleted file mode 100644 index 17177fead8e7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointIntegrationTests.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import java.nio.charset.StandardCharsets; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.web.reactive.server.WebTestClient; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for the WebFlux actuator endpoints. - * - * @author Andy Wilkinson - */ -class WebFluxEndpointIntegrationTests { - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, CodecsAutoConfiguration.class, - WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class, EndpointAutoConfiguration.class, - WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class, - ReactiveManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)) - .withUserConfiguration(EndpointsConfiguration.class); - - @Test - void linksAreProvidedToAllEndpointTypes() { - this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include:*").run((context) -> { - WebTestClient client = createWebTestClient(context); - client.get() - .uri("/actuator") - .exchange() - .expectStatus() - .isOk() - .expectBody() - .jsonPath("_links.beans") - .isNotEmpty() - .jsonPath("_links.restcontroller") - .isNotEmpty() - .jsonPath("_links.controller") - .isNotEmpty(); - }); - } - - @Test - void linksPageIsNotAvailableWhenDisabled() { - this.contextRunner.withPropertyValues("management.endpoints.web.discovery.enabled=false").run((context) -> { - WebTestClient client = createWebTestClient(context); - client.get().uri("/actuator").exchange().expectStatus().isNotFound(); - }); - } - - @Test - void endpointObjectMapperCanBeApplied() { - this.contextRunner.withUserConfiguration(EndpointObjectMapperConfiguration.class) - .withPropertyValues("management.endpoints.web.exposure.include:*") - .run((context) -> { - WebTestClient client = createWebTestClient(context); - client.get() - .uri("/actuator/beans") - .exchange() - .expectStatus() - .isOk() - .expectBody() - .consumeWith((result) -> { - String json = new String(result.getResponseBody(), StandardCharsets.UTF_8); - assertThat(json).contains("\"scope\":\"notelgnis\""); - }); - }); - } - - private WebTestClient createWebTestClient(ApplicationContext context) { - return WebTestClient.bindToApplicationContext(context) - .configureClient() - .baseUrl("https://spring.example.org") - .build(); - } - - @org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint(id = "controller") - @SuppressWarnings("removal") - static class TestControllerEndpoint { - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "restcontroller") - @SuppressWarnings("removal") - static class TestRestControllerEndpoint { - - } - - @Configuration(proxyBeanMethods = false) - static class EndpointsConfiguration { - - @Bean - TestControllerEndpoint testControllerEndpoint() { - return new TestControllerEndpoint(); - } - - @Bean - TestRestControllerEndpoint testRestControllerEndpoint() { - return new TestRestControllerEndpoint(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxHealthEndpointAdditionalPathIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxHealthEndpointAdditionalPathIntegrationTests.java deleted file mode 100644 index 503641482b2f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxHealthEndpointAdditionalPathIntegrationTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext; - -/** - * Integration tests for Webflux health groups on an additional path. - * - * @author Madhura Bhave - */ -class WebFluxHealthEndpointAdditionalPathIntegrationTests extends - AbstractHealthEndpointAdditionalPathIntegrationTests { - - WebFluxHealthEndpointAdditionalPathIntegrationTests() { - super(new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, CodecsAutoConfiguration.class, - WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class, EndpointAutoConfiguration.class, - HealthEndpointAutoConfiguration.class, DiskSpaceHealthContributorAutoConfiguration.class, - WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class, - ReactiveWebServerFactoryAutoConfiguration.class, ReactiveManagementContextAutoConfiguration.class, - BeansEndpointAutoConfiguration.class)) - .withInitializer(new ServerPortInfoApplicationContextInitializer()) - .withPropertyValues("server.port=0")); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointAccessIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointAccessIntegrationTests.java deleted file mode 100644 index e28450c1e2a1..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointAccessIntegrationTests.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import java.io.IOException; -import java.time.Duration; -import java.util.function.Supplier; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.test.web.reactive.server.EntityExchangeResult; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.reactive.function.client.ExchangeStrategies; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for controlling access to endpoints exposed by Spring MVC. - * - * @author Andy Wilkinson - */ -class WebMvcEndpointAccessIntegrationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, JacksonAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - HealthContributorAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)) - .withUserConfiguration(CustomMvcEndpoint.class, CustomServletEndpoint.class) - .withPropertyValues("server.port:0"); - - @Test - void accessIsUnrestrictedByDefault() { - this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*").run((context) -> { - WebTestClient client = createClient(context); - assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue(); - assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue(); - assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isTrue(); - assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue(); - assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isTrue(); - }); - } - - @Test - void accessCanBeReadOnlyByDefault() { - this.contextRunner - .withPropertyValues("management.endpoints.web.exposure.include=*", - "management.endpoints.access.default=READ_ONLY") - .run((context) -> { - WebTestClient client = createClient(context); - assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue(); - assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue(); - assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); - assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue(); - assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse(); - }); - } - - @Test - void accessCanBeNoneByDefault() { - this.contextRunner - .withPropertyValues("management.endpoints.web.exposure.include=*", - "management.endpoints.access.default=NONE") - .run((context) -> { - WebTestClient client = createClient(context); - assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse(); - assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isFalse(); - assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); - assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isFalse(); - assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse(); - }); - } - - @Test - void accessForOneEndpointCanOverrideTheDefaultAccess() { - this.contextRunner - .withPropertyValues("management.endpoints.web.exposure.include=*", - "management.endpoints.access.default=READ_ONLY", - "management.endpoint.customservlet.access=UNRESTRICTED") - .run((context) -> { - WebTestClient client = createClient(context); - assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue(); - assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue(); - assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); - assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue(); - assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isTrue(); - }); - } - - @Test - void accessCanBeCappedAtReadOnly() { - this.contextRunner - .withPropertyValues("management.endpoints.web.exposure.include=*", - "management.endpoints.access.default=UNRESTRICTED", - "management.endpoints.access.max-permitted=READ_ONLY") - .run((context) -> { - WebTestClient client = createClient(context); - assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue(); - assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue(); - assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); - assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue(); - assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse(); - }); - } - - @Test - void accessCanBeCappedAtNone() { - this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*", - "management.endpoints.access.default=UNRESTRICTED", "management.endpoints.access.max-permitted=NONE") - .run((context) -> { - WebTestClient client = createClient(context); - assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse(); - assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isFalse(); - assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); - assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isFalse(); - assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse(); - }); - } - - private WebTestClient createClient(AssertableWebApplicationContext context) { - int port = context.getSourceApplicationContext(ServletWebServerApplicationContext.class) - .getWebServer() - .getPort(); - ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() - .codecs((configurer) -> configurer.defaultCodecs().maxInMemorySize(-1)) - .build(); - return WebTestClient.bindToServer() - .baseUrl("http://localhost:" + port) - .exchangeStrategies(exchangeStrategies) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - } - - private boolean isAccessible(WebTestClient client, HttpMethod method, String path) { - path = "/actuator/" + path; - EntityExchangeResult result = client.method(method).uri(path).exchange().expectBody().returnResult(); - if (result.getStatus() == HttpStatus.OK) { - return true; - } - if (result.getStatus() == HttpStatus.NOT_FOUND || result.getStatus() == HttpStatus.METHOD_NOT_ALLOWED) { - return false; - } - throw new IllegalStateException( - String.format("Unexpected %s HTTP status for endpoint %s", result.getStatus(), path)); - } - - @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "custommvc") - @SuppressWarnings("removal") - static class CustomMvcEndpoint { - - @GetMapping("/") - String get() { - return "get"; - } - - @PostMapping("/") - String post() { - return "post"; - } - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "customservlet") - @SuppressWarnings({ "deprecation", "removal" }) - static class CustomServletEndpoint - implements Supplier { - - @Override - public org.springframework.boot.actuate.endpoint.web.EndpointServlet get() { - return new org.springframework.boot.actuate.endpoint.web.EndpointServlet(new HttpServlet() { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - } - - }); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointExposureIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointExposureIntegrationTests.java deleted file mode 100644 index 9db75d591439..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointExposureIntegrationTests.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import java.io.IOException; -import java.time.Duration; -import java.util.function.Supplier; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.test.web.reactive.server.EntityExchangeResult; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.reactive.function.client.ExchangeStrategies; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for Endpoints over Spring MVC. - * - * @author Stephane Nicoll - * @author Phillip Webb - */ -class WebMvcEndpointExposureIntegrationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, JacksonAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - HttpExchangesAutoConfiguration.class, HealthContributorAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)) - .withUserConfiguration(CustomMvcEndpoint.class, CustomServletEndpoint.class, - HttpExchangeRepositoryConfiguration.class, AuditEventRepositoryConfiguration.class) - .withPropertyValues("server.port:0"); - - @Test - void webEndpointsAreDisabledByDefault() { - this.contextRunner.run((context) -> { - WebTestClient client = createClient(context); - assertThat(isExposed(client, HttpMethod.GET, "beans")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "conditions")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "configprops")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "custommvc")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "customservlet")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "env")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "info")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "mappings")).isFalse(); - assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "threaddump")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "httpexchanges")).isFalse(); - }); - } - - @Test - void webEndpointsCanBeExposed() { - WebApplicationContextRunner contextRunner = this.contextRunner - .withPropertyValues("management.endpoints.web.exposure.include=*"); - contextRunner.run((context) -> { - WebTestClient client = createClient(context); - assertThat(isExposed(client, HttpMethod.GET, "beans")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "conditions")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "configprops")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "custommvc")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "customservlet")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "env")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "info")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "mappings")).isTrue(); - assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "threaddump")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "httpexchanges")).isTrue(); - }); - } - - @Test - void singleWebEndpointCanBeExposed() { - WebApplicationContextRunner contextRunner = this.contextRunner - .withPropertyValues("management.endpoints.web.exposure.include=beans"); - contextRunner.run((context) -> { - WebTestClient client = createClient(context); - assertThat(isExposed(client, HttpMethod.GET, "beans")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "conditions")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "configprops")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "custommvc")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "customservlet")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "env")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "health")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "info")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "mappings")).isFalse(); - assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "threaddump")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "httpexchanges")).isFalse(); - }); - } - - @Test - void singleWebEndpointCanBeExcluded() { - WebApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues( - "management.endpoints.web.exposure.include=*", "management.endpoints.web.exposure.exclude=shutdown"); - contextRunner.run((context) -> { - WebTestClient client = createClient(context); - assertThat(isExposed(client, HttpMethod.GET, "beans")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "conditions")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "configprops")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "custommvc")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "customservlet")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "env")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "info")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "mappings")).isTrue(); - assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse(); - assertThat(isExposed(client, HttpMethod.GET, "threaddump")).isTrue(); - assertThat(isExposed(client, HttpMethod.GET, "httpexchanges")).isTrue(); - }); - } - - private WebTestClient createClient(AssertableWebApplicationContext context) { - int port = context.getSourceApplicationContext(ServletWebServerApplicationContext.class) - .getWebServer() - .getPort(); - ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() - .codecs((configurer) -> configurer.defaultCodecs().maxInMemorySize(-1)) - .build(); - return WebTestClient.bindToServer() - .baseUrl("http://localhost:" + port) - .exchangeStrategies(exchangeStrategies) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - } - - private boolean isExposed(WebTestClient client, HttpMethod method, String path) { - path = "/actuator/" + path; - EntityExchangeResult result = client.method(method).uri(path).exchange().expectBody().returnResult(); - if (result.getStatus() == HttpStatus.OK) { - return true; - } - if (result.getStatus() == HttpStatus.NOT_FOUND) { - return false; - } - throw new IllegalStateException( - String.format("Unexpected %s HTTP status for endpoint %s", result.getStatus(), path)); - } - - @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "custommvc") - @SuppressWarnings("removal") - static class CustomMvcEndpoint { - - @GetMapping("/") - String main() { - return "test"; - } - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "customservlet") - @SuppressWarnings({ "deprecation", "removal" }) - static class CustomServletEndpoint - implements Supplier { - - @Override - public org.springframework.boot.actuate.endpoint.web.EndpointServlet get() { - return new org.springframework.boot.actuate.endpoint.web.EndpointServlet(new HttpServlet() { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - } - - }); - } - - } - - @Configuration(proxyBeanMethods = false) - static class HttpExchangeRepositoryConfiguration { - - @Bean - InMemoryHttpExchangeRepository httpExchangeRepository() { - return new InMemoryHttpExchangeRepository(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class AuditEventRepositoryConfiguration { - - @Bean - InMemoryAuditEventRepository auditEventRepository() { - return new InMemoryAuditEventRepository(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointIntegrationTests.java deleted file mode 100644 index b8d7beb6817c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointIntegrationTests.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import java.util.function.Supplier; - -import jakarta.servlet.http.HttpServlet; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockServletContext; -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.test.context.TestSecurityContextHolder; -import org.springframework.test.web.servlet.assertj.MockMvcTester; -import org.springframework.test.web.servlet.setup.MockMvcConfigurer; -import org.springframework.web.util.pattern.PathPatternParser; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; - -/** - * Integration tests for the Actuator's MVC endpoints. - * - * @author Andy Wilkinson - */ -class WebMvcEndpointIntegrationTests { - - private AnnotationConfigServletWebApplicationContext context; - - @AfterEach - void close() { - TestSecurityContextHolder.clearContext(); - this.context.close(); - } - - @Test - void webMvcEndpointHandlerMappingIsConfiguredWithPathPatternParser() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(DefaultConfiguration.class); - this.context.setServletContext(new MockServletContext()); - this.context.refresh(); - WebMvcEndpointHandlerMapping handlerMapping = this.context.getBean(WebMvcEndpointHandlerMapping.class); - assertThat(handlerMapping.getPatternParser()).isInstanceOf(PathPatternParser.class); - } - - @Test - void endpointsAreSecureByDefault() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(SecureConfiguration.class); - MockMvcTester mvc = createSecureMockMvcTester(); - assertThat(mvc.get().uri("/actuator/beans").accept(MediaType.APPLICATION_JSON)) - .hasStatus(HttpStatus.UNAUTHORIZED); - } - - @Test - void endpointsAreSecureByDefaultWithCustomBasePath() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(SecureConfiguration.class); - TestPropertyValues.of("management.endpoints.web.base-path:/management").applyTo(this.context); - MockMvcTester mvc = createSecureMockMvcTester(); - assertThat(mvc.get().uri("/management/beans").accept(MediaType.APPLICATION_JSON)) - .hasStatus(HttpStatus.UNAUTHORIZED); - } - - @Test - void endpointsAreSecureWithActuatorRoleWithCustomBasePath() { - TestSecurityContextHolder.getContext() - .setAuthentication(new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR")); - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(SecureConfiguration.class); - TestPropertyValues - .of("management.endpoints.web.base-path:/management", "management.endpoints.web.exposure.include=*") - .applyTo(this.context); - MockMvcTester mvc = createSecureMockMvcTester(); - assertThat(mvc.get().uri("/management/beans")).hasStatusOk(); - } - - @Test - void linksAreProvidedToAllEndpointTypes() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(DefaultConfiguration.class, EndpointsConfiguration.class); - TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context); - MockMvcTester mvc = doCreateMockMvcTester(); - assertThat(mvc.get().uri("/actuator").accept("*/*")).hasStatusOk() - .bodyJson() - .extractingPath("_links") - .asMap() - .containsKeys("beans", "servlet", "restcontroller", "controller"); - } - - @Test - void linksPageIsNotAvailableWhenDisabled() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(DefaultConfiguration.class, EndpointsConfiguration.class); - TestPropertyValues.of("management.endpoints.web.discovery.enabled=false").applyTo(this.context); - MockMvcTester mvc = doCreateMockMvcTester(); - assertThat(mvc.get().uri("/actuator").accept("*/*")).hasStatus(HttpStatus.NOT_FOUND); - } - - @Test - void endpointObjectMapperCanBeApplied() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.register(EndpointObjectMapperConfiguration.class, DefaultConfiguration.class); - TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context); - MockMvcTester mvc = doCreateMockMvcTester(); - assertThat(mvc.get().uri("/actuator/beans")).hasStatusOk().bodyText().contains("\"scope\":\"notelgnis\""); - } - - private MockMvcTester createSecureMockMvcTester() { - return doCreateMockMvcTester(springSecurity()); - } - - private MockMvcTester doCreateMockMvcTester(MockMvcConfigurer... configurers) { - this.context.setServletContext(new MockServletContext()); - this.context.refresh(); - return MockMvcTester.from(this.context, (builder) -> { - for (MockMvcConfigurer configurer : configurers) { - builder.apply(configurer); - } - return builder.build(); - }); - } - - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ServletManagementContextAutoConfiguration.class, AuditAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class, - ManagementContextAutoConfiguration.class, AuditAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, BeansEndpointAutoConfiguration.class }) - static class DefaultConfiguration { - - } - - @Import(SecureConfiguration.class) - @ImportAutoConfiguration({ HypermediaAutoConfiguration.class }) - static class SpringHateoasConfiguration { - - } - - @Import(SecureConfiguration.class) - @ImportAutoConfiguration({ HypermediaAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class }) - static class SpringDataRestConfiguration { - - } - - @Import(DefaultConfiguration.class) - @ImportAutoConfiguration({ SecurityAutoConfiguration.class }) - static class SecureConfiguration { - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "servlet") - @SuppressWarnings({ "deprecation", "removal" }) - static class TestServletEndpoint - implements Supplier { - - @Override - public org.springframework.boot.actuate.endpoint.web.EndpointServlet get() { - return new org.springframework.boot.actuate.endpoint.web.EndpointServlet(new HttpServlet() { - }); - } - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint(id = "controller") - @SuppressWarnings("removal") - static class TestControllerEndpoint { - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "restcontroller") - @SuppressWarnings("removal") - static class TestRestControllerEndpoint { - - } - - @Configuration(proxyBeanMethods = false) - static class EndpointsConfiguration { - - @Bean - TestServletEndpoint testServletEndpoint() { - return new TestServletEndpoint(); - } - - @Bean - TestControllerEndpoint testControllerEndpoint() { - return new TestControllerEndpoint(); - } - - @Bean - TestRestControllerEndpoint testRestControllerEndpoint() { - return new TestRestControllerEndpoint(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcHealthEndpointAdditionalPathIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcHealthEndpointAdditionalPathIntegrationTests.java deleted file mode 100644 index e52e06bc342a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcHealthEndpointAdditionalPathIntegrationTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.integrationtest; - -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.web.context.ConfigurableWebApplicationContext; - -/** - * Integration tests for MVC health groups on an additional path. - * - * @author Madhura Bhave - */ -class WebMvcHealthEndpointAdditionalPathIntegrationTests extends - AbstractHealthEndpointAdditionalPathIntegrationTests { - - WebMvcHealthEndpointAdditionalPathIntegrationTests() { - super(new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, ManagementContextAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, WebMvcAutoConfiguration.class, - ServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, - EndpointAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - HealthEndpointAutoConfiguration.class, DiskSpaceHealthContributorAutoConfiguration.class)) - .withInitializer(new ServerPortInfoApplicationContextInitializer()) - .withPropertyValues("server.port=0")); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jms/JmsHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jms/JmsHealthContributorAutoConfigurationTests.java deleted file mode 100644 index 69543d32a4ec..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jms/JmsHealthContributorAutoConfigurationTests.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.jms; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.jms.JmsHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link JmsHealthContributorAutoConfiguration}. - * - * @author Phillip Webb - */ -class JmsHealthContributorAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ArtemisAutoConfiguration.class, - JmsHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class)); - - @Test - void runShouldCreateIndicator() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(JmsHealthIndicator.class)); - } - - @Test - void runWhenDisabledShouldNotCreateIndicator() { - this.contextRunner.withPropertyValues("management.health.jms.enabled:false") - .run((context) -> assertThat(context).doesNotHaveBean(JmsHealthIndicator.class)); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/OpenTelemetryLoggingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/OpenTelemetryLoggingAutoConfigurationTests.java deleted file mode 100644 index de4baa2db990..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/OpenTelemetryLoggingAutoConfigurationTests.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging; - -import java.util.Collection; -import java.util.concurrent.atomic.AtomicInteger; - -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.logs.LogRecordProcessor; -import io.opentelemetry.sdk.logs.ReadWriteLogRecord; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; -import io.opentelemetry.sdk.logs.data.LogRecordData; -import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; -import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link OpenTelemetryLoggingAutoConfiguration}. - * - * @author Toshiaki Maki - */ -class OpenTelemetryLoggingAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner; - - OpenTelemetryLoggingAutoConfigurationTests() { - this.contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations - .of(OpenTelemetryAutoConfiguration.class, OpenTelemetryLoggingAutoConfiguration.class)); - } - - @Test - void shouldSupplyBeans() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context).hasSingleBean(SdkLoggerProvider.class); - }); - } - - @ParameterizedTest - @ValueSource(strings = { "io.opentelemetry.sdk.logs", "io.opentelemetry.api" }) - void shouldNotSupplyBeansIfDependencyIsMissing(String packageName) { - this.contextRunner.withClassLoader(new FilteredClassLoader(packageName)).run((context) -> { - assertThat(context).doesNotHaveBean(BatchLogRecordProcessor.class); - assertThat(context).doesNotHaveBean(SdkLoggerProvider.class); - }); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfig.class).run((context) -> { - assertThat(context).hasBean("customBatchLogRecordProcessor").hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context.getBeansOfType(LogRecordProcessor.class)).hasSize(1); - assertThat(context).hasBean("customSdkLoggerProvider").hasSingleBean(SdkLoggerProvider.class); - }); - } - - @Test - void shouldAllowMultipleLogRecordExporters() { - this.contextRunner.withUserConfiguration(MultipleLogRecordExportersConfig.class).run((context) -> { - assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context.getBeansOfType(LogRecordExporter.class)).hasSize(2); - assertThat(context).hasBean("customLogRecordExporter1"); - assertThat(context).hasBean("customLogRecordExporter2"); - }); - } - - @Test - void shouldAllowMultipleLogRecordProcessorsInAdditionToBatchLogRecordProcessor() { - this.contextRunner.withUserConfiguration(MultipleLogRecordProcessorsConfig.class).run((context) -> { - assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context).hasSingleBean(SdkLoggerProvider.class); - assertThat(context.getBeansOfType(LogRecordProcessor.class)).hasSize(3); - assertThat(context).hasBean("batchLogRecordProcessor"); - assertThat(context).hasBean("customLogRecordProcessor1"); - assertThat(context).hasBean("customLogRecordProcessor2"); - }); - } - - @Test - void shouldAllowMultipleSdkLoggerProviderBuilderCustomizers() { - this.contextRunner.withUserConfiguration(MultipleSdkLoggerProviderBuilderCustomizersConfig.class) - .run((context) -> { - assertThat(context).hasSingleBean(SdkLoggerProvider.class); - assertThat(context.getBeansOfType(SdkLoggerProviderBuilderCustomizer.class)).hasSize(2); - assertThat(context).hasBean("customSdkLoggerProviderBuilderCustomizer1"); - assertThat(context).hasBean("customSdkLoggerProviderBuilderCustomizer2"); - assertThat(context - .getBean("customSdkLoggerProviderBuilderCustomizer1", NoopSdkLoggerProviderBuilderCustomizer.class) - .called()).isEqualTo(1); - assertThat(context - .getBean("customSdkLoggerProviderBuilderCustomizer2", NoopSdkLoggerProviderBuilderCustomizer.class) - .called()).isEqualTo(1); - }); - } - - @Configuration(proxyBeanMethods = false) - public static class CustomConfig { - - @Bean - public BatchLogRecordProcessor customBatchLogRecordProcessor() { - return BatchLogRecordProcessor.builder(new NoopLogRecordExporter()).build(); - } - - @Bean - public SdkLoggerProvider customSdkLoggerProvider() { - return SdkLoggerProvider.builder().build(); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class MultipleLogRecordExportersConfig { - - @Bean - public LogRecordExporter customLogRecordExporter1() { - return new NoopLogRecordExporter(); - } - - @Bean - public LogRecordExporter customLogRecordExporter2() { - return new NoopLogRecordExporter(); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class MultipleLogRecordProcessorsConfig { - - @Bean - public LogRecordProcessor customLogRecordProcessor1() { - return new NoopLogRecordProcessor(); - } - - @Bean - public LogRecordProcessor customLogRecordProcessor2() { - return new NoopLogRecordProcessor(); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class MultipleSdkLoggerProviderBuilderCustomizersConfig { - - @Bean - public SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer1() { - return new NoopSdkLoggerProviderBuilderCustomizer(); - } - - @Bean - public SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer2() { - return new NoopSdkLoggerProviderBuilderCustomizer(); - } - - } - - static class NoopLogRecordExporter implements LogRecordExporter { - - @Override - public CompletableResultCode export(Collection logs) { - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode flush() { - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode shutdown() { - return CompletableResultCode.ofSuccess(); - } - - } - - static class NoopLogRecordProcessor implements LogRecordProcessor { - - @Override - public void onEmit(Context context, ReadWriteLogRecord logRecord) { - - } - - } - - static class NoopSdkLoggerProviderBuilderCustomizer implements SdkLoggerProviderBuilderCustomizer { - - final AtomicInteger called = new AtomicInteger(0); - - @Override - public void customize(SdkLoggerProviderBuilder builder) { - this.called.incrementAndGet(); - } - - int called() { - return this.called.get(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationIntegrationTests.java deleted file mode 100644 index 4e2394e07ed6..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging.otlp; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.util.concurrent.TimeUnit; - -import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; -import okio.Buffer; -import okio.GzipSource; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.logging.OpenTelemetryLoggingAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.ApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link OtlpLoggingAutoConfiguration}. - * - * @author Toshiaki Maki - */ -class OtlpLoggingAutoConfigurationIntegrationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.application.name=otlp-logs-test", - "management.otlp.logging.headers.Authorization=Bearer my-token") - .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class, - OpenTelemetryLoggingAutoConfiguration.class, OtlpLoggingAutoConfiguration.class)); - - private final MockWebServer mockWebServer = new MockWebServer(); - - @BeforeEach - void setUp() throws IOException { - this.mockWebServer.start(); - } - - @AfterEach - void tearDown() throws IOException { - this.mockWebServer.close(); - } - - @Test - void httpLogRecordExporterShouldUseProtobufAndNoCompressionByDefault() { - this.mockWebServer.enqueue(new MockResponse()); - this.contextRunner - .withPropertyValues("management.otlp.logging.endpoint=http://localhost:%d/v1/logs" - .formatted(this.mockWebServer.getPort())) - .run((context) -> { - logMessage(context); - RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS); - assertThat(request).isNotNull(); - assertThat(request.getRequestLine()).contains("/v1/logs"); - assertThat(request.getHeader("Content-Type")).isEqualTo("application/x-protobuf"); - assertThat(request.getHeader("Content-Encoding")).isNull(); - assertThat(request.getBodySize()).isPositive(); - try (Buffer body = request.getBody()) { - assertLogMessage(body); - } - }); - } - - @Test - void httpLogRecordExporterCanBeConfiguredToUseGzipCompression() { - this.mockWebServer.enqueue(new MockResponse()); - this.contextRunner - .withPropertyValues("management.otlp.logging.endpoint=http://localhost:%d/v1/logs" - .formatted(this.mockWebServer.getPort()), "management.otlp.logging.compression=gzip") - .run((context) -> { - logMessage(context); - RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS); - assertThat(request).isNotNull(); - assertThat(request.getRequestLine()).contains("/v1/logs"); - assertThat(request.getHeader("Content-Type")).isEqualTo("application/x-protobuf"); - assertThat(request.getHeader("Content-Encoding")).isEqualTo("gzip"); - assertThat(request.getBodySize()).isPositive(); - try (Buffer uncompressed = new Buffer(); Buffer body = request.getBody()) { - uncompressed.writeAll(new GzipSource(body)); - assertLogMessage(uncompressed); - } - }); - } - - private static void logMessage(ApplicationContext context) { - SdkLoggerProvider loggerProvider = context.getBean(SdkLoggerProvider.class); - loggerProvider.get("test") - .logRecordBuilder() - .setSeverity(Severity.INFO) - .setSeverityText("INFO") - .setBody("Hello") - .setTimestamp(Instant.now()) - .emit(); - } - - private static void assertLogMessage(Buffer body) { - String string = body.readString(StandardCharsets.UTF_8); - assertThat(string).contains("otlp-logs-test"); - assertThat(string).contains("test"); - assertThat(string).contains("INFO"); - assertThat(string).contains("Hello"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationTests.java deleted file mode 100644 index dc38c9e89af6..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationTests.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.logging.otlp; - -import java.util.function.Supplier; - -import io.opentelemetry.api.metrics.MeterProvider; -import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; -import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import okhttp3.HttpUrl; -import org.assertj.core.api.InstanceOfAssertFactories; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConfigurations.ConnectionDetails.PropertiesOtlpLoggingConnectionDetails; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link OtlpLoggingAutoConfiguration}. - * - * @author Toshiaki Maki - * @author Moritz Halbritter - */ -class OtlpLoggingAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(OtlpLoggingAutoConfiguration.class)); - - @Test - void shouldNotSupplyBeansIfPropertyIsNotSet() { - this.contextRunner.run((context) -> { - assertThat(context).doesNotHaveBean(OtlpLoggingConnectionDetails.class); - assertThat(context).doesNotHaveBean(OtlpHttpLogRecordExporter.class); - }); - } - - @Test - void shouldSupplyBeans() { - this.contextRunner.withPropertyValues("management.otlp.logging.endpoint=http://localhost:4318/v1/logs") - .run((context) -> { - assertThat(context).hasSingleBean(OtlpLoggingConnectionDetails.class); - OtlpLoggingConnectionDetails connectionDetails = context.getBean(OtlpLoggingConnectionDetails.class); - assertThat(connectionDetails.getUrl(Transport.HTTP)).isEqualTo("http://localhost:4318/v1/logs"); - assertThat(context).hasSingleBean(OtlpHttpLogRecordExporter.class) - .hasSingleBean(LogRecordExporter.class); - }); - } - - @ParameterizedTest - @ValueSource(strings = { "io.opentelemetry.sdk.logs", "io.opentelemetry.api", - "io.opentelemetry.exporter.otlp.http.logs" }) - void shouldNotSupplyBeansIfDependencyIsMissing(String packageName) { - this.contextRunner.withClassLoader(new FilteredClassLoader(packageName)).run((context) -> { - assertThat(context).doesNotHaveBean(OtlpLoggingConnectionDetails.class); - assertThat(context).doesNotHaveBean(OtlpHttpLogRecordExporter.class); - }); - } - - @Test - void shouldBackOffWhenLoggingExportPropertyIsNotEnabled() { - this.contextRunner - .withPropertyValues("management.logging.export.enabled=false", - "management.otlp.logging.endpoint=http://localhost:4318/v1/logs") - .run((context) -> { - assertThat(context).hasSingleBean(OtlpLoggingConnectionDetails.class); - assertThat(context).doesNotHaveBean(LogRecordExporter.class); - }); - } - - @Test - void shouldBackOffWhenOtlpLoggingExportPropertyIsNotEnabled() { - this.contextRunner - .withPropertyValues("management.otlp.logging.export.enabled=false", - "management.otlp.logging.endpoint=http://localhost:4318/v1/logs") - .run((context) -> { - assertThat(context).hasSingleBean(OtlpLoggingConnectionDetails.class); - assertThat(context).doesNotHaveBean(LogRecordExporter.class); - }); - } - - @Test - void shouldBackOffWhenCustomHttpExporterIsDefined() { - this.contextRunner.withUserConfiguration(CustomHttpExporterConfiguration.class) - .run((context) -> assertThat(context).hasBean("customOtlpHttpLogRecordExporter") - .hasSingleBean(LogRecordExporter.class)); - } - - @Test - void shouldBackOffWhenCustomGrpcExporterIsDefined() { - this.contextRunner.withUserConfiguration(CustomGrpcExporterConfiguration.class) - .run((context) -> assertThat(context).hasBean("customOtlpGrpcLogRecordExporter") - .hasSingleBean(LogRecordExporter.class)); - } - - @Test - void shouldBackOffWhenCustomOtlpLoggingConnectionDetailsIsDefined() { - this.contextRunner.withUserConfiguration(CustomOtlpLoggingConnectionDetails.class).run((context) -> { - assertThat(context).hasSingleBean(OtlpLoggingConnectionDetails.class) - .doesNotHaveBean(PropertiesOtlpLoggingConnectionDetails.class); - OtlpHttpLogRecordExporter otlpHttpLogRecordExporter = context.getBean(OtlpHttpLogRecordExporter.class); - assertThat(otlpHttpLogRecordExporter).extracting("delegate.httpSender.url") - .isEqualTo(HttpUrl.get("https://otel.example.com/v1/logs")); - }); - } - - @Test - void shouldUseHttpExporterIfTransportIsNotSet() { - this.contextRunner.withPropertyValues("management.otlp.logging.endpoint=http://localhost:4318/v1/logs") - .run((context) -> { - assertThat(context).hasSingleBean(OtlpHttpLogRecordExporter.class) - .hasSingleBean(LogRecordExporter.class); - assertThat(context).doesNotHaveBean(OtlpGrpcLogRecordExporter.class); - }); - } - - @Test - void shouldUseHttpExporterIfTransportIsSetToHttp() { - this.contextRunner - .withPropertyValues("management.otlp.logging.endpoint=http://localhost:4318/v1/logs", - "management.otlp.logging.transport=http") - .run((context) -> { - assertThat(context).hasSingleBean(OtlpHttpLogRecordExporter.class) - .hasSingleBean(LogRecordExporter.class); - assertThat(context).doesNotHaveBean(OtlpGrpcLogRecordExporter.class); - }); - } - - @Test - void shouldUseGrpcExporterIfTransportIsSetToGrpc() { - this.contextRunner - .withPropertyValues("management.otlp.logging.endpoint=http://localhost:4318/v1/logs", - "management.otlp.logging.transport=grpc") - .run((context) -> { - assertThat(context).hasSingleBean(OtlpGrpcLogRecordExporter.class) - .hasSingleBean(LogRecordExporter.class); - assertThat(context).doesNotHaveBean(OtlpHttpLogRecordExporter.class); - }); - } - - @Test - void httpShouldUseMeterProviderIfSet() { - this.contextRunner.withUserConfiguration(MeterProviderConfiguration.class) - .withPropertyValues("management.otlp.logging.endpoint=http://localhost:4318/v1/logs") - .run((context) -> { - OtlpHttpLogRecordExporter otlpHttpLogRecordExporter = context.getBean(OtlpHttpLogRecordExporter.class); - assertThat(otlpHttpLogRecordExporter.toBuilder()) - .extracting("delegate.meterProviderSupplier", InstanceOfAssertFactories.type(Supplier.class)) - .satisfies((meterProviderSupplier) -> assertThat(meterProviderSupplier.get()) - .isSameAs(MeterProviderConfiguration.meterProvider)); - }); - } - - @Test - void grpcShouldUseMeterProviderIfSet() { - this.contextRunner.withUserConfiguration(MeterProviderConfiguration.class) - .withPropertyValues("management.otlp.logging.endpoint=http://localhost:4318/v1/logs", - "management.otlp.logging.transport=grpc") - .run((context) -> { - OtlpGrpcLogRecordExporter otlpGrpcLogRecordExporter = context.getBean(OtlpGrpcLogRecordExporter.class); - assertThat(otlpGrpcLogRecordExporter.toBuilder()) - .extracting("delegate.meterProviderSupplier", InstanceOfAssertFactories.type(Supplier.class)) - .satisfies((meterProviderSupplier) -> assertThat(meterProviderSupplier.get()) - .isSameAs(MeterProviderConfiguration.meterProvider)); - }); - } - - @Configuration(proxyBeanMethods = false) - private static final class MeterProviderConfiguration { - - static final MeterProvider meterProvider = (instrumentationScopeName) -> null; - - @Bean - MeterProvider meterProvider() { - return meterProvider; - } - - } - - @Configuration(proxyBeanMethods = false) - private static final class CustomHttpExporterConfiguration { - - @Bean - OtlpHttpLogRecordExporter customOtlpHttpLogRecordExporter() { - return OtlpHttpLogRecordExporter.builder().build(); - } - - } - - @Configuration(proxyBeanMethods = false) - private static final class CustomGrpcExporterConfiguration { - - @Bean - OtlpGrpcLogRecordExporter customOtlpGrpcLogRecordExporter() { - return OtlpGrpcLogRecordExporter.builder().build(); - } - - } - - @Configuration(proxyBeanMethods = false) - private static final class CustomOtlpLoggingConnectionDetails { - - @Bean - OtlpLoggingConnectionDetails customOtlpLoggingConnectionDetails() { - return (transport) -> "https://otel.example.com/v1/logs"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java deleted file mode 100644 index 5a0820a29eb7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics; - -import java.util.Arrays; -import java.util.Set; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.composite.CompositeMeterRegistry; -import io.micrometer.core.instrument.simple.SimpleConfig; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import io.micrometer.graphite.GraphiteMeterRegistry; -import io.micrometer.jmx.JmxMeterRegistry; -import org.assertj.core.api.InstanceOfAssertFactories; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for metrics auto-configuration. - * - * @author Stephane Nicoll - */ -class MetricsAutoConfigurationIntegrationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()); - - @Test - void propertyBasedMeterFilteringIsAutoConfigured() { - this.contextRunner.withPropertyValues("management.metrics.enable.my.org=false").run((context) -> { - MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.timer("my.org.timer"); - assertThat(registry.find("my.org.timer").timer()).isNull(); - }); - } - - @Test - void propertyBasedCommonTagsIsAutoConfigured() { - this.contextRunner - .withPropertyValues("management.metrics.tags.region=test", "management.metrics.tags.origin=local") - .run((context) -> { - MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.counter("my.counter", "env", "qa"); - assertThat(registry.find("my.counter") - .tags("env", "qa") - .tags("region", "test") - .tags("origin", "local") - .counter()).isNotNull(); - }); - } - - @Test - void simpleMeterRegistryIsUsedAsAFallback() { - this.contextRunner - .run((context) -> assertThat(context.getBean(MeterRegistry.class)).isInstanceOf(SimpleMeterRegistry.class)); - } - - @Test - void emptyCompositeIsCreatedWhenNoMeterRegistriesAreAutoConfigured() { - new ApplicationContextRunner().with(MetricsRun.limitedTo()).run((context) -> { - MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); - assertThat(((CompositeMeterRegistry) registry).getRegistries()).isEmpty(); - }); - } - - @Test - void noCompositeIsCreatedWhenASingleMeterRegistryIsAutoConfigured() { - new ApplicationContextRunner().with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class)) - .run((context) -> assertThat(context.getBean(MeterRegistry.class)) - .isInstanceOf(GraphiteMeterRegistry.class)); - } - - @Test - void noCompositeIsCreatedWithMultipleRegistriesAndOneThatIsPrimary() { - new ApplicationContextRunner() - .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, - JmxMetricsExportAutoConfiguration.class)) - .withUserConfiguration(PrimaryMeterRegistryConfiguration.class) - .run((context) -> assertThat(context.getBean(MeterRegistry.class)).isInstanceOf(SimpleMeterRegistry.class)); - } - - @Test - void compositeCreatedWithMultipleRegistries() { - new ApplicationContextRunner() - .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, - JmxMetricsExportAutoConfiguration.class)) - .run((context) -> { - MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); - assertThat(((CompositeMeterRegistry) registry).getRegistries()) - .hasAtLeastOneElementOfType(GraphiteMeterRegistry.class) - .hasAtLeastOneElementOfType(JmxMeterRegistry.class); - }); - } - - @Test - void autoConfiguredCompositeDoesNotHaveMeterFiltersApplied() { - new ApplicationContextRunner() - .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, - JmxMetricsExportAutoConfiguration.class)) - .run((context) -> { - MeterRegistry composite = context.getBean(MeterRegistry.class); - assertThat(composite).extracting("filters", InstanceOfAssertFactories.ARRAY).isEmpty(); - assertThat(composite).isInstanceOf(CompositeMeterRegistry.class); - Set registries = ((CompositeMeterRegistry) composite).getRegistries(); - assertThat(registries).hasSize(2); - assertThat(registries).hasAtLeastOneElementOfType(GraphiteMeterRegistry.class) - .hasAtLeastOneElementOfType(JmxMeterRegistry.class); - assertThat(registries).allSatisfy( - (registry) -> assertThat(registry).extracting("filters", InstanceOfAssertFactories.ARRAY) - .hasSize(1)); - }); - } - - @Test - void userConfiguredCompositeHasMeterFiltersApplied() { - new ApplicationContextRunner().with(MetricsRun.limitedTo()) - .withUserConfiguration(CompositeMeterRegistryConfiguration.class) - .run((context) -> { - MeterRegistry composite = context.getBean(MeterRegistry.class); - assertThat(composite).extracting("filters", InstanceOfAssertFactories.ARRAY).hasSize(1); - assertThat(composite).isInstanceOf(CompositeMeterRegistry.class); - Set registries = ((CompositeMeterRegistry) composite).getRegistries(); - assertThat(registries).hasSize(2); - assertThat(registries).hasOnlyElementsOfTypes(SimpleMeterRegistry.class); - }); - } - - @Configuration(proxyBeanMethods = false) - static class PrimaryMeterRegistryConfiguration { - - @Primary - @Bean - MeterRegistry simpleMeterRegistry() { - return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CompositeMeterRegistryConfiguration { - - @Bean - CompositeMeterRegistry compositeMeterRegistry() { - return new CompositeMeterRegistry(new MockClock(), - Arrays.asList(new SimpleMeterRegistry(), new SimpleMeterRegistry())); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java deleted file mode 100644 index 6d25dff50824..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics; - -import java.util.Map; - -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.LoggerContext; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.composite.CompositeMeterRegistry; -import org.junit.jupiter.api.Test; -import org.slf4j.LoggerFactory; - -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link MeterRegistryPostProcessor} configured by - * {@link MetricsAutoConfiguration}. - * - * @author Jon Schneider - */ -class MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .with(MetricsRun.limitedTo(AtlasMetricsExportAutoConfiguration.class, - PrometheusMetricsExportAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(JvmMetricsAutoConfiguration.class)); - - @Test - void binderMetricsAreSearchableFromTheComposite() { - this.contextRunner.run((context) -> { - CompositeMeterRegistry composite = context.getBean(CompositeMeterRegistry.class); - composite.get("jvm.memory.used").gauge(); - context.getBeansOfType(MeterRegistry.class) - .forEach((name, registry) -> registry.get("jvm.memory.used").gauge()); - }); - } - - @Test - void customizersAreAppliedBeforeBindersAreCreated() { - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(MetricsAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class)) - .withUserConfiguration(TestConfiguration.class) - .run((context) -> { - }); - } - - @Test - void counterIsIncrementedOncePerEventWithoutCompositeMeterRegistry() { - new ApplicationContextRunner().with(MetricsRun.limitedTo(JmxMetricsExportAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)) - .run((context) -> { - Logger logger = ((LoggerContext) LoggerFactory.getILoggerFactory()).getLogger("test-logger"); - logger.error("Error."); - Map registriesByName = context.getBeansOfType(MeterRegistry.class); - assertThat(registriesByName).hasSize(1); - MeterRegistry registry = registriesByName.values().iterator().next(); - assertThat(registry.get("logback.events").tag("level", "error").counter().count()).isOne(); - }); - } - - @Test - void counterIsIncrementedOncePerEventWithCompositeMeterRegistry() { - new ApplicationContextRunner() - .with(MetricsRun.limitedTo(JmxMetricsExportAutoConfiguration.class, - PrometheusMetricsExportAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)) - .run((context) -> { - Logger logger = ((LoggerContext) LoggerFactory.getILoggerFactory()).getLogger("test-logger"); - logger.error("Error."); - Map registriesByName = context.getBeansOfType(MeterRegistry.class); - assertThat(registriesByName).hasSize(3); - registriesByName.forEach((name, - registry) -> assertThat(registry.get("logback.events").tag("level", "error").counter().count()) - .isOne()); - }); - } - - @Configuration(proxyBeanMethods = false) - static class TestConfiguration { - - @Bean - MeterBinder testBinder(Alpha thing) { - return (registry) -> { - }; - } - - @Bean - MeterRegistryCustomizer testCustomizer() { - return (registry) -> registry.config().commonTags("testTag", "testValue"); - } - - @Bean - Alpha alpha() { - return new Alpha(); - } - - @Bean - Bravo bravo(Alpha alpha) { - return new Bravo(alpha); - } - - @Bean - static BeanPostProcessor testPostProcessor(ApplicationContext context) { - return new BeanPostProcessor() { - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) { - if (bean instanceof Bravo) { - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - meterRegistry.gauge("test", 1); - System.out.println(meterRegistry.find("test").gauge().getId().getTags()); - } - return bean; - } - - }; - } - - } - - static class Alpha { - - } - - static class Bravo { - - Bravo(Alpha alpha) { - - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java deleted file mode 100644 index aa9fa98ee437..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics; - -import io.micrometer.core.instrument.Clock; -import io.micrometer.core.instrument.Meter; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.config.MeterFilter; -import io.micrometer.core.instrument.config.MeterFilterReply; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration.MeterRegistryCloser; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link MetricsAutoConfiguration}. - * - * @author Andy Wilkinson - * @author Moritz Halbritter - */ -class MetricsAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)); - - @Test - void autoConfiguresAClock() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(Clock.class)); - } - - @Test - void allowsACustomClockToBeUsed() { - this.contextRunner.withUserConfiguration(CustomClockConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(Clock.class).hasBean("customClock")); - } - - @SuppressWarnings("unchecked") - @Test - void configuresMeterRegistries() { - this.contextRunner.withUserConfiguration(MeterRegistryConfiguration.class).run((context) -> { - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - MeterFilter[] filters = (MeterFilter[]) ReflectionTestUtils.getField(meterRegistry, "filters"); - assertThat(filters).hasSize(3); - assertThat(filters[0].accept((Meter.Id) null)).isEqualTo(MeterFilterReply.DENY); - assertThat(filters[1]).isInstanceOf(PropertiesMeterFilter.class); - assertThat(filters[2].accept((Meter.Id) null)).isEqualTo(MeterFilterReply.ACCEPT); - then((MeterBinder) context.getBean("meterBinder")).should().bindTo(meterRegistry); - then(context.getBean(MeterRegistryCustomizer.class)).should().customize(meterRegistry); - }); - } - - @Test - void shouldSupplyMeterRegistryCloser() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(MeterRegistryCloser.class)); - } - - @Test - void meterRegistryCloserShouldCloseRegistryOnShutdown() { - this.contextRunner.withUserConfiguration(MeterRegistryConfiguration.class).run((context) -> { - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.isClosed()).isFalse(); - context.close(); - assertThat(meterRegistry.isClosed()).isTrue(); - }); - } - - @Configuration(proxyBeanMethods = false) - static class CustomClockConfiguration { - - @Bean - Clock customClock() { - return Clock.SYSTEM; - } - - } - - @Configuration(proxyBeanMethods = false) - static class MeterRegistryConfiguration { - - @Bean - MeterRegistry meterRegistry() { - return new SimpleMeterRegistry(); - } - - @Bean - @SuppressWarnings("rawtypes") - MeterRegistryCustomizer meterRegistryCustomizer() { - return mock(MeterRegistryCustomizer.class); - } - - @Bean - MeterBinder meterBinder() { - return mock(MeterBinder.class); - } - - @Bean - @Order(1) - MeterFilter acceptMeterFilter() { - return MeterFilter.accept(); - } - - @Bean - @Order(-1) - MeterFilter denyMeterFilter() { - return MeterFilter.deny(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/ValidationFailureAnalyzerTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/ValidationFailureAnalyzerTests.java deleted file mode 100644 index b8be3d434693..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/ValidationFailureAnalyzerTests.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics; - -import io.micrometer.core.instrument.Clock; -import io.micrometer.newrelic.NewRelicMeterRegistry; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic.NewRelicProperties; -import org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic.NewRelicPropertiesConfigAdapter; -import org.springframework.boot.diagnostics.FailureAnalysis; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -/** - * Tests for {@link ValidationFailureAnalyzer}. - * - * @author Andy Wilkinson - */ -class ValidationFailureAnalyzerTests { - - @Test - void analyzesMissingRequiredConfiguration() { - FailureAnalysis analysis = new ValidationFailureAnalyzer() - .analyze(createFailure(MissingAccountIdAndApiKeyConfiguration.class)); - assertThat(analysis).isNotNull(); - assertThat(analysis.getCause().getMessage()).contains("management.newrelic.metrics.export.apiKey was 'null'"); - assertThat(analysis.getDescription()).isEqualTo(String.format("Invalid Micrometer configuration detected:%n%n" - + " - management.newrelic.metrics.export.apiKey was 'null' but it is required when publishing to Insights API%n" - + " - management.newrelic.metrics.export.accountId was 'null' but it is required when publishing to Insights API")); - } - - private Exception createFailure(Class configuration) { - try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(configuration)) { - fail("Expected failure did not occur"); - return null; - } - catch (Exception ex) { - return ex; - } - } - - @Configuration(proxyBeanMethods = false) - @Import(NewRelicProperties.class) - static class MissingAccountIdAndApiKeyConfiguration { - - @Bean - NewRelicMeterRegistry meterRegistry(NewRelicProperties newRelicProperties) { - return new NewRelicMeterRegistry(new NewRelicPropertiesConfigAdapter(newRelicProperties), Clock.SYSTEM); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfigurationIntegrationTests.java deleted file mode 100644 index 62769e7ffbf5..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.data; - -import io.micrometer.core.instrument.Gauge; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.MeterBinder; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.data.city.CityRepository; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.autoconfigure.AutoConfigurationPackage; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link RepositoryMetricsAutoConfiguration}. - * - * @author Phillip Webb - */ -class RepositoryMetricsAutoConfigurationIntegrationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration( - AutoConfigurations.of(HibernateJpaAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, RepositoryMetricsAutoConfiguration.class)) - .withUserConfiguration(EmbeddedDataSourceConfiguration.class, TestConfig.class); - - @Test - void repositoryMethodCallRecordsMetrics() { - this.contextRunner.run((context) -> { - context.getBean(CityRepository.class).count(); - MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry.get("spring.data.repository.invocations") - .tag("repository", "CityRepository") - .timer() - .count()).isOne(); - }); - } - - @Test - void doesNotPreventMeterBindersFromDependingUponSpringDataRepositories() { - this.contextRunner.withUserConfiguration(SpringDataRepositoryMeterBinderConfiguration.class) - .run((context) -> assertThat(context).hasNotFailed()); - } - - @Configuration(proxyBeanMethods = false) - @AutoConfigurationPackage - static class TestConfig { - - } - - @Configuration(proxyBeanMethods = false) - static class SpringDataRepositoryMeterBinderConfiguration { - - @Bean - MeterBinder meterBinder(CityRepository repository) { - return (registry) -> Gauge.builder("city.count", repository::count); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/city/City.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/city/City.java deleted file mode 100644 index a4327cc1564c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/city/City.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.data.city; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; - -@Entity -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String state; - - @Column(nullable = false) - private String country; - - @Column(nullable = false) - private String map; - - protected City() { - } - - public City(String name, String country) { - this.name = name; - this.country = country; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/city/CityRepository.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/city/CityRepository.java deleted file mode 100644 index 6a5765db557a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/city/CityRepository.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.data.city; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface CityRepository extends JpaRepository { - - @Override - Page findAll(Pageable pageable); - - Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); - - City findByNameAndCountryAllIgnoringCase(String name, String country); - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxMetricsExportAutoConfigurationTests.java deleted file mode 100644 index 378c87b838b7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxMetricsExportAutoConfigurationTests.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx; - -import io.micrometer.core.instrument.Clock; -import io.micrometer.signalfx.SignalFxConfig; -import io.micrometer.signalfx.SignalFxMeterRegistry; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SignalFxMetricsExportAutoConfiguration}. - * - * @author Andy Wilkinson - * @deprecated since 3.5.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.5.0", forRemoval = true) -class SignalFxMetricsExportAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SignalFxMetricsExportAutoConfiguration.class)); - - @Test - void backsOffWithoutAClock() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(SignalFxMeterRegistry.class)); - } - - @Test - void failsWithoutAnAccessToken() { - this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .run((context) -> assertThat(context).hasFailed()); - } - - @Test - void autoConfiguresWithAnAccessToken() { - this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.signalfx.metrics.export.access-token=abcde") - .run((context) -> assertThat(context).hasSingleBean(SignalFxMeterRegistry.class) - .hasSingleBean(Clock.class) - .hasSingleBean(SignalFxConfig.class)); - } - - @Test - void autoConfigurationCanBeDisabledWithDefaultsEnabledProperty() { - this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.defaults.metrics.export.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(SignalFxMeterRegistry.class) - .doesNotHaveBean(SignalFxConfig.class)); - } - - @Test - void autoConfigurationCanBeDisabledWithSpecificEnabledProperty() { - this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.signalfx.metrics.export.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(SignalFxMeterRegistry.class) - .doesNotHaveBean(SignalFxConfig.class)); - } - - @Test - void allowsConfigToBeCustomized() { - this.contextRunner.withPropertyValues("management.signalfx.metrics.export.access-token=abcde") - .withUserConfiguration(CustomConfigConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(Clock.class) - .hasSingleBean(SignalFxMeterRegistry.class) - .hasSingleBean(SignalFxConfig.class) - .hasBean("customConfig")); - } - - @Test - void allowsRegistryToBeCustomized() { - this.contextRunner.withPropertyValues("management.signalfx.metrics.export.access-token=abcde") - .withUserConfiguration(CustomRegistryConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(Clock.class) - .hasSingleBean(SignalFxConfig.class) - .hasSingleBean(SignalFxMeterRegistry.class) - .hasBean("customRegistry")); - } - - @Test - void stopsMeterRegistryWhenContextIsClosed() { - this.contextRunner.withPropertyValues("management.signalfx.metrics.export.access-token=abcde") - .withUserConfiguration(BaseConfiguration.class) - .run((context) -> { - SignalFxMeterRegistry registry = context.getBean(SignalFxMeterRegistry.class); - assertThat(registry.isClosed()).isFalse(); - context.close(); - assertThat(registry.isClosed()).isTrue(); - }); - } - - @Configuration(proxyBeanMethods = false) - static class BaseConfiguration { - - @Bean - Clock customClock() { - return Clock.SYSTEM; - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(BaseConfiguration.class) - static class CustomConfigConfiguration { - - @Bean - SignalFxConfig customConfig() { - return (key) -> { - if ("signalfx.accessToken".equals(key)) { - return "abcde"; - } - return null; - }; - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(BaseConfiguration.class) - static class CustomRegistryConfiguration { - - @Bean - SignalFxMeterRegistry customRegistry(SignalFxConfig config, Clock clock) { - return new SignalFxMeterRegistry(config, clock); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapterTests.java deleted file mode 100644 index 950ba16291d7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesConfigAdapterTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapterTests; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SignalFxPropertiesConfigAdapter}. - * - * @author Mirko Sobeck - * @deprecated since 3.5.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.5.0", forRemoval = true) -class SignalFxPropertiesConfigAdapterTests - extends StepRegistryPropertiesConfigAdapterTests { - - protected SignalFxPropertiesConfigAdapterTests() { - super(SignalFxPropertiesConfigAdapter.class); - } - - @Override - protected SignalFxProperties createProperties() { - SignalFxProperties signalFxProperties = new SignalFxProperties(); - signalFxProperties.setAccessToken("ABC"); - return signalFxProperties; - } - - @Override - protected SignalFxPropertiesConfigAdapter createConfigAdapter(SignalFxProperties properties) { - return new SignalFxPropertiesConfigAdapter(properties); - } - - @Test - void whenPropertiesAccessTokenIsSetAdapterAccessTokenReturnsIt() { - SignalFxProperties properties = createProperties(); - assertThat(createConfigAdapter(properties).accessToken()).isEqualTo("ABC"); - } - - @Test - void whenPropertiesUriIsSetAdapterUriReturnsIt() { - SignalFxProperties properties = createProperties(); - properties.setUri("https://example.signalfx.com"); - assertThat(createConfigAdapter(properties).uri()).isEqualTo("https://example.signalfx.com"); - } - - @Test - void whenPropertiesSourceIsSetAdapterSourceReturnsIt() { - SignalFxProperties properties = createProperties(); - properties.setSource("DESKTOP-GA5"); - assertThat(createConfigAdapter(properties).source()).isEqualTo("DESKTOP-GA5"); - } - - @Test - void whenPropertiesPublishHistogramTypeIsCumulativeAdapterPublishCumulativeHistogramReturnsIt() { - SignalFxProperties properties = createProperties(); - properties.setPublishedHistogramType(SignalFxProperties.HistogramType.CUMULATIVE); - assertThat(createConfigAdapter(properties).publishCumulativeHistogram()).isTrue(); - assertThat(createConfigAdapter(properties).publishDeltaHistogram()).isFalse(); - } - - @Test - void whenPropertiesPublishHistogramTypeIsDeltaAdapterPublishDeltaHistogramReturnsIt() { - SignalFxProperties properties = createProperties(); - properties.setPublishedHistogramType(SignalFxProperties.HistogramType.DELTA); - assertThat(createConfigAdapter(properties).publishDeltaHistogram()).isTrue(); - assertThat(createConfigAdapter(properties).publishCumulativeHistogram()).isFalse(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesTests.java deleted file mode 100644 index 39e73e48514f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/signalfx/SignalFxPropertiesTests.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx; - -import io.micrometer.signalfx.SignalFxConfig; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SignalFxProperties}. - * - * @author Stephane Nicoll - * @deprecated since 3.5.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.5.0", forRemoval = true) -class SignalFxPropertiesTests extends StepRegistryPropertiesTests { - - @Test - void defaultValuesAreConsistent() { - SignalFxProperties properties = new SignalFxProperties(); - SignalFxConfig config = (key) -> null; - assertStepRegistryDefaultValues(properties, config); - // access token is mandatory - assertThat(properties.getUri()).isEqualTo(config.uri()); - // source has no static default value - // Not publishing cumulative or delta histograms implies that the default - // histogram type should be published. - assertThat(config.publishCumulativeHistogram()).isFalse(); - assertThat(config.publishDeltaHistogram()).isFalse(); - assertThat(properties.getPublishedHistogramType()).isEqualTo(SignalFxProperties.HistogramType.DEFAULT); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfigurationTests.java deleted file mode 100644 index a8716469c875..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfigurationTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.jersey; - -import java.net.URI; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Timer; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import org.glassfish.jersey.micrometer.server.ObservationApplicationEventListener; -import org.glassfish.jersey.server.ResourceConfig; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration; -import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link JerseyServerMetricsAutoConfiguration}. - * - * @author Michael Weirauch - * @author Michael Simons - * @author Moritz Halbritter - */ -class JerseyServerMetricsAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(JerseyServerMetricsAutoConfiguration.class)); - - private final WebApplicationContextRunner webContextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration( - AutoConfigurations.of(JerseyAutoConfiguration.class, JerseyServerMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class, - ObservationAutoConfiguration.class, MetricsAutoConfiguration.class)) - .withUserConfiguration(ResourceConfiguration.class) - .withPropertyValues("server.port:0"); - - @Test - void shouldOnlyBeActiveInWebApplicationContext() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ResourceConfigCustomizer.class)); - } - - @Test - void shouldProvideAllNecessaryBeans() { - this.webContextRunner.run((context) -> assertThat(context).hasBean("jerseyMetricsUriTagFilter") - .hasSingleBean(ResourceConfigCustomizer.class)); - } - - @Test - void httpRequestsAreTimed() { - this.webContextRunner.run((context) -> { - doRequest(context); - Thread.sleep(500); - MeterRegistry registry = context.getBean(MeterRegistry.class); - Timer timer = registry.get("http.server.requests").tag("uri", "/users/{id}").timer(); - assertThat(timer.count()).isOne(); - }); - } - - @Test - void noHttpRequestsTimedWhenJerseyInstrumentationMissingFromClasspath() { - this.webContextRunner.withClassLoader(new FilteredClassLoader(ObservationApplicationEventListener.class)) - .run((context) -> { - doRequest(context); - MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry.find("http.server.requests").timer()).isNull(); - }); - } - - private static void doRequest(AssertableWebApplicationContext context) { - int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) - .getWebServer() - .getPort(); - RestTemplate restTemplate = new RestTemplate(); - restTemplate.getForEntity(URI.create("http://localhost:" + port + "/users/3"), String.class); - } - - @Configuration(proxyBeanMethods = false) - static class ResourceConfiguration { - - @Bean - ResourceConfig resourceConfig() { - return new ResourceConfig().register(new TestResource()); - } - - @Path("/users") - public static class TestResource { - - @GET - @Path("/{id}") - public String getUser(@PathParam("id") String id) { - return id; - } - - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java deleted file mode 100644 index 22f7ac479661..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.test; - -import java.time.Duration; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CyclicBarrier; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; -import io.micrometer.core.instrument.binder.logging.LogbackMetrics; -import io.micrometer.core.instrument.simple.SimpleConfig; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import jakarta.servlet.DispatcherType; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.metrics.JvmMetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.LogbackMetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.SystemMetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.amqp.RabbitMetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.web.client.HttpClientObservationsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.web.reactive.WebFluxObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.web.servlet.WebMvcObservationAutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.filter.ServerHttpObservationFilter; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.waitAtMost; -import static org.springframework.test.web.client.ExpectedCount.once; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - -/** - * Integration tests for Metrics. - * - * @author Jon Schneider - */ -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = MetricsIntegrationTests.MetricsApp.class, - properties = "management.metrics.use-global-registry=false") -class MetricsIntegrationTests { - - @Autowired - private ApplicationContext context; - - @Autowired - private RestTemplate external; - - @Autowired - private TestRestTemplate loopback; - - @Autowired - private MeterRegistry registry; - - @BeforeEach - void setUp() { - this.registry.clear(); - } - - @SuppressWarnings("unchecked") - @Test - void restTemplateIsInstrumented() { - MockRestServiceServer server = MockRestServiceServer.bindTo(this.external).build(); - server.expect(once(), requestTo("/api/external")) - .andExpect(method(HttpMethod.GET)) - .andRespond(withSuccess("{\"message\": \"hello\"}", MediaType.APPLICATION_JSON)); - assertThat(this.external.getForObject("/api/external", Map.class)).containsKey("message"); - assertThat(this.registry.get("http.client.requests").timer().count()).isOne(); - } - - @Test - void requestMappingIsInstrumented() { - this.loopback.getForObject("/api/people", Set.class); - waitAtMost(Duration.ofSeconds(5)) - .untilAsserted(() -> assertThat(this.registry.get("http.server.requests").timer().count()).isOne()); - - } - - @Test - void automaticallyRegisteredBinders() { - assertThat(this.context.getBeansOfType(MeterBinder.class).values()) - .hasAtLeastOneElementOfType(LogbackMetrics.class) - .hasAtLeastOneElementOfType(JvmMemoryMetrics.class); - } - - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - void metricsFilterRegisteredForAsyncDispatches() { - Map filterRegistrations = this.context - .getBeansOfType(FilterRegistrationBean.class); - assertThat(filterRegistrations).containsKey("webMvcObservationFilter"); - FilterRegistrationBean registration = filterRegistrations.get("webMvcObservationFilter"); - assertThat(registration.getFilter()).isInstanceOf(ServerHttpObservationFilter.class); - assertThat((Set) ReflectionTestUtils.getField(registration, "dispatcherTypes")) - .containsExactlyInAnyOrder(DispatcherType.REQUEST, DispatcherType.ASYNC); - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ MetricsAutoConfiguration.class, ObservationAutoConfiguration.class, - JvmMetricsAutoConfiguration.class, LogbackMetricsAutoConfiguration.class, - SystemMetricsAutoConfiguration.class, RabbitMetricsAutoConfiguration.class, - CacheMetricsAutoConfiguration.class, DataSourcePoolMetricsAutoConfiguration.class, - HibernateMetricsAutoConfiguration.class, HttpClientObservationsAutoConfiguration.class, - WebFluxObservationAutoConfiguration.class, WebMvcObservationAutoConfiguration.class, - JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - RestTemplateAutoConfiguration.class, WebMvcAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class }) - @Import(PersonController.class) - static class MetricsApp { - - @Primary - @Bean - MeterRegistry registry() { - return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); - } - - @Bean - RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) { - return restTemplateBuilder.build(); - } - - @Bean - CyclicBarrier cyclicBarrier() { - return new CyclicBarrier(2); - } - - } - - @RestController - static class PersonController { - - @GetMapping("/api/people") - Set personName() { - return Collections.singleton("Jon"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsRun.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsRun.java deleted file mode 100644 index 1eca9f2334a0..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsRun.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.test; - -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.function.Function; - -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.datadog.DatadogMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.GangliaMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.influx.InfluxMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic.NewRelicMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.AbstractApplicationContextRunner; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.util.Assert; - -/** - * Additional metrics configuration and settings that can be applied to a - * {@link ApplicationContextRunner} when running a metrics test. - * - * @author Jon Schneider - * @author Phillip Webb - */ -@SuppressWarnings("removal") -public final class MetricsRun { - - private static final Set> EXPORT_AUTO_CONFIGURATIONS; - - static { - Set> implementations = new LinkedHashSet<>(); - implementations.add(AtlasMetricsExportAutoConfiguration.class); - implementations.add(DatadogMetricsExportAutoConfiguration.class); - implementations.add(GangliaMetricsExportAutoConfiguration.class); - implementations.add(GraphiteMetricsExportAutoConfiguration.class); - implementations.add(InfluxMetricsExportAutoConfiguration.class); - implementations.add(JmxMetricsExportAutoConfiguration.class); - implementations.add(NewRelicMetricsExportAutoConfiguration.class); - implementations.add(OtlpMetricsExportAutoConfiguration.class); - implementations.add(PrometheusMetricsExportAutoConfiguration.class); - implementations.add(SimpleMetricsExportAutoConfiguration.class); - implementations.add( - org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx.SignalFxMetricsExportAutoConfiguration.class); - implementations.add(StatsdMetricsExportAutoConfiguration.class); - EXPORT_AUTO_CONFIGURATIONS = Collections.unmodifiableSet(implementations); - } - - private static final AutoConfigurations AUTO_CONFIGURATIONS = AutoConfigurations.of(MetricsAutoConfiguration.class, - CompositeMeterRegistryAutoConfiguration.class); - - private MetricsRun() { - } - - /** - * Return a function that configures the run to be limited to the {@code simple} - * implementation. - * @return the function to apply - */ - public static > Function simple() { - return limitedTo(SimpleMetricsExportAutoConfiguration.class); - } - - /** - * Return a function that configures the run to be limited to the specified - * implementations. - * @param exportAutoConfigurations the export auto-configurations to include - * @return the function to apply - */ - public static > Function limitedTo( - Class... exportAutoConfigurations) { - return (contextRunner) -> apply(contextRunner, exportAutoConfigurations); - } - - @SuppressWarnings("unchecked") - private static > T apply(T contextRunner, - Class[] exportAutoConfigurations) { - for (Class configuration : exportAutoConfigurations) { - Assert.state(EXPORT_AUTO_CONFIGURATIONS.contains(configuration), - () -> "Unknown export auto-configuration " + configuration.getName()); - } - return (T) contextRunner.withPropertyValues("management.metrics.use-global-registry=false") - .withConfiguration(AUTO_CONFIGURATIONS) - .withConfiguration(AutoConfigurations.of(exportAutoConfigurations)); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/TestController.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/TestController.java deleted file mode 100644 index 54113b4c1a2a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/TestController.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.metrics.web; - -import io.micrometer.core.annotation.Timed; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Test controller used by metrics tests. - * - * @author Dmytro Nosan - * @author Stephane Nicoll - * @author Chanhyeong LEE - */ -@RestController -public class TestController { - - @GetMapping("test0") - public String test0() { - return "test0"; - } - - @GetMapping("test1") - public String test1() { - return "test1"; - } - - @GetMapping("test2") - public String test2() { - return "test2"; - } - - @Timed - @GetMapping("test3") - public String test3() { - return "test3"; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java deleted file mode 100644 index 768b0afa4334..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java +++ /dev/null @@ -1,689 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation; - -import java.util.ArrayList; -import java.util.List; - -import io.micrometer.common.KeyValue; -import io.micrometer.common.KeyValues; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; -import io.micrometer.core.instrument.observation.MeterObservationHandler; -import io.micrometer.core.instrument.search.MeterNotFoundException; -import io.micrometer.observation.GlobalObservationConvention; -import io.micrometer.observation.Observation; -import io.micrometer.observation.Observation.Context; -import io.micrometer.observation.ObservationFilter; -import io.micrometer.observation.ObservationHandler; -import io.micrometer.observation.ObservationHandler.AllMatchingCompositeObservationHandler; -import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; -import io.micrometer.observation.ObservationPredicate; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.observation.aop.ObservedAspect; -import io.micrometer.tracing.Tracer; -import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; -import io.micrometer.tracing.handler.TracingObservationHandler; -import org.aspectj.weaver.Advice; -import org.junit.jupiter.api.Test; -import org.mockito.Answers; - -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.annotation.Order; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ObservationAutoConfiguration}. - * - * @author Moritz Halbritter - * @author Jonatan Ivanov - * @author Vedran Pavic - */ -class ObservationAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withPropertyValues("management.observations.annotations.enabled=true") - .withClassLoader(new FilteredClassLoader("io.micrometer.tracing")) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class)); - - private final ApplicationContextRunner tracingContextRunner = new ApplicationContextRunner() - .with(MetricsRun.simple()) - .withPropertyValues("management.observations.annotations.enabled=true") - .withUserConfiguration(TracerConfiguration.class) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class)); - - @Test - void beansShouldNotBeSuppliedWhenMicrometerObservationIsNotOnClassPath() { - this.tracingContextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.observation")) - .run((context) -> { - assertThat(context).hasSingleBean(MeterRegistry.class); - assertThat(context).doesNotHaveBean(ObservationRegistry.class); - assertThat(context).doesNotHaveBean(ObservationHandler.class); - assertThat(context).doesNotHaveBean(ObservedAspect.class); - assertThat(context).doesNotHaveBean(ObservationHandlerGrouping.class); - }); - } - - @Test - void supplyObservationRegistryWhenMicrometerCoreAndTracingAreNotOnClassPath() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.core", "io.micrometer.tracing")) - .run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("test-observation", observationRegistry).stop(); - assertThat(context).doesNotHaveBean(ObservationHandler.class); - assertThat(context).hasSingleBean(ObservedAspect.class); - assertThat(context).doesNotHaveBean(ObservationHandlerGrouping.class); - }); - } - - @Test - void supplyMeterHandlerAndGroupingWhenMicrometerCoreIsOnClassPathButTracingIsNot() { - this.contextRunner.run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("test-observation", observationRegistry).stop(); - assertThat(context).hasSingleBean(ObservationHandler.class); - assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class); - assertThat(context).hasSingleBean(ObservedAspect.class); - assertThat(context).hasSingleBean(ObservationHandlerGrouping.class); - assertThat(context).hasBean("metricsObservationHandlerGrouping"); - }); - } - - @Test - void supplyOnlyTracingObservationHandlerGroupingWhenMicrometerCoreIsNotOnClassPathButTracingIs() { - this.tracingContextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.core")).run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("test-observation", observationRegistry).stop(); - assertThat(context).doesNotHaveBean(ObservationHandler.class); - assertThat(context).hasSingleBean(ObservedAspect.class); - assertThat(context).hasSingleBean(ObservationHandlerGrouping.class); - assertThat(context).hasBean("tracingObservationHandlerGrouping"); - }); - } - - @Test - void supplyMeterHandlerAndGroupingWhenMicrometerCoreAndTracingAreOnClassPath() { - this.tracingContextRunner.run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - // Intentionally not stopped since that will trigger additional logic in - // TracingAwareMeterObservationHandler that we don't test here - Observation.start("test-observation", observationRegistry); - assertThat(context).hasSingleBean(ObservationHandler.class); - assertThat(context).hasSingleBean(ObservedAspect.class); - assertThat(context).hasSingleBean(TracingAwareMeterObservationHandler.class); - assertThat(context).hasSingleBean(ObservationHandlerGrouping.class); - assertThat(context).hasBean("metricsAndTracingObservationHandlerGrouping"); - }); - } - - @Test - void supplyMeterHandlerAndGroupingWhenMicrometerCoreAndTracingAreOnClassPathButThereIsNoTracer() { - new ApplicationContextRunner().with(MetricsRun.simple()) - .withPropertyValues("management.observations.annotations.enabled=true") - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class)) - .run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("test-observation", observationRegistry).stop(); - assertThat(context).hasSingleBean(ObservationHandler.class); - assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class); - assertThat(context).hasSingleBean(ObservedAspect.class); - assertThat(context).hasSingleBean(ObservationHandlerGrouping.class); - assertThat(context).hasBean("metricsAndTracingObservationHandlerGrouping"); - }); - } - - @Test - void autoConfiguresDefaultMeterObservationHandler() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class); - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("test-observation", observationRegistry).stop(); - // When a DefaultMeterObservationHandler is registered, every stopped - // Observation leads to a timer - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.get("test-observation").timer().count()).isOne(); - assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class); - assertThat(context).hasSingleBean(ObservationHandler.class); - assertThat(context).hasSingleBean(ObservedAspect.class); - }); - } - - @Test - void allowsDefaultMeterObservationHandlerToBeDisabled() { - this.contextRunner.withClassLoader(new FilteredClassLoader(MeterRegistry.class)) - .run((context) -> assertThat(context).doesNotHaveBean(ObservationHandler.class)); - } - - @Test - void allowsObservedAspectToBeDisabled() { - this.contextRunner.withClassLoader(new FilteredClassLoader(Advice.class)) - .run((context) -> assertThat(context).doesNotHaveBean(ObservedAspect.class)); - } - - @Test - void allowsObservedAspectToBeDisabledWithProperty() { - this.contextRunner.withPropertyValues("management.observations.annotations.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(ObservedAspect.class)); - } - - @Test - void allowsObservedAspectToBeCustomized() { - this.contextRunner.withUserConfiguration(CustomObservedAspectConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ObservedAspect.class) - .getBean(ObservedAspect.class) - .isSameAs(context.getBean("customObservedAspect"))); - } - - @Test - void autoConfiguresObservationPredicates() { - this.contextRunner.withUserConfiguration(ObservationPredicates.class).run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - // This is allowed by ObservationPredicates.customPredicate - Observation.start("observation1", observationRegistry).stop(); - // This isn't allowed by ObservationPredicates.customPredicate - Observation.start("observation2", observationRegistry).stop(); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.get("observation1").timer().count()).isOne(); - assertThatExceptionOfType(MeterNotFoundException.class) - .isThrownBy(() -> meterRegistry.get("observation2").timer()); - }); - } - - @Test - void autoConfiguresObservationFilters() { - this.contextRunner.withUserConfiguration(ObservationFilters.class).run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("filtered", observationRegistry).stop(); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.get("filtered").tag("filter", "one").timer().count()).isOne(); - }); - } - - @Test - void shouldSupplyPropertiesObservationFilterBean() { - this.contextRunner - .run((context) -> assertThat(context).hasSingleBean(PropertiesObservationFilterPredicate.class)); - } - - @Test - void shouldApplyCommonKeyValuesToObservations() { - this.contextRunner.withPropertyValues("management.observations.key-values.a=alpha").run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("keyvalues", observationRegistry).stop(); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.get("keyvalues").tag("a", "alpha").timer().count()).isOne(); - }); - } - - @Test - void autoConfiguresGlobalObservationConventions() { - this.contextRunner.withUserConfiguration(CustomGlobalObservationConvention.class).run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Context micrometerContext = new Context(); - Observation.start("test-observation", () -> micrometerContext, observationRegistry).stop(); - assertThat(micrometerContext.getAllKeyValues()).containsExactly(KeyValue.of("key1", "value1")); - }); - } - - @Test - void autoConfiguresObservationHandlers() { - this.contextRunner.withUserConfiguration(ObservationHandlers.class).run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - List> handlers = context.getBean(CalledHandlers.class).getCalledHandlers(); - Observation.start("test-observation", observationRegistry).stop(); - assertThat(context).doesNotHaveBean(DefaultMeterObservationHandler.class); - assertThat(handlers).hasSize(2); - // Multiple MeterObservationHandler are wrapped in - // FirstMatchingCompositeObservationHandler, which calls only the first one - assertThat(handlers.get(0)).isInstanceOf(CustomMeterObservationHandler.class); - assertThat(((CustomMeterObservationHandler) handlers.get(0)).getName()) - .isEqualTo("customMeterObservationHandler1"); - // Regular handlers are registered last - assertThat(handlers.get(1)).isInstanceOf(CustomObservationHandler.class); - assertThat(context).doesNotHaveBean(DefaultMeterObservationHandler.class); - assertThat(context).doesNotHaveBean(TracingAwareMeterObservationHandler.class); - }); - } - - @Test - void autoConfiguresObservationHandlerWithCustomContext() { - this.contextRunner.withUserConfiguration(ObservationHandlerWithCustomContextConfiguration.class) - .run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - List> handlers = context.getBean(CalledHandlers.class).getCalledHandlers(); - CustomContext customContext = new CustomContext(); - Observation.start("test-observation", () -> customContext, observationRegistry).stop(); - assertThat(handlers).hasSize(1); - assertThat(handlers.get(0)).isInstanceOf(ObservationHandlerWithCustomContext.class); - assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class); - assertThat(context).doesNotHaveBean(TracingAwareMeterObservationHandler.class); - }); - } - - @Test - void autoConfiguresTracingAwareMeterObservationHandler() { - this.tracingContextRunner.withUserConfiguration(CustomTracingObservationHandlers.class).run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - List> handlers = context.getBean(CalledHandlers.class).getCalledHandlers(); - // Intentionally not stopped since that will trigger additional logic in - // TracingAwareMeterObservationHandler that we don't test here - Observation.start("test-observation", observationRegistry); - assertThat(handlers).hasSize(1); - assertThat(handlers.get(0)).isInstanceOf(CustomTracingObservationHandler.class); - assertThat(context).hasSingleBean(TracingAwareMeterObservationHandler.class); - assertThat(context.getBeansOfType(ObservationHandler.class)).hasSize(2); - }); - } - - @Test - void autoConfiguresObservationHandlerWhenTracingIsActive() { - this.tracingContextRunner.withUserConfiguration(ObservationHandlersTracing.class).run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - List> handlers = context.getBean(CalledHandlers.class).getCalledHandlers(); - Observation.start("test-observation", observationRegistry).stop(); - assertThat(handlers).hasSize(3); - // Multiple TracingObservationHandler are wrapped in - // FirstMatchingCompositeObservationHandler, which calls only the first one - assertThat(handlers.get(0)).isInstanceOf(CustomTracingObservationHandler.class); - assertThat(((CustomTracingObservationHandler) handlers.get(0)).getName()) - .isEqualTo("customTracingHandler1"); - // Multiple MeterObservationHandler are wrapped in - // FirstMatchingCompositeObservationHandler, which calls only the first one - assertThat(handlers.get(1)).isInstanceOf(CustomMeterObservationHandler.class); - assertThat(((CustomMeterObservationHandler) handlers.get(1)).getName()) - .isEqualTo("customMeterObservationHandler1"); - // Regular handlers are registered last - assertThat(handlers.get(2)).isInstanceOf(CustomObservationHandler.class); - assertThat(context).doesNotHaveBean(TracingAwareMeterObservationHandler.class); - assertThat(context).doesNotHaveBean(DefaultMeterObservationHandler.class); - }); - } - - @Test - void shouldNotDisableSpringSecurityObservationsByDefault() { - this.contextRunner.run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("spring.security.filterchains", observationRegistry).stop(); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.get("spring.security.filterchains").timer().count()).isOne(); - }); - } - - @Test - void shouldDisableSpringSecurityObservationsIfPropertyIsSet() { - this.contextRunner.withPropertyValues("management.observations.enable.spring.security=false").run((context) -> { - ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); - Observation.start("spring.security.filterchains", observationRegistry).stop(); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThatExceptionOfType(MeterNotFoundException.class) - .isThrownBy(() -> meterRegistry.get("spring.security.filterchains").timer()); - }); - } - - @Test - void shouldEnableLongTaskTimersByDefault() { - this.contextRunner.run((context) -> { - DefaultMeterObservationHandler handler = context.getBean(DefaultMeterObservationHandler.class); - assertThat(handler).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", true); - }); - } - - @Test - void shouldDisableLongTaskTimerIfPropertyIsSet() { - this.contextRunner.withPropertyValues("management.observations.long-task-timer.enabled=false") - .run((context) -> { - DefaultMeterObservationHandler handler = context.getBean(DefaultMeterObservationHandler.class); - assertThat(handler).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", false); - }); - } - - @Test - @SuppressWarnings("unchecked") - void shouldEnableLongTaskTimersForTracingByDefault() { - this.tracingContextRunner.run((context) -> { - TracingAwareMeterObservationHandler tracingHandler = context - .getBean(TracingAwareMeterObservationHandler.class); - Object delegate = ReflectionTestUtils.getField(tracingHandler, "delegate"); - assertThat(delegate).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", true); - }); - } - - @Test - @SuppressWarnings("unchecked") - void shouldDisableLongTaskTimerForTracingIfPropertyIsSet() { - this.tracingContextRunner.withPropertyValues("management.observations.long-task-timer.enabled=false") - .run((context) -> { - TracingAwareMeterObservationHandler tracingHandler = context - .getBean(TracingAwareMeterObservationHandler.class); - Object delegate = ReflectionTestUtils.getField(tracingHandler, "delegate"); - assertThat(delegate).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", false); - }); - } - - @Configuration(proxyBeanMethods = false) - static class ObservationPredicates { - - @Bean - ObservationPredicate customPredicate() { - return (s, context) -> s.equals("observation1"); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ObservationFilters { - - @Bean - @Order(1) - ObservationFilter observationFilterOne() { - return (context) -> context.addLowCardinalityKeyValue(KeyValue.of("filter", "one")); - } - - @Bean - @Order(0) - ObservationFilter observationFilterTwo() { - return (context) -> context.addLowCardinalityKeyValue(KeyValue.of("filter", "two")); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomObservedAspectConfiguration { - - @Bean - ObservedAspect customObservedAspect(ObservationRegistry observationRegistry) { - return new ObservedAspect(observationRegistry); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomGlobalObservationConvention { - - @Bean - GlobalObservationConvention customConvention() { - return new GlobalObservationConvention<>() { - @Override - public boolean supportsContext(Context context) { - return true; - } - - @Override - public KeyValues getLowCardinalityKeyValues(Context context) { - return KeyValues.of("key1", "value1"); - } - }; - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(CalledHandlersConfiguration.class) - static class ObservationHandlers { - - @Bean - @Order(4) - AllMatchingCompositeObservationHandler customAllMatchingCompositeObservationHandler() { - return new AllMatchingCompositeObservationHandler(); - } - - @Bean - @Order(3) - FirstMatchingCompositeObservationHandler customFirstMatchingCompositeObservationHandler() { - return new FirstMatchingCompositeObservationHandler(); - } - - @Bean - @Order(2) - ObservationHandler customObservationHandler(CalledHandlers calledHandlers) { - return new CustomObservationHandler(calledHandlers); - } - - @Bean - @Order(1) - MeterObservationHandler customMeterObservationHandler2(CalledHandlers calledHandlers) { - return new CustomMeterObservationHandler("customMeterObservationHandler2", calledHandlers); - } - - @Bean - @Order(0) - MeterObservationHandler customMeterObservationHandler1(CalledHandlers calledHandlers) { - return new CustomMeterObservationHandler("customMeterObservationHandler1", calledHandlers); - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(CalledHandlersConfiguration.class) - static class ObservationHandlerWithCustomContextConfiguration { - - @Bean - ObservationHandlerWithCustomContext observationHandlerWithCustomContext(CalledHandlers calledHandlers) { - return new ObservationHandlerWithCustomContext(calledHandlers); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TracerConfiguration { - - @Bean - Tracer tracer() { - return mock(Tracer.class); // simulating tracer configuration - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(CalledHandlersConfiguration.class) - static class CustomTracingObservationHandlers { - - @Bean - CustomTracingObservationHandler customTracingHandler1(CalledHandlers calledHandlers) { - return new CustomTracingObservationHandler("customTracingHandler1", calledHandlers); - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(CalledHandlersConfiguration.class) - static class ObservationHandlersTracing { - - @Bean - @Order(6) - CustomTracingObservationHandler customTracingHandler2(CalledHandlers calledHandlers) { - return new CustomTracingObservationHandler("customTracingHandler2", calledHandlers); - } - - @Bean - @Order(5) - CustomTracingObservationHandler customTracingHandler1(CalledHandlers calledHandlers) { - return new CustomTracingObservationHandler("customTracingHandler1", calledHandlers); - } - - @Bean - @Order(4) - AllMatchingCompositeObservationHandler customAllMatchingCompositeObservationHandler() { - return new AllMatchingCompositeObservationHandler(); - } - - @Bean - @Order(3) - FirstMatchingCompositeObservationHandler customFirstMatchingCompositeObservationHandler() { - return new FirstMatchingCompositeObservationHandler(); - } - - @Bean - @Order(2) - ObservationHandler customObservationHandler(CalledHandlers calledHandlers) { - return new CustomObservationHandler(calledHandlers); - } - - @Bean - @Order(1) - MeterObservationHandler customMeterObservationHandler2(CalledHandlers calledHandlers) { - return new CustomMeterObservationHandler("customMeterObservationHandler2", calledHandlers); - } - - @Bean - @Order(0) - MeterObservationHandler customMeterObservationHandler1(CalledHandlers calledHandlers) { - return new CustomMeterObservationHandler("customMeterObservationHandler1", calledHandlers); - } - - } - - private static class CustomTracingObservationHandler implements TracingObservationHandler { - - private final Tracer tracer = mock(Tracer.class, Answers.RETURNS_MOCKS); - - private final String name; - - private final CalledHandlers calledHandlers; - - CustomTracingObservationHandler(String name, CalledHandlers calledHandlers) { - this.name = name; - this.calledHandlers = calledHandlers; - } - - String getName() { - return this.name; - } - - @Override - public Tracer getTracer() { - return this.tracer; - } - - @Override - public void onStart(Context context) { - this.calledHandlers.onCalled(this); - } - - @Override - public boolean supportsContext(Context context) { - return true; - } - - } - - private static class ObservationHandlerWithCustomContext implements ObservationHandler { - - private final CalledHandlers calledHandlers; - - ObservationHandlerWithCustomContext(CalledHandlers calledHandlers) { - this.calledHandlers = calledHandlers; - } - - @Override - public void onStart(CustomContext context) { - this.calledHandlers.onCalled(this); - } - - @Override - public boolean supportsContext(Context context) { - return context instanceof CustomContext; - } - - } - - private static final class CustomContext extends Context { - - } - - private static final class CalledHandlers { - - private final List> calledHandlers = new ArrayList<>(); - - void onCalled(ObservationHandler handler) { - this.calledHandlers.add(handler); - } - - List> getCalledHandlers() { - return this.calledHandlers; - } - - } - - @Configuration(proxyBeanMethods = false) - static class CalledHandlersConfiguration { - - @Bean - CalledHandlers calledHandlers() { - return new CalledHandlers(); - } - - } - - private static class CustomObservationHandler implements ObservationHandler { - - private final CalledHandlers calledHandlers; - - CustomObservationHandler(CalledHandlers calledHandlers) { - this.calledHandlers = calledHandlers; - } - - @Override - public void onStart(Context context) { - this.calledHandlers.onCalled(this); - } - - @Override - public boolean supportsContext(Context context) { - return true; - } - - } - - private static class CustomMeterObservationHandler implements MeterObservationHandler { - - private final CalledHandlers calledHandlers; - - private final String name; - - CustomMeterObservationHandler(String name, CalledHandlers calledHandlers) { - this.name = name; - this.calledHandlers = calledHandlers; - } - - String getName() { - return this.name; - } - - @Override - public void onStart(Context context) { - this.calledHandlers.onCalled(this); - } - - @Override - public boolean supportsContext(Context context) { - return true; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGroupingTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGroupingTests.java deleted file mode 100644 index 5be5e1981bc7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationHandlerGroupingTests.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation; - -import java.lang.reflect.Method; -import java.util.List; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.Observation.Context; -import io.micrometer.observation.ObservationHandler; -import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; -import io.micrometer.observation.ObservationRegistry.ObservationConfig; -import org.junit.jupiter.api.Test; - -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ObservationHandlerGrouping}. - * - * @author Moritz Halbritter - */ -class ObservationHandlerGroupingTests { - - @Test - void shouldGroupCategoriesIntoFirstMatchingHandlerAndRespectCategoryOrder() { - ObservationHandlerGrouping grouping = new ObservationHandlerGrouping( - List.of(ObservationHandlerA.class, ObservationHandlerB.class)); - ObservationConfig config = new ObservationConfig(); - ObservationHandlerA handlerA1 = new ObservationHandlerA("a1"); - ObservationHandlerA handlerA2 = new ObservationHandlerA("a2"); - ObservationHandlerB handlerB1 = new ObservationHandlerB("b1"); - ObservationHandlerB handlerB2 = new ObservationHandlerB("b2"); - grouping.apply(List.of(handlerB1, handlerB2, handlerA1, handlerA2), config); - List> handlers = getObservationHandlers(config); - assertThat(handlers).hasSize(2); - // Category A is first - assertThat(handlers.get(0)).isInstanceOf(FirstMatchingCompositeObservationHandler.class); - FirstMatchingCompositeObservationHandler firstMatching0 = (FirstMatchingCompositeObservationHandler) handlers - .get(0); - assertThat(firstMatching0.getHandlers()).containsExactly(handlerA1, handlerA2); - // Category B is second - assertThat(handlers.get(1)).isInstanceOf(FirstMatchingCompositeObservationHandler.class); - FirstMatchingCompositeObservationHandler firstMatching1 = (FirstMatchingCompositeObservationHandler) handlers - .get(1); - assertThat(firstMatching1.getHandlers()).containsExactly(handlerB1, handlerB2); - } - - @Test - void uncategorizedHandlersShouldBeOrderedAfterCategories() { - ObservationHandlerGrouping grouping = new ObservationHandlerGrouping(ObservationHandlerA.class); - ObservationConfig config = new ObservationConfig(); - ObservationHandlerA handlerA1 = new ObservationHandlerA("a1"); - ObservationHandlerA handlerA2 = new ObservationHandlerA("a2"); - ObservationHandlerB handlerB1 = new ObservationHandlerB("b1"); - grouping.apply(List.of(handlerB1, handlerA1, handlerA2), config); - List> handlers = getObservationHandlers(config); - assertThat(handlers).hasSize(2); - // Category A is first - assertThat(handlers.get(0)).isInstanceOf(FirstMatchingCompositeObservationHandler.class); - FirstMatchingCompositeObservationHandler firstMatching0 = (FirstMatchingCompositeObservationHandler) handlers - .get(0); - // Uncategorized handlers follow - assertThat(firstMatching0.getHandlers()).containsExactly(handlerA1, handlerA2); - assertThat(handlers.get(1)).isEqualTo(handlerB1); - } - - @SuppressWarnings("unchecked") - private static List> getObservationHandlers(ObservationConfig config) { - Method method = ReflectionUtils.findMethod(ObservationConfig.class, "getObservationHandlers"); - ReflectionUtils.makeAccessible(method); - return (List>) ReflectionUtils.invokeMethod(method, config); - } - - private static class NamedObservationHandler implements ObservationHandler { - - private final String name; - - NamedObservationHandler(String name) { - this.name = name; - } - - @Override - public boolean supportsContext(Context context) { - return true; - } - - @Override - public String toString() { - return getClass().getSimpleName() + "{name='" + this.name + "'}"; - } - - } - - private static class ObservationHandlerA extends NamedObservationHandler { - - ObservationHandlerA(String name) { - super(name); - } - - } - - private static class ObservationHandlerB extends NamedObservationHandler { - - ObservationHandlerB(String name) { - super(name); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationTests.java deleted file mode 100644 index 98d99b3e1390..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationTests.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import io.micrometer.common.KeyValues; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.observation.tck.TestObservationRegistry; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.metrics.web.client.ObservationRestClientCustomizer; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.web.client.MockServerRestClientCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.observation.ClientRequestObservationContext; -import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.client.RestClient; -import org.springframework.web.client.RestClient.Builder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; - -/** - * Tests for {@link RestClientObservationConfiguration}. - * - * @author Brian Clozel - * @author Moritz Halbritter - */ -@ExtendWith(OutputCaptureExtension.class) -class RestClientObservationConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withBean(ObservationRegistry.class, TestObservationRegistry::create) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, RestClientAutoConfiguration.class, - HttpClientObservationsAutoConfiguration.class)); - - @Test - void contributesCustomizerBean() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ObservationRestClientCustomizer.class)); - } - - @Test - void restClientCreatedWithBuilderIsInstrumented() { - this.contextRunner.run((context) -> { - RestClient restClient = buildRestClient(context); - restClient.get().uri("/projects/{project}", "spring-boot").retrieve().toBodilessEntity(); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasObservationWithNameEqualToIgnoringCase("http.client.requests"); - }); - } - - @Test - void restClientCreatedWithBuilderUsesCustomConventionName() { - final String observationName = "test.metric.name"; - this.contextRunner.withPropertyValues("management.observations.http.client.requests.name=" + observationName) - .run((context) -> { - RestClient restClient = buildRestClient(context); - restClient.get().uri("/projects/{project}", "spring-boot").retrieve().toBodilessEntity(); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasObservationWithNameEqualToIgnoringCase(observationName); - }); - } - - @Test - void restClientCreatedWithBuilderUsesCustomConvention() { - this.contextRunner.withUserConfiguration(CustomConvention.class).run((context) -> { - RestClient restClient = buildRestClient(context); - restClient.get().uri("/projects/{project}", "spring-boot").retrieve().toBodilessEntity(); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasObservationWithNameEqualTo("http.client.requests") - .that() - .hasLowCardinalityKeyValue("project", "spring-boot"); - }); - } - - @Test - void afterMaxUrisReachedFurtherUrisAreDenied(CapturedOutput output) { - this.contextRunner.with(MetricsRun.simple()) - .withPropertyValues("management.metrics.web.client.max-uri-tags=2") - .run((context) -> { - RestClientWithMockServer restClientWithMockServer = buildRestClientAndMockServer(context); - MockRestServiceServer server = restClientWithMockServer.mockServer(); - RestClient restClient = restClientWithMockServer.restClient(); - for (int i = 0; i < 3; i++) { - server.expect(requestTo("/test/" + i)).andRespond(withStatus(HttpStatus.OK)); - } - for (int i = 0; i < 3; i++) { - restClient.get().uri("/test/" + i, String.class).retrieve().toBodilessEntity(); - } - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasNumberOfObservationsWithNameEqualTo("http.client.requests", 3); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(2); - assertThat(output).contains("Reached the maximum number of URI tags for 'http.client.requests'.") - .contains("Are you using 'uriVariables'?"); - }); - } - - @Test - void backsOffWhenRestClientBuilderIsMissing() { - new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, - HttpClientObservationsAutoConfiguration.class)) - .run((context) -> assertThat(context).doesNotHaveBean(ObservationRestClientCustomizer.class)); - } - - private RestClient buildRestClient(AssertableApplicationContext context) { - RestClientWithMockServer restClientWithMockServer = buildRestClientAndMockServer(context); - restClientWithMockServer.mockServer() - .expect(requestTo("/projects/spring-boot")) - .andRespond(withStatus(HttpStatus.OK)); - return restClientWithMockServer.restClient(); - } - - private RestClientWithMockServer buildRestClientAndMockServer(AssertableApplicationContext context) { - Builder builder = context.getBean(Builder.class); - MockServerRestClientCustomizer customizer = new MockServerRestClientCustomizer(); - customizer.customize(builder); - return new RestClientWithMockServer(builder.build(), customizer.getServer()); - } - - private record RestClientWithMockServer(RestClient restClient, MockRestServiceServer mockServer) { - } - - @Configuration(proxyBeanMethods = false) - static class CustomConventionConfiguration { - - @Bean - CustomConvention customConvention() { - return new CustomConvention(); - } - - } - - static class CustomConvention extends DefaultClientRequestObservationConvention { - - @Override - public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) { - return super.getLowCardinalityKeyValues(context).and("project", "spring-boot"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationWithoutMetricsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationWithoutMetricsTests.java deleted file mode 100644 index bb5b20845b8f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestClientObservationConfigurationWithoutMetricsTests.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.observation.tck.TestObservationRegistry; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.web.client.MockServerRestClientCustomizer; -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.http.HttpStatus; -import org.springframework.web.client.RestClient; -import org.springframework.web.client.RestClient.Builder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; - -/** - * Tests for {@link RestClientObservationConfiguration} without Micrometer Metrics. - * - * @author Brian Clozel - * @author Andy Wilkinson - * @author Moritz Halbritter - */ -@ExtendWith(OutputCaptureExtension.class) -@ClassPathExclusions("micrometer-core-*.jar") -class RestClientObservationConfigurationWithoutMetricsTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withBean(ObservationRegistry.class, TestObservationRegistry::create) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, RestClientAutoConfiguration.class, - HttpClientObservationsAutoConfiguration.class)); - - @Test - void restClientCreatedWithBuilderIsInstrumented() { - this.contextRunner.run((context) -> { - RestClient restClient = buildRestClient(context); - restClient.get().uri("/projects/{project}", "spring-boot").retrieve().toBodilessEntity(); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasObservationWithNameEqualToIgnoringCase("http.client.requests"); - }); - } - - private RestClient buildRestClient(AssertableApplicationContext context) { - Builder builder = context.getBean(Builder.class); - MockServerRestClientCustomizer customizer = new MockServerRestClientCustomizer(); - customizer.customize(builder); - customizer.getServer().expect(requestTo("/projects/spring-boot")).andRespond(withStatus(HttpStatus.OK)); - return builder.build(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationTests.java deleted file mode 100644 index 752147c54797..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationTests.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import io.micrometer.common.KeyValues; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.observation.tck.TestObservationRegistry; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.metrics.web.client.ObservationRestTemplateCustomizer; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.observation.ClientRequestObservationContext; -import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; - -/** - * Tests for {@link RestTemplateObservationConfiguration}. - * - * @author Brian Clozel - */ -@ExtendWith(OutputCaptureExtension.class) -class RestTemplateObservationConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withBean(ObservationRegistry.class, TestObservationRegistry::create) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, - RestTemplateAutoConfiguration.class, HttpClientObservationsAutoConfiguration.class)); - - @Test - void contributesCustomizerBean() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ObservationRestTemplateCustomizer.class)); - } - - @Test - void restTemplateCreatedWithBuilderIsInstrumented() { - this.contextRunner.run((context) -> { - RestTemplate restTemplate = buildRestTemplate(context); - restTemplate.getForEntity("/projects/{project}", Void.class, "spring-boot"); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasObservationWithNameEqualToIgnoringCase("http.client.requests"); - }); - } - - @Test - void restTemplateCreatedWithBuilderUsesCustomConventionName() { - final String observationName = "test.metric.name"; - this.contextRunner.withPropertyValues("management.observations.http.client.requests.name=" + observationName) - .run((context) -> { - RestTemplate restTemplate = buildRestTemplate(context); - restTemplate.getForEntity("/projects/{project}", Void.class, "spring-boot"); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasObservationWithNameEqualToIgnoringCase(observationName); - }); - } - - @Test - void restTemplateCreatedWithBuilderUsesCustomConvention() { - this.contextRunner.withUserConfiguration(CustomConvention.class).run((context) -> { - RestTemplate restTemplate = buildRestTemplate(context); - restTemplate.getForEntity("/projects/{project}", Void.class, "spring-boot"); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasObservationWithNameEqualTo("http.client.requests") - .that() - .hasLowCardinalityKeyValue("project", "spring-boot"); - }); - } - - @Test - void afterMaxUrisReachedFurtherUrisAreDenied(CapturedOutput output) { - this.contextRunner.with(MetricsRun.simple()) - .withPropertyValues("management.metrics.web.client.max-uri-tags=2") - .run((context) -> { - RestTemplate restTemplate = context.getBean(RestTemplateBuilder.class).build(); - MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate); - for (int i = 0; i < 3; i++) { - server.expect(requestTo("/test/" + i)).andRespond(withStatus(HttpStatus.OK)); - } - for (int i = 0; i < 3; i++) { - restTemplate.getForObject("/test/" + i, String.class); - } - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasNumberOfObservationsWithNameEqualTo("http.client.requests", 3); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(2); - assertThat(output).contains("Reached the maximum number of URI tags for 'http.client.requests'.") - .contains("Are you using 'uriVariables'?"); - }); - } - - @Test - void backsOffWhenRestTemplateBuilderIsMissing() { - new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, - HttpClientObservationsAutoConfiguration.class)) - .run((context) -> assertThat(context).doesNotHaveBean(ObservationRestTemplateCustomizer.class)); - } - - private RestTemplate buildRestTemplate(AssertableApplicationContext context) { - RestTemplate restTemplate = context.getBean(RestTemplateBuilder.class).build(); - MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate); - server.expect(requestTo("/projects/spring-boot")).andRespond(withStatus(HttpStatus.OK)); - return restTemplate; - } - - @Configuration(proxyBeanMethods = false) - static class CustomConventionConfiguration { - - @Bean - CustomConvention customConvention() { - return new CustomConvention(); - } - - } - - static class CustomConvention extends DefaultClientRequestObservationConvention { - - @Override - public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) { - return super.getLowCardinalityKeyValues(context).and("project", "spring-boot"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationWithoutMetricsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationWithoutMetricsTests.java deleted file mode 100644 index fff165f0c6d5..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/RestTemplateObservationConfigurationWithoutMetricsTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.observation.tck.TestObservationRegistry; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpStatus; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; - -/** - * Tests for {@link RestTemplateObservationConfiguration} without Micrometer Metrics. - * - * @author Brian Clozel - * @author Andy Wilkinson - */ -@ExtendWith(OutputCaptureExtension.class) -@ClassPathExclusions("micrometer-core-*.jar") -class RestTemplateObservationConfigurationWithoutMetricsTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withBean(ObservationRegistry.class, TestObservationRegistry::create) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, - RestTemplateAutoConfiguration.class, HttpClientObservationsAutoConfiguration.class)); - - @Test - void restTemplateCreatedWithBuilderIsInstrumented() { - this.contextRunner.run((context) -> { - RestTemplate restTemplate = buildRestTemplate(context); - restTemplate.getForEntity("/projects/{project}", Void.class, "spring-boot"); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - assertThat(registry).hasObservationWithNameEqualToIgnoringCase("http.client.requests"); - }); - } - - private RestTemplate buildRestTemplate(AssertableApplicationContext context) { - RestTemplate restTemplate = context.getBean(RestTemplateBuilder.class).build(); - MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate); - server.expect(requestTo("/projects/spring-boot")).andRespond(withStatus(HttpStatus.OK)); - return restTemplate; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfigurationTests.java deleted file mode 100644 index d2805aa7cc41..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/client/WebClientObservationConfigurationTests.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.observation.web.client; - -import java.time.Duration; - -import io.micrometer.common.KeyValues; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.observation.tck.TestObservationRegistry; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import reactor.core.publisher.Mono; - -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.metrics.web.reactive.client.ObservationWebClientCustomizer; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.reactive.ClientHttpConnector; -import org.springframework.mock.http.client.reactive.MockClientHttpResponse; -import org.springframework.web.reactive.function.client.ClientRequestObservationContext; -import org.springframework.web.reactive.function.client.DefaultClientRequestObservationConvention; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link WebClientObservationConfiguration} - * - * @author Brian Clozel - * @author Stephane Nicoll - */ -@ExtendWith(OutputCaptureExtension.class) -class WebClientObservationConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withBean(ObservationRegistry.class, TestObservationRegistry::create) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, WebClientAutoConfiguration.class, - HttpClientObservationsAutoConfiguration.class)); - - @Test - void contributesCustomizerBean() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ObservationWebClientCustomizer.class)); - } - - @Test - void webClientCreatedWithBuilderIsInstrumented() { - this.contextRunner.run((context) -> { - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - WebClient.Builder builder = context.getBean(WebClient.Builder.class); - validateWebClient(builder, registry); - }); - } - - @Test - void shouldUseCustomConventionIfAvailable() { - this.contextRunner.withUserConfiguration(CustomConvention.class).run((context) -> { - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - WebClient.Builder builder = context.getBean(WebClient.Builder.class); - WebClient webClient = mockWebClient(builder); - assertThat(registry).doesNotHaveAnyObservation(); - webClient.get() - .uri("https://example.org/projects/{project}", "spring-boot") - .retrieve() - .toBodilessEntity() - .block(Duration.ofSeconds(30)); - assertThat(registry).hasObservationWithNameEqualTo("http.client.requests") - .that() - .hasLowCardinalityKeyValue("project", "spring-boot"); - }); - } - - @Test - void afterMaxUrisReachedFurtherUrisAreDenied(CapturedOutput output) { - this.contextRunner.withPropertyValues("management.metrics.web.client.max-uri-tags=2").run((context) -> { - TestObservationRegistry registry = getInitializedRegistry(context); - assertThat(registry).hasNumberOfObservationsWithNameEqualTo("http.client.requests", 3); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(1); - // MeterFilter.maximumAllowableTags() works with prefix matching. - assertThat(meterRegistry.find("http.client.requests.active").longTaskTimers()).hasSize(1); - assertThat(output).contains("Reached the maximum number of URI tags for 'http.client.requests'.") - .contains("Are you using 'uriVariables'?"); - }); - } - - @Test - void shouldNotDenyNorLogIfMaxUrisIsNotReached(CapturedOutput output) { - this.contextRunner.withPropertyValues("management.metrics.web.client.max-uri-tags=5").run((context) -> { - TestObservationRegistry registry = getInitializedRegistry(context); - assertThat(registry).hasNumberOfObservationsWithNameEqualTo("http.client.requests", 3); - MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); - assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(3); - assertThat(output).doesNotContain("Reached the maximum number of URI tags for 'http.client.requests'.") - .doesNotContain("Are you using 'uriVariables'?"); - }); - } - - private TestObservationRegistry getInitializedRegistry(AssertableApplicationContext context) { - WebClient webClient = mockWebClient(context.getBean(WebClient.Builder.class)); - TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); - for (int i = 0; i < 3; i++) { - webClient.get() - .uri("https://example.org/projects/" + i) - .retrieve() - .toBodilessEntity() - .block(Duration.ofSeconds(30)); - } - return registry; - } - - private void validateWebClient(WebClient.Builder builder, TestObservationRegistry registry) { - WebClient webClient = mockWebClient(builder); - assertThat(registry).doesNotHaveAnyObservation(); - webClient.get() - .uri("https://example.org/projects/{project}", "spring-boot") - .retrieve() - .toBodilessEntity() - .block(Duration.ofSeconds(30)); - assertThat(registry).hasObservationWithNameEqualTo("http.client.requests") - .that() - .hasLowCardinalityKeyValue("uri", "/projects/{project}"); - } - - private WebClient mockWebClient(WebClient.Builder builder) { - ClientHttpConnector connector = mock(ClientHttpConnector.class); - given(connector.connect(any(), any(), any())).willReturn(Mono.just(new MockClientHttpResponse(HttpStatus.OK))); - return builder.clientConnector(connector).build(); - } - - @Configuration(proxyBeanMethods = false) - static class CustomConventionConfig { - - @Bean - CustomConvention customConvention() { - return new CustomConvention(); - } - - } - - static class CustomConvention extends DefaultClientRequestObservationConvention { - - @Override - public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) { - return super.getLowCardinalityKeyValues(context).and("project", "spring-boot"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfigurationTests.java deleted file mode 100644 index ad7c443c22e6..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfigurationTests.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.opentelemetry; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.metrics.SdkMeterProvider; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.context.annotation.ImportCandidates; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link OpenTelemetryAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class OpenTelemetryAutoConfigurationTests { - - private final ApplicationContextRunner runner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)); - - @Test - void isRegisteredInAutoConfigurationImports() { - assertThat(ImportCandidates.load(AutoConfiguration.class, null).getCandidates()) - .contains(OpenTelemetryAutoConfiguration.class.getName()); - } - - @Test - void shouldProvideBeans() { - this.runner.run((context) -> { - assertThat(context).hasSingleBean(OpenTelemetrySdk.class); - assertThat(context).hasSingleBean(Resource.class); - }); - } - - @Test - void shouldBackOffIfOpenTelemetryIsNotOnClasspath() { - this.runner.withClassLoader(new FilteredClassLoader("io.opentelemetry")).run((context) -> { - assertThat(context).doesNotHaveBean(OpenTelemetrySdk.class); - assertThat(context).doesNotHaveBean(Resource.class); - }); - } - - @Test - void backsOffOnUserSuppliedBeans() { - this.runner.withUserConfiguration(UserConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(OpenTelemetry.class); - assertThat(context).hasBean("customOpenTelemetry"); - assertThat(context).hasSingleBean(Resource.class); - assertThat(context).hasBean("customResource"); - }); - } - - @Test - void shouldApplySpringApplicationNameToResource() { - this.runner.withPropertyValues("spring.application.name=my-application").run((context) -> { - Resource resource = context.getBean(Resource.class); - assertThat(resource.getAttributes().asMap()) - .contains(entry(AttributeKey.stringKey("service.name"), "my-application")); - }); - } - - @Test - void shouldApplySpringApplicationGroupToResource() { - this.runner.withPropertyValues("spring.application.group=my-group").run((context) -> { - Resource resource = context.getBean(Resource.class); - assertThat(resource.getAttributes().asMap()) - .contains(entry(AttributeKey.stringKey("service.group"), "my-group")); - }); - } - - @Test - void shouldNotApplySpringApplicationGroupIfNotSet() { - this.runner.run((context) -> { - Resource resource = context.getBean(Resource.class); - assertThat(resource.getAttributes().asMap()).doesNotContainKey(AttributeKey.stringKey("service.group")); - }); - } - - @Test - void shouldApplyServiceNamespaceIfApplicationGroupIsSet() { - this.runner.withPropertyValues("spring.application.group=my-group").run((context) -> { - Resource resource = context.getBean(Resource.class); - assertThat(resource.getAttributes().asMap()).containsEntry(AttributeKey.stringKey("service.namespace"), - "my-group"); - }); - } - - @Test - void shouldNotApplyServiceNamespaceIfApplicationGroupIsNotSet() { - this.runner.run(((context) -> { - Resource resource = context.getBean(Resource.class); - assertThat(resource.getAttributes().asMap()).doesNotContainKey(AttributeKey.stringKey("service.namespace")); - })); - } - - @Test - void shouldFallbackToDefaultApplicationNameIfSpringApplicationNameIsNotSet() { - this.runner.run((context) -> { - Resource resource = context.getBean(Resource.class); - assertThat(resource.getAttributes().asMap()) - .contains(entry(AttributeKey.stringKey("service.name"), "unknown_service")); - }); - } - - @Test - void shouldApplyResourceAttributesFromProperties() { - this.runner.withPropertyValues("management.opentelemetry.resource-attributes.region=us-west").run((context) -> { - Resource resource = context.getBean(Resource.class); - assertThat(resource.getAttributes().asMap()).contains(entry(AttributeKey.stringKey("region"), "us-west")); - }); - } - - @Test - void shouldRegisterSdkTracerProviderIfAvailable() { - this.runner.withBean(SdkTracerProvider.class, () -> SdkTracerProvider.builder().build()).run((context) -> { - OpenTelemetry openTelemetry = context.getBean(OpenTelemetry.class); - assertThat(openTelemetry.getTracerProvider()).isNotNull(); - }); - } - - @Test - void shouldRegisterContextPropagatorsIfAvailable() { - this.runner.withBean(ContextPropagators.class, ContextPropagators::noop).run((context) -> { - OpenTelemetry openTelemetry = context.getBean(OpenTelemetry.class); - assertThat(openTelemetry.getPropagators()).isNotNull(); - }); - } - - @Test - void shouldRegisterSdkLoggerProviderIfAvailable() { - this.runner.withBean(SdkLoggerProvider.class, () -> SdkLoggerProvider.builder().build()).run((context) -> { - OpenTelemetry openTelemetry = context.getBean(OpenTelemetry.class); - assertThat(openTelemetry.getLogsBridge()).isNotNull(); - }); - } - - @Test - void shouldRegisterSdkMeterProviderIfAvailable() { - this.runner.withBean(SdkMeterProvider.class, () -> SdkMeterProvider.builder().build()).run((context) -> { - OpenTelemetry openTelemetry = context.getBean(OpenTelemetry.class); - assertThat(openTelemetry.getMeterProvider()).isNotNull(); - }); - } - - @Configuration(proxyBeanMethods = false) - static class UserConfiguration { - - @Bean - OpenTelemetry customOpenTelemetry() { - return mock(OpenTelemetry.class); - } - - @Bean - Resource customResource() { - return Resource.getDefault(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/sbom/SbomEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/sbom/SbomEndpointAutoConfigurationTests.java index 36086f2094ae..2d7dcce0e50b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/sbom/SbomEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/sbom/SbomEndpointAutoConfigurationTests.java @@ -42,15 +42,6 @@ void runWhenWebExposedShouldHaveEndpointBeanAndWebExtension() { .hasSingleBean(SbomEndpointWebExtension.class)); } - @Test - void runWhenCloudFoundryExposedShouldHaveEndpointBeanAndWebExtension() { - this.contextRunner - .withPropertyValues("management.endpoints.cloud-foundry.exposure.include=sbom", - "spring.main.cloud-platform=cloud_foundry") - .run((context) -> assertThat(context).hasSingleBean(SbomEndpoint.class) - .hasSingleBean(SbomEndpointWebExtension.class)); - } - @Test void runWhenNotExposedShouldNotHaveEndpointBean() { this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(SbomEndpoint.class)); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfigurationTests.java deleted file mode 100644 index 2220f2753373..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfigurationTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.scheduling; - -import java.util.List; - -import io.micrometer.observation.ObservationRegistry; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.scheduling.ScheduledTasksObservabilityAutoConfiguration.ObservabilitySchedulingConfigurer; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.context.annotation.ImportCandidates; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.scheduling.config.ScheduledTaskRegistrar; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ScheduledTasksObservabilityAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class ScheduledTasksObservabilityAutoConfigurationTests { - - private final ApplicationContextRunner runner = new ApplicationContextRunner().withConfiguration(AutoConfigurations - .of(ObservationAutoConfiguration.class, ScheduledTasksObservabilityAutoConfiguration.class)); - - @Test - void shouldProvideObservabilitySchedulingConfigurer() { - this.runner.run((context) -> assertThat(context).hasSingleBean(ObservabilitySchedulingConfigurer.class)); - } - - @Test - void observabilitySchedulingConfigurerShouldConfigureObservationRegistry() { - ObservationRegistry observationRegistry = ObservationRegistry.create(); - ObservabilitySchedulingConfigurer configurer = new ObservabilitySchedulingConfigurer(observationRegistry); - ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar(); - configurer.configureTasks(registrar); - assertThat(registrar.getObservationRegistry()).isEqualTo(observationRegistry); - } - - @Test - void isRegisteredInAutoConfigurationsFile() { - List configurations = ImportCandidates.load(AutoConfiguration.class, null).getCandidates(); - assertThat(configurations).contains(ScheduledTasksObservabilityAutoConfiguration.class.getName()); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestTests.java deleted file mode 100644 index 721e576da967..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestTests.java +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.security.reactive; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.assertj.core.api.AssertDelegateTarget; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.boot.actuate.endpoint.ExposableEndpoint; -import org.springframework.boot.actuate.endpoint.Operation; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoint; -import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; -import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.boot.web.server.WebServer; -import org.springframework.context.support.StaticApplicationContext; -import org.springframework.http.HttpMethod; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerHttpResponse; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; -import org.springframework.web.context.support.StaticWebApplicationContext; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebHandler; -import org.springframework.web.server.adapter.HttpWebHandlerAdapter; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link EndpointRequest}. - * - * @author Madhura Bhave - * @author Phillip Webb - * @author Chris Bono - */ -class EndpointRequestTests { - - @Test - void toAnyEndpointShouldMatchEndpointPath() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher).matches("/actuator/foo"); - assertMatcher(matcher).matches("/actuator/bar"); - assertMatcher(matcher).matches("/actuator"); - } - - @Test - void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().withHttpMethod(HttpMethod.POST); - assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/foo"); - assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo"); - } - - @Test - void toAnyEndpointShouldMatchEndpointPathWithTrailingSlash() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher).matches("/actuator/foo/"); - assertMatcher(matcher).matches("/actuator/bar/"); - assertMatcher(matcher).matches("/actuator/"); - } - - @Test - void toAnyEndpointWhenBasePathIsEmptyShouldNotMatchLinks() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); - assertMatcher.doesNotMatch("/"); - assertMatcher.matches("/foo"); - assertMatcher.matches("/bar"); - } - - @Test - void toAnyEndpointShouldNotMatchOtherPath() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher).doesNotMatch("/actuator/baz"); - } - - @Test - void toEndpointClassShouldMatchEndpointPath() { - ServerWebExchangeMatcher matcher = EndpointRequest.to(FooEndpoint.class); - assertMatcher(matcher).matches("/actuator/foo"); - assertMatcher(matcher).matches("/actuator/foo/"); - } - - @Test - void toEndpointClassShouldNotMatchOtherPath() { - ServerWebExchangeMatcher matcher = EndpointRequest.to(FooEndpoint.class); - assertMatcher(matcher).doesNotMatch("/actuator/bar"); - assertMatcher(matcher).doesNotMatch("/actuator/bar/"); - } - - @Test - void toEndpointIdShouldMatchEndpointPath() { - ServerWebExchangeMatcher matcher = EndpointRequest.to("foo"); - assertMatcher(matcher).matches("/actuator/foo"); - assertMatcher(matcher).matches("/actuator/foo/"); - } - - @Test - void toEndpointIdShouldNotMatchOtherPath() { - ServerWebExchangeMatcher matcher = EndpointRequest.to("foo"); - assertMatcher(matcher).doesNotMatch("/actuator/bar"); - assertMatcher(matcher).doesNotMatch("/actuator/bar/"); - } - - @Test - void toLinksShouldOnlyMatchLinks() { - ServerWebExchangeMatcher matcher = EndpointRequest.toLinks(); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); - assertMatcher(matcher).doesNotMatch("/actuator/bar"); - assertMatcher(matcher).matches("/actuator"); - assertMatcher(matcher).matches("/actuator/"); - } - - @Test - void toLinksWhenBasePathEmptyShouldNotMatch() { - ServerWebExchangeMatcher matcher = EndpointRequest.toLinks(); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); - assertMatcher.doesNotMatch("/actuator/foo"); - assertMatcher.doesNotMatch("/actuator/bar"); - assertMatcher.doesNotMatch("/"); - } - - @Test - void excludeByClassShouldNotMatchExcluded() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint() - .excluding(FooEndpoint.class, BazServletEndpoint.class); - List> endpoints = new ArrayList<>(); - endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo")); - endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar")); - endpoints.add(mockEndpoint(EndpointId.of("baz"), "baz")); - PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator", () -> endpoints); - assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo"); - assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo/"); - assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz"); - assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz/"); - assertMatcher(matcher).matches("/actuator/bar"); - assertMatcher(matcher).matches("/actuator/bar/"); - assertMatcher(matcher).matches("/actuator"); - assertMatcher(matcher).matches("/actuator/"); - } - - @Test - void excludeByClassShouldNotMatchLinksIfExcluded() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint() - .excludingLinks() - .excluding(FooEndpoint.class); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); - assertMatcher(matcher).doesNotMatch("/actuator/foo/"); - assertMatcher(matcher).doesNotMatch("/actuator"); - assertMatcher(matcher).doesNotMatch("/actuator/"); - } - - @Test - void excludeByIdShouldNotMatchExcluded() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("foo"); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); - assertMatcher(matcher).doesNotMatch("/actuator/foo/"); - assertMatcher(matcher).matches("/actuator/bar"); - assertMatcher(matcher).matches("/actuator/bar/"); - assertMatcher(matcher).matches("/actuator"); - assertMatcher(matcher).matches("/actuator/"); - } - - @Test - void excludeByIdShouldNotMatchLinksIfExcluded() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks().excluding("foo"); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); - assertMatcher(matcher).doesNotMatch("/actuator/foo/"); - assertMatcher(matcher).doesNotMatch("/actuator"); - assertMatcher(matcher).doesNotMatch("/actuator/"); - } - - @Test - void excludeLinksShouldNotMatchBasePath() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks(); - assertMatcher(matcher).doesNotMatch("/actuator"); - assertMatcher(matcher).doesNotMatch("/actuator/"); - assertMatcher(matcher).matches("/actuator/foo"); - assertMatcher(matcher).matches("/actuator/foo/"); - assertMatcher(matcher).matches("/actuator/bar"); - assertMatcher(matcher).matches("/actuator/bar/"); - } - - @Test - void excludeLinksShouldNotMatchBasePathIfEmptyAndExcluded() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks(); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); - assertMatcher.doesNotMatch("/"); - assertMatcher.matches("/foo"); - assertMatcher.matches("/foo/"); - assertMatcher.matches("/bar"); - assertMatcher.matches("/bar/"); - } - - @Test - void noEndpointPathsBeansShouldNeverMatch() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/foo"); - assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/foo/"); - assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/bar"); - assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/bar/"); - } - - @Test - void toStringWhenIncludedEndpoints() { - ServerWebExchangeMatcher matcher = EndpointRequest.to("foo", "bar"); - assertThat(matcher).hasToString("EndpointRequestMatcher includes=[foo, bar], excludes=[], includeLinks=false"); - } - - @Test - void toStringWhenEmptyIncludedEndpoints() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertThat(matcher).hasToString("EndpointRequestMatcher includes=[*], excludes=[], includeLinks=true"); - } - - @Test - void toStringWhenIncludedEndpointsClasses() { - ServerWebExchangeMatcher matcher = EndpointRequest.to(FooEndpoint.class).excluding("bar"); - assertThat(matcher).hasToString("EndpointRequestMatcher includes=[foo], excludes=[bar], includeLinks=false"); - } - - @Test - void toStringWhenIncludedExcludedEndpoints() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("bar").excludingLinks(); - assertThat(matcher).hasToString("EndpointRequestMatcher includes=[*], excludes=[bar], includeLinks=false"); - } - - @Test - void toStringWhenToAdditionalPaths() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "test"); - assertThat(matcher) - .hasToString("AdditionalPathsEndpointServerWebExchangeMatcher endpoints=[test], webServerNamespace=server"); - } - - @Test - void toAnyEndpointWhenEndpointPathMappedToRootIsExcludedShouldNotMatchRoot() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("root"); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("/", () -> List - .of(mockEndpoint(EndpointId.of("root"), "/"), mockEndpoint(EndpointId.of("alpha"), "alpha")))); - assertMatcher.doesNotMatch("/"); - assertMatcher.matches("/alpha"); - assertMatcher.matches("/alpha/sub"); - } - - @Test - void toEndpointWhenEndpointPathMappedToRootShouldMatchRoot() { - ServerWebExchangeMatcher matcher = EndpointRequest.to("root"); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, - new PathMappedEndpoints("/", () -> List.of(mockEndpoint(EndpointId.of("root"), "/")))); - assertMatcher.matches("/"); - } - - @Test - void toAdditionalPathsWithEndpointClassShouldMatchAdditionalPath() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, - FooEndpoint.class); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", - () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); - assertMatcher.matches("/additional"); - } - - @Test - void toAdditionalPathsWithEndpointIdShouldMatchAdditionalPath() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "foo"); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", - () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); - assertMatcher.matches("/additional"); - } - - @Test - void toAdditionalPathsWithEndpointClassShouldNotMatchOtherPaths() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, - FooEndpoint.class); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", - () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); - assertMatcher.doesNotMatch("/foo"); - assertMatcher.doesNotMatch("/bar"); - } - - @Test - void toAdditionalPathsWithEndpointClassShouldNotMatchOtherNamespace() { - ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, - FooEndpoint.class); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", - () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional"))), - WebServerNamespace.MANAGEMENT); - assertMatcher.doesNotMatch("/additional"); - } - - private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher) { - return assertMatcher(matcher, mockPathMappedEndpoints("/actuator")); - } - - private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, String basePath) { - return assertMatcher(matcher, mockPathMappedEndpoints(basePath)); - } - - private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, - PathMappedEndpoints pathMappedEndpoints) { - return assertMatcher(matcher, pathMappedEndpoints, null); - } - - private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, - PathMappedEndpoints pathMappedEndpoints, WebServerNamespace namespace) { - StaticApplicationContext context = new StaticApplicationContext(); - if (namespace != null && !WebServerNamespace.SERVER.equals(namespace)) { - NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); - context.setParent(parentContext); - } - context.registerBean(WebEndpointProperties.class); - if (pathMappedEndpoints != null) { - context.registerBean(PathMappedEndpoints.class, () -> pathMappedEndpoints); - WebEndpointProperties properties = context.getBean(WebEndpointProperties.class); - if (!properties.getBasePath().equals(pathMappedEndpoints.getBasePath())) { - properties.setBasePath(pathMappedEndpoints.getBasePath()); - } - } - return assertThat(new RequestMatcherAssert(context, matcher)); - } - - private PathMappedEndpoints mockPathMappedEndpoints(String basePath) { - List> endpoints = new ArrayList<>(); - endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo")); - endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar")); - return new PathMappedEndpoints(basePath, () -> endpoints); - } - - private TestEndpoint mockEndpoint(EndpointId id, String rootPath) { - return mockEndpoint(id, rootPath, WebServerNamespace.SERVER); - } - - private TestEndpoint mockEndpoint(EndpointId id, String rootPath, WebServerNamespace webServerNamespace, - String... additionalPaths) { - TestEndpoint endpoint = mock(TestEndpoint.class); - given(endpoint.getEndpointId()).willReturn(id); - given(endpoint.getRootPath()).willReturn(rootPath); - given(endpoint.getAdditionalPaths(webServerNamespace)).willReturn(Arrays.asList(additionalPaths)); - return endpoint; - } - - static class NamedStaticWebApplicationContext extends StaticWebApplicationContext - implements WebServerApplicationContext { - - private final WebServerNamespace webServerNamespace; - - NamedStaticWebApplicationContext(WebServerNamespace webServerNamespace) { - this.webServerNamespace = webServerNamespace; - } - - @Override - public WebServer getWebServer() { - return null; - } - - @Override - public String getServerNamespace() { - return (this.webServerNamespace != null) ? this.webServerNamespace.getValue() : null; - } - - } - - static class RequestMatcherAssert implements AssertDelegateTarget { - - private final StaticApplicationContext context; - - private final ServerWebExchangeMatcher matcher; - - RequestMatcherAssert(StaticApplicationContext context, ServerWebExchangeMatcher matcher) { - this.context = context; - this.matcher = matcher; - } - - void matches(String path) { - ServerWebExchange exchange = webHandler().createExchange(MockServerHttpRequest.get(path).build(), - new MockServerHttpResponse()); - matches(exchange); - } - - void matches(HttpMethod httpMethod, String path) { - ServerWebExchange exchange = webHandler() - .createExchange(MockServerHttpRequest.method(httpMethod, path).build(), new MockServerHttpResponse()); - matches(exchange); - } - - private void matches(ServerWebExchange exchange) { - assertThat(this.matcher.matches(exchange).block(Duration.ofSeconds(30)).isMatch()) - .as("Matches " + getRequestPath(exchange)) - .isTrue(); - } - - void doesNotMatch(String path) { - ServerWebExchange exchange = webHandler().createExchange(MockServerHttpRequest.get(path).build(), - new MockServerHttpResponse()); - doesNotMatch(exchange); - } - - void doesNotMatch(HttpMethod httpMethod, String path) { - ServerWebExchange exchange = webHandler() - .createExchange(MockServerHttpRequest.method(httpMethod, path).build(), new MockServerHttpResponse()); - doesNotMatch(exchange); - } - - private void doesNotMatch(ServerWebExchange exchange) { - assertThat(this.matcher.matches(exchange).block(Duration.ofSeconds(30)).isMatch()) - .as("Does not match " + getRequestPath(exchange)) - .isFalse(); - } - - private TestHttpWebHandlerAdapter webHandler() { - TestHttpWebHandlerAdapter adapter = new TestHttpWebHandlerAdapter(mock(WebHandler.class)); - adapter.setApplicationContext(this.context); - return adapter; - } - - private String getRequestPath(ServerWebExchange exchange) { - return exchange.getRequest().getPath().toString(); - } - - } - - static class TestHttpWebHandlerAdapter extends HttpWebHandlerAdapter { - - TestHttpWebHandlerAdapter(WebHandler delegate) { - super(delegate); - } - - @Override - protected ServerWebExchange createExchange(ServerHttpRequest request, ServerHttpResponse response) { - return super.createExchange(request, response); - } - - } - - @Endpoint(id = "foo") - static class FooEndpoint { - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "baz") - @SuppressWarnings("removal") - static class BazServletEndpoint { - - } - - interface TestEndpoint extends ExposableEndpoint, PathMappedEndpoint { - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java deleted file mode 100644 index 0a16d3cade70..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.security.servlet; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import jakarta.servlet.http.HttpServletRequest; -import org.assertj.core.api.AssertDelegateTarget; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest.AdditionalPathsEndpointRequestMatcher; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest.EndpointRequestMatcher; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.boot.actuate.endpoint.ExposableEndpoint; -import org.springframework.boot.actuate.endpoint.Operation; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoint; -import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; -import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.boot.web.server.WebServer; -import org.springframework.http.HttpMethod; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockServletContext; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.StaticWebApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link EndpointRequest}. - * - * @author Phillip Webb - * @author Madhura Bhave - * @author Chris Bono - */ -class EndpointRequestTests { - - @Test - void toAnyEndpointShouldMatchEndpointPath() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher, "/actuator").matches("/actuator/foo"); - assertMatcher(matcher, "/actuator").matches("/actuator/foo/zoo/"); - assertMatcher(matcher, "/actuator").matches("/actuator/bar"); - assertMatcher(matcher, "/actuator").matches("/actuator/bar/baz"); - assertMatcher(matcher, "/actuator").matches("/actuator"); - } - - @Test - void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() { - EndpointRequest.EndpointRequestMatcher matcher = EndpointRequest.toAnyEndpoint() - .withHttpMethod(HttpMethod.POST); - assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/foo"); - assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo"); - } - - @Test - void toAnyEndpointShouldMatchEndpointPathWithTrailingSlash() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher, "/actuator").matches("/actuator/foo/"); - assertMatcher(matcher, "/actuator").matches("/actuator/bar/"); - assertMatcher(matcher, "/actuator").matches("/actuator/"); - } - - @Test - void toAnyEndpointWhenBasePathIsEmptyShouldNotMatchLinks() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); - assertMatcher.doesNotMatch("/"); - assertMatcher.matches("/foo"); - assertMatcher.matches("/bar"); - } - - @Test - void toAnyEndpointShouldNotMatchOtherPath() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher).doesNotMatch("/actuator/baz"); - } - - @Test - void toAnyEndpointWhenDispatcherServletPathProviderNotAvailableUsesEmptyPath() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher, "/actuator").matches("/actuator/foo"); - assertMatcher(matcher, "/actuator").matches("/actuator/bar"); - assertMatcher(matcher, "/actuator").matches("/actuator"); - assertMatcher(matcher, "/actuator").doesNotMatch("/actuator/baz"); - } - - @Test - void toEndpointClassShouldMatchEndpointPath() { - RequestMatcher matcher = EndpointRequest.to(FooEndpoint.class); - assertMatcher(matcher).matches("/actuator/foo"); - } - - @Test - void toEndpointClassShouldNotMatchOtherPath() { - RequestMatcher matcher = EndpointRequest.to(FooEndpoint.class); - assertMatcher(matcher).doesNotMatch("/actuator/bar"); - assertMatcher(matcher).doesNotMatch("/actuator"); - } - - @Test - void toEndpointIdShouldMatchEndpointPath() { - RequestMatcher matcher = EndpointRequest.to("foo"); - assertMatcher(matcher).matches("/actuator/foo"); - } - - @Test - void toEndpointIdShouldNotMatchOtherPath() { - RequestMatcher matcher = EndpointRequest.to("foo"); - assertMatcher(matcher).doesNotMatch("/actuator/bar"); - assertMatcher(matcher).doesNotMatch("/actuator"); - } - - @Test - void toLinksShouldOnlyMatchLinks() { - RequestMatcher matcher = EndpointRequest.toLinks(); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); - assertMatcher(matcher).doesNotMatch("/actuator/bar"); - assertMatcher(matcher).matches("/actuator"); - assertMatcher(matcher).matches("/actuator/"); - } - - @Test - void toLinksWhenBasePathEmptyShouldNotMatch() { - RequestMatcher matcher = EndpointRequest.toLinks(); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); - assertMatcher.doesNotMatch("/actuator/foo"); - assertMatcher.doesNotMatch("/actuator/bar"); - assertMatcher.doesNotMatch("/"); - } - - @Test - void excludeByClassShouldNotMatchExcluded() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding(FooEndpoint.class, BazServletEndpoint.class); - List> endpoints = new ArrayList<>(); - endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo")); - endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar")); - endpoints.add(mockEndpoint(EndpointId.of("baz"), "baz")); - PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator", () -> endpoints); - assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo"); - assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz"); - assertMatcher(matcher).matches("/actuator/bar"); - assertMatcher(matcher).matches("/actuator"); - } - - @Test - void excludeByClassShouldNotMatchLinksIfExcluded() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks().excluding(FooEndpoint.class); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); - assertMatcher(matcher).doesNotMatch("/actuator"); - } - - @Test - void excludeByIdShouldNotMatchExcluded() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("foo"); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); - assertMatcher(matcher).matches("/actuator/bar"); - assertMatcher(matcher).matches("/actuator"); - } - - @Test - void excludeByIdShouldNotMatchLinksIfExcluded() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks().excluding("foo"); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); - assertMatcher(matcher).doesNotMatch("/actuator"); - } - - @Test - void excludeLinksShouldNotMatchBasePath() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks(); - assertMatcher(matcher).doesNotMatch("/actuator"); - assertMatcher(matcher).matches("/actuator/foo"); - assertMatcher(matcher).matches("/actuator/bar"); - } - - @Test - void excludeLinksShouldNotMatchBasePathIfEmptyAndExcluded() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks(); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); - assertMatcher.doesNotMatch("/"); - assertMatcher.matches("/foo"); - assertMatcher.matches("/bar"); - } - - @Test - void endpointRequestMatcherShouldUseCustomRequestMatcherProvider() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); - RequestMatcher mockRequestMatcher = (request) -> false; - RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), - (pattern, method) -> mockRequestMatcher, null); - assertMatcher.doesNotMatch("/foo"); - assertMatcher.doesNotMatch("/bar"); - } - - @Test - void linksRequestMatcherShouldUseCustomRequestMatcherProvider() { - RequestMatcher matcher = EndpointRequest.toLinks(); - RequestMatcher mockRequestMatcher = (request) -> false; - RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints("/actuator"), - (pattern, method) -> mockRequestMatcher, null); - assertMatcher.doesNotMatch("/actuator"); - } - - @Test - void noEndpointPathsBeansShouldNeverMatch() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/foo"); - assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/bar"); - } - - @Test - void toStringWhenIncludedEndpoints() { - RequestMatcher matcher = EndpointRequest.to("foo", "bar"); - assertThat(matcher).hasToString("EndpointRequestMatcher includes=[foo, bar], excludes=[], includeLinks=false"); - } - - @Test - void toStringWhenEmptyIncludedEndpoints() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); - assertThat(matcher).hasToString("EndpointRequestMatcher includes=[*], excludes=[], includeLinks=true"); - } - - @Test - void toStringWhenIncludedEndpointsClasses() { - RequestMatcher matcher = EndpointRequest.to(FooEndpoint.class).excluding("bar"); - assertThat(matcher).hasToString("EndpointRequestMatcher includes=[foo], excludes=[bar], includeLinks=false"); - } - - @Test - void toStringWhenIncludedExcludedEndpoints() { - RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("bar").excludingLinks(); - assertThat(matcher).hasToString("EndpointRequestMatcher includes=[*], excludes=[bar], includeLinks=false"); - } - - @Test - void toStringWhenToAdditionalPaths() { - RequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "test"); - assertThat(matcher) - .hasToString("AdditionalPathsEndpointRequestMatcher endpoints=[test], webServerNamespace=server"); - } - - @Test - void toAnyEndpointWhenEndpointPathMappedToRootIsExcludedShouldNotMatchRoot() { - EndpointRequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("root"); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", () -> List - .of(mockEndpoint(EndpointId.of("root"), "/"), mockEndpoint(EndpointId.of("alpha"), "alpha")))); - assertMatcher.doesNotMatch("/"); - assertMatcher.matches("/alpha"); - assertMatcher.matches("/alpha/sub"); - } - - @Test - void toEndpointWhenEndpointPathMappedToRootShouldMatchRoot() { - EndpointRequestMatcher matcher = EndpointRequest.to("root"); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, - new PathMappedEndpoints("", () -> List.of(mockEndpoint(EndpointId.of("root"), "/")))); - assertMatcher.matches("/"); - } - - @Test - void toAdditionalPathsWithEndpointClassShouldMatchAdditionalPath() { - AdditionalPathsEndpointRequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, - FooEndpoint.class); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", - () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); - assertMatcher.matches("/additional"); - } - - @Test - void toAdditionalPathsWithEndpointIdShouldMatchAdditionalPath() { - AdditionalPathsEndpointRequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, - "foo"); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", - () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); - assertMatcher.matches("/additional"); - } - - @Test - void toAdditionalPathsWithEndpointClassShouldNotMatchOtherPaths() { - AdditionalPathsEndpointRequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, - FooEndpoint.class); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", - () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); - assertMatcher.doesNotMatch("/foo"); - assertMatcher.doesNotMatch("/bar"); - } - - @Test - void toAdditionalPathsWithEndpointClassShouldNotMatchOtherNamespace() { - AdditionalPathsEndpointRequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, - FooEndpoint.class); - RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", - () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional"))), - null, WebServerNamespace.MANAGEMENT); - assertMatcher.doesNotMatch("/additional"); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher) { - return assertMatcher(matcher, mockPathMappedEndpoints("/actuator")); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String basePath) { - return assertMatcher(matcher, mockPathMappedEndpoints(basePath), null, null); - } - - private PathMappedEndpoints mockPathMappedEndpoints(String basePath) { - List> endpoints = new ArrayList<>(); - endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo")); - endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar")); - return new PathMappedEndpoints(basePath, () -> endpoints); - } - - private TestEndpoint mockEndpoint(EndpointId id, String rootPath) { - return mockEndpoint(id, rootPath, WebServerNamespace.SERVER); - } - - private TestEndpoint mockEndpoint(EndpointId id, String rootPath, WebServerNamespace webServerNamespace, - String... additionalPaths) { - TestEndpoint endpoint = mock(TestEndpoint.class); - given(endpoint.getEndpointId()).willReturn(id); - given(endpoint.getRootPath()).willReturn(rootPath); - given(endpoint.getAdditionalPaths(webServerNamespace)).willReturn(Arrays.asList(additionalPaths)); - return endpoint; - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher, PathMappedEndpoints pathMappedEndpoints) { - return assertMatcher(matcher, pathMappedEndpoints, null, null); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher, PathMappedEndpoints pathMappedEndpoints, - RequestMatcherProvider matcherProvider, WebServerNamespace namespace) { - StaticWebApplicationContext context = new StaticWebApplicationContext(); - if (namespace != null && !WebServerNamespace.SERVER.equals(namespace)) { - NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); - context.setParent(parentContext); - } - context.registerBean(WebEndpointProperties.class); - if (pathMappedEndpoints != null) { - context.registerBean(PathMappedEndpoints.class, () -> pathMappedEndpoints); - WebEndpointProperties properties = context.getBean(WebEndpointProperties.class); - if (!properties.getBasePath().equals(pathMappedEndpoints.getBasePath())) { - properties.setBasePath(pathMappedEndpoints.getBasePath()); - } - } - if (matcherProvider != null) { - context.registerBean(RequestMatcherProvider.class, () -> matcherProvider); - } - return assertThat(new RequestMatcherAssert(context, matcher)); - } - - static class NamedStaticWebApplicationContext extends StaticWebApplicationContext - implements WebServerApplicationContext { - - private final WebServerNamespace webServerNamespace; - - NamedStaticWebApplicationContext(WebServerNamespace webServerNamespace) { - this.webServerNamespace = webServerNamespace; - } - - @Override - public WebServer getWebServer() { - return null; - } - - @Override - public String getServerNamespace() { - return (this.webServerNamespace != null) ? this.webServerNamespace.getValue() : null; - } - - } - - static class RequestMatcherAssert implements AssertDelegateTarget { - - private final WebApplicationContext context; - - private final RequestMatcher matcher; - - RequestMatcherAssert(WebApplicationContext context, RequestMatcher matcher) { - this.context = context; - this.matcher = matcher; - } - - void matches(String servletPath) { - matches(mockRequest(null, servletPath)); - } - - void matches(HttpMethod httpMethod, String servletPath) { - matches(mockRequest(httpMethod, servletPath)); - } - - private void matches(HttpServletRequest request) { - assertThat(this.matcher.matches(request)).as("Matches " + getRequestPath(request)).isTrue(); - } - - void doesNotMatch(String requestUri) { - doesNotMatch(mockRequest(null, requestUri)); - } - - void doesNotMatch(HttpMethod httpMethod, String requestUri) { - doesNotMatch(mockRequest(httpMethod, requestUri)); - } - - private void doesNotMatch(HttpServletRequest request) { - assertThat(this.matcher.matches(request)).as("Does not match " + getRequestPath(request)).isFalse(); - } - - private MockHttpServletRequest mockRequest(HttpMethod httpMethod, String requestUri) { - MockServletContext servletContext = new MockServletContext(); - servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); - MockHttpServletRequest request = new MockHttpServletRequest(servletContext); - if (requestUri != null) { - request.setRequestURI(requestUri); - } - if (httpMethod != null) { - request.setMethod(httpMethod.name()); - } - return request; - } - - private String getRequestPath(HttpServletRequest request) { - String url = request.getServletPath(); - if (request.getPathInfo() != null) { - url += request.getPathInfo(); - } - return url; - } - - } - - @Endpoint(id = "foo") - static class FooEndpoint { - - } - - @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "baz") - @SuppressWarnings("removal") - static class BazServletEndpoint { - - } - - interface TestEndpoint extends ExposableEndpoint, PathMappedEndpoint { - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslHealthContributorAutoConfigurationTests.java index ced8bfcea97e..9bb5a9c1a0a5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslHealthContributorAutoConfigurationTests.java @@ -22,12 +22,13 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.ssl.SslHealthContributorAutoConfigurationTests.CustomSslInfoConfiguration.CustomSslHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.actuate.ssl.SslHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.info.SslInfo; import org.springframework.boot.info.SslInfo.CertificateChainInfo; import org.springframework.boot.ssl.SslBundles; @@ -47,8 +48,8 @@ class SslHealthContributorAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(SslHealthContributorAutoConfiguration.class, SslAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(SslHealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, SslAutoConfiguration.class)) .withPropertyValues("server.ssl.bundle=ssltest", "spring.ssl.bundle.jks.ssltest.keystore.location=classpath:test.jks"); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslObservabilityAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslObservabilityAutoConfigurationTests.java deleted file mode 100644 index 4a40f7dff908..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslObservabilityAutoConfigurationTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.ssl; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; -import org.springframework.boot.info.SslInfo; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SslObservabilityAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class SslObservabilityAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, - SslAutoConfiguration.class, SslObservabilityAutoConfiguration.class)); - - private final ApplicationContextRunner contextRunnerWithoutSslBundles = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, - CompositeMeterRegistryAutoConfiguration.class, SslObservabilityAutoConfiguration.class)); - - private final ApplicationContextRunner contextRunnerWithoutMeterRegistry = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SslAutoConfiguration.class, SslObservabilityAutoConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner - .run((context) -> assertThat(context).hasSingleBean(SslMeterBinder.class).hasSingleBean(SslInfo.class)); - } - - @Test - void shouldBackOffIfSslBundlesIsMissing() { - this.contextRunnerWithoutSslBundles - .run((context) -> assertThat(context).doesNotHaveBean(SslMeterBinder.class).doesNotHaveBean(SslInfo.class)); - } - - @Test - void shouldBackOffIfMeterRegistryIsMissing() { - this.contextRunnerWithoutMeterRegistry - .run((context) -> assertThat(context).doesNotHaveBean(SslMeterBinder.class).doesNotHaveBean(SslInfo.class)); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthContributorAutoConfigurationTests.java index 236c83a9abe9..5ffe2fc933b8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthContributorAutoConfigurationTests.java @@ -18,9 +18,9 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.system.DiskSpaceHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.util.unit.DataSize; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java deleted file mode 100644 index 909ce5642308..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; - -import org.junit.jupiter.api.Test; -import zipkin2.reporter.Encoding; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ZipkinAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class ZipkinAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ZipkinAutoConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(Encoding.class) - .hasSingleBean(PropertiesZipkinConnectionDetails.class)); - } - - @Test - void shouldNotSupplyBeansIfZipkinReporterIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("zipkin2.reporter")) - .run((context) -> assertThat(context).doesNotHaveBean(Encoding.class)); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customEncoding"); - assertThat(context).hasSingleBean(Encoding.class); - }); - } - - @Test - void definesPropertiesBasedConnectionDetailsByDefault() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesZipkinConnectionDetails.class)); - } - - @Test - void shouldUseCustomConnectionDetailsWhenDefined() { - this.contextRunner - .withBean(ZipkinConnectionDetails.class, () -> new FixedZipkinConnectionDetails("http://localhost")) - .run((context) -> assertThat(context).hasSingleBean(ZipkinConnectionDetails.class) - .doesNotHaveBean(PropertiesZipkinConnectionDetails.class)); - } - - @Test - void shouldWorkWithoutSenders() { - this.contextRunner - .withClassLoader(new FilteredClassLoader("org.springframework.web.client", - "org.springframework.web.reactive.function.client")) - .run((context) -> assertThat(context).hasNotFailed()); - } - - private static final class FixedZipkinConnectionDetails implements ZipkinConnectionDetails { - - private final String spanEndpoint; - - private FixedZipkinConnectionDetails(String spanEndpoint) { - this.spanEndpoint = spanEndpoint; - } - - @Override - public String getSpanEndpoint() { - return this.spanEndpoint; - } - - } - - @Configuration(proxyBeanMethods = false) - private static final class CustomConfiguration { - - @Bean - Encoding customEncoding() { - return Encoding.PROTO3; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java deleted file mode 100644 index 58fe2babda5f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; - -import java.net.http.HttpClient; - -import org.junit.jupiter.api.Test; -import zipkin2.reporter.BytesMessageSender; -import zipkin2.reporter.HttpEndpointSupplier; - -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.HttpClientSenderConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link SenderConfiguration}. - * - * @author Moritz Halbritter - * @author Wick Dynex - */ -class ZipkinConfigurationsSenderConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(DefaultEncodingConfiguration.class, SenderConfiguration.class)); - - @Test - void shouldSupplyDefaultHttpClientSenderBean() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(BytesMessageSender.class); - assertThat(context).hasSingleBean(ZipkinHttpClientSender.class); - }); - } - - @Test - void shouldNotProvideHttpClientSenderIfHttpClientIsNotAvailable() { - this.contextRunner.withUserConfiguration(HttpClientSenderConfiguration.class) - .withClassLoader(new FilteredClassLoader(HttpClient.class)) - .run((context) -> assertThat(context).doesNotHaveBean(ZipkinHttpClientSender.class)); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customSender"); - assertThat(context).hasSingleBean(BytesMessageSender.class); - }); - } - - @Test - void shouldUseCustomHttpEndpointSupplierFactory() { - this.contextRunner.withUserConfiguration(CustomHttpEndpointSupplierFactoryConfiguration.class) - .run((context) -> { - ZipkinHttpClientSender httpClientSender = context.getBean(ZipkinHttpClientSender.class); - assertThat(httpClientSender).extracting("endpointSupplier") - .isInstanceOf(CustomHttpEndpointSupplier.class); - }); - } - - @Configuration(proxyBeanMethods = false) - static class CustomConfiguration { - - @Bean - BytesMessageSender customSender() { - return mock(BytesMessageSender.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomHttpEndpointSupplierFactoryConfiguration { - - @Bean - HttpEndpointSupplier.Factory httpEndpointSupplier() { - return new CustomHttpEndpointSupplierFactory(); - } - - } - - static class CustomHttpEndpointSupplierFactory implements HttpEndpointSupplier.Factory { - - @Override - public HttpEndpointSupplier create(String endpoint) { - return new CustomHttpEndpointSupplier(endpoint); - } - - } - - static class CustomHttpEndpointSupplier implements HttpEndpointSupplier { - - private final String endpoint; - - CustomHttpEndpointSupplier(String endpoint) { - this.endpoint = endpoint; - } - - @Override - public String get() { - return this.endpoint; - } - - @Override - public void close() { - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java deleted file mode 100644 index b2ef42cc4183..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesAutoConfigurationTests.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.exchanges; - -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.web.exchanges.HttpExchange; -import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; -import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; -import org.springframework.boot.actuate.web.exchanges.Include; -import org.springframework.boot.actuate.web.exchanges.reactive.HttpExchangesWebFilter; -import org.springframework.boot.actuate.web.exchanges.servlet.HttpExchangesFilter; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HttpExchangesAutoConfiguration}. - * - * @author Andy Wilkinson - * @author Madhura Bhave - */ -class HttpExchangesAutoConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpExchangesAutoConfiguration.class)); - - @Test - void autoConfigurationIsDisabledByDefault() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesAutoConfiguration.class)); - } - - @Test - void autoConfigurationIsEnabledWhenHttpExchangeRepositoryBeanPresent() { - this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(HttpExchangesFilter.class); - assertThat(context).hasSingleBean(HttpExchangeRepository.class); - assertThat(context.getBean(HttpExchangeRepository.class)).isInstanceOf(CustomHttpExchangesRepository.class); - }); - } - - @Test - void usesUserProvidedWebFilterWhenReactiveContext() { - new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpExchangesAutoConfiguration.class)) - .withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .withUserConfiguration(CustomWebFilterConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(HttpExchangesWebFilter.class); - assertThat(context.getBean(HttpExchangesWebFilter.class)) - .isInstanceOf(CustomHttpExchangesWebFilter.class); - }); - } - - @Test - void configuresServletFilter() { - this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(HttpExchangesFilter.class)); - } - - @Test - void usesUserProvidedServletFilter() { - this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .withUserConfiguration(CustomFilterConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(HttpExchangesFilter.class); - assertThat(context.getBean(HttpExchangesFilter.class)).isInstanceOf(CustomHttpExchangesFilter.class); - }); - } - - @Test - void backsOffWhenNotRecording() { - this.contextRunner.withUserConfiguration(CustomHttpExchangesRepositoryConfiguration.class) - .withPropertyValues("management.httpexchanges.recording.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(InMemoryHttpExchangeRepository.class) - .doesNotHaveBean(HttpExchangesFilter.class)); - } - - static class CustomHttpExchangesRepository implements HttpExchangeRepository { - - @Override - public List findAll() { - return null; - } - - @Override - public void add(HttpExchange exchange) { - - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomHttpExchangesRepositoryConfiguration { - - @Bean - CustomHttpExchangesRepository customRepository() { - return new CustomHttpExchangesRepository(); - } - - } - - private static final class CustomHttpExchangesWebFilter extends HttpExchangesWebFilter { - - private CustomHttpExchangesWebFilter(HttpExchangeRepository repository, Set includes) { - super(repository, includes); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomWebFilterConfiguration { - - @Bean - CustomHttpExchangesWebFilter customWebFilter(HttpExchangeRepository repository, - HttpExchangesProperties properties) { - return new CustomHttpExchangesWebFilter(repository, properties.getRecording().getInclude()); - } - - } - - private static final class CustomHttpExchangesFilter extends HttpExchangesFilter { - - private CustomHttpExchangesFilter(HttpExchangeRepository repository, Set includes) { - super(repository, includes); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomFilterConfiguration { - - @Bean - CustomHttpExchangesFilter customWebFilter(HttpExchangeRepository repository, Set includes) { - return new CustomHttpExchangesFilter(repository, includes); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java index 2c3e4d3d4145..8bea75726e4c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointAutoConfigurationTests.java @@ -35,8 +35,8 @@ */ class HttpExchangesEndpointAutoConfigurationTests { - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner().withConfiguration( - AutoConfigurations.of(HttpExchangesAutoConfiguration.class, HttpExchangesEndpointAutoConfiguration.class)); + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HttpExchangesEndpointAutoConfiguration.class)); @Test void runWhenRepositoryBeanAvailableShouldHaveEndpointBean() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfigurationTests.java index af0c956fe133..79948d1e95ed 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfigurationTests.java @@ -18,17 +18,8 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration; -import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -41,34 +32,18 @@ class MappingsEndpointAutoConfigurationTests { @Test - void whenEndpointIsUnavailableThenEndpointAndDescriptionProvidersAreNotCreated() { + void whenEndpointIsUnavailableThenEndpointIsNotCreated() { new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(MappingsEndpointAutoConfiguration.class, - JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - WebMvcEndpointManagementContextConfiguration.class, PropertyPlaceholderAutoConfiguration.class)) - .run((context) -> { - assertThat(context).doesNotHaveBean(MappingsEndpoint.class); - assertThat(context).doesNotHaveBean(MappingDescriptionProvider.class); - }); - + .withConfiguration(AutoConfigurations.of(MappingsEndpointAutoConfiguration.class)) + .run((context) -> assertThat(context).doesNotHaveBean(MappingsEndpoint.class)); } @Test - void whenEndpointIsAvailableThenEndpointAndDescriptionProvidersAreCreated() { + void whenEndpointIsAvailableThenEndpointIsCreated() { new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(MappingsEndpointAutoConfiguration.class, - JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - WebMvcEndpointManagementContextConfiguration.class, PropertyPlaceholderAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(MappingsEndpointAutoConfiguration.class)) .withPropertyValues("management.endpoints.web.exposure.include=mappings") - .run((context) -> { - assertThat(context).hasSingleBean(MappingsEndpoint.class); - assertThat(context.getBeansOfType(MappingDescriptionProvider.class)).hasSize(3); - }); - + .run((context) -> assertThat(context).hasSingleBean(MappingsEndpoint.class)); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationIntegrationTests.java deleted file mode 100644 index 6636d5bfc265..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationIntegrationTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.reactive; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -import org.apache.catalina.Valve; -import org.apache.catalina.startup.Tomcat; -import org.apache.catalina.valves.AccessLogValve; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.convert.ApplicationConversionService; -import org.springframework.boot.env.ConfigTreePropertySource; -import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.server.WebServer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.convert.support.ConfigurableConversionService; -import org.springframework.http.MediaType; -import org.springframework.util.FileCopyUtils; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link ReactiveManagementChildContextConfiguration}. - * - * @author Andy Wilkinson - */ -class ReactiveManagementChildContextConfigurationIntegrationTests { - - private final List webServers = new ArrayList<>(); - - private final ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, - ReactiveWebServerFactoryAutoConfiguration.class, ReactiveManagementContextAutoConfiguration.class, - WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class, HttpHandlerAutoConfiguration.class, - WebFluxAutoConfiguration.class)) - .withUserConfiguration(SucceedingEndpoint.class) - .withInitializer(new ServerPortInfoApplicationContextInitializer()) - .withInitializer((context) -> context.addApplicationListener( - (ApplicationListener) (event) -> this.webServers.add(event.getWebServer()))) - .withPropertyValues("server.port=0", "management.server.port=0", "management.endpoints.web.exposure.include=*"); - - @TempDir - Path temp; - - @Test - void endpointsAreBeneathActuatorByDefault() { - this.runner.withPropertyValues("management.server.port:0").run(withWebTestClient((client) -> { - String body = client.get() - .uri("actuator/success") - .accept(MediaType.APPLICATION_JSON) - .exchangeToMono((response) -> response.bodyToMono(String.class)) - .block(); - assertThat(body).isEqualTo("Success"); - })); - } - - @Test - void whenManagementServerBasePathIsConfiguredThenEndpointsAreBeneathThatPath() { - this.runner.withPropertyValues("management.server.port:0", "management.server.base-path:/manage") - .run(withWebTestClient((client) -> { - String body = client.get() - .uri("manage/actuator/success") - .accept(MediaType.APPLICATION_JSON) - .exchangeToMono((response) -> response.bodyToMono(String.class)) - .block(); - assertThat(body).isEqualTo("Success"); - })); - } - - @Test // gh-32941 - void whenManagementServerPortLoadedFromConfigTree() { - this.runner.withInitializer(this::addConfigTreePropertySource) - .run((context) -> assertThat(context).hasNotFailed()); - } - - @Test - void accessLogHasManagementServerSpecificPrefix() { - this.runner.withPropertyValues("server.tomcat.accesslog.enabled=true").run((context) -> { - AccessLogValve accessLogValve = findAccessLogValve(); - assertThat(accessLogValve).isNotNull(); - assertThat(accessLogValve.getPrefix()).isEqualTo("management_access_log"); - }); - } - - private AccessLogValve findAccessLogValve() { - assertThat(this.webServers).hasSize(2); - Tomcat tomcat = ((TomcatWebServer) this.webServers.get(1)).getTomcat(); - for (Valve valve : tomcat.getEngine().getPipeline().getValves()) { - if (valve instanceof AccessLogValve accessLogValve) { - return accessLogValve; - } - } - return null; - } - - private void addConfigTreePropertySource(ConfigurableApplicationContext applicationContext) { - try { - applicationContext.getEnvironment() - .setConversionService((ConfigurableConversionService) ApplicationConversionService.getSharedInstance()); - Path configtree = this.temp.resolve("configtree"); - Path file = configtree.resolve("management/server/port"); - file.toFile().getParentFile().mkdirs(); - FileCopyUtils.copy("0".getBytes(StandardCharsets.UTF_8), file.toFile()); - ConfigTreePropertySource source = new ConfigTreePropertySource("configtree", configtree); - applicationContext.getEnvironment().getPropertySources().addFirst(source); - } - catch (IOException ex) { - throw new IllegalStateException(ex); - } - } - - private ContextConsumer withWebTestClient(Consumer webClient) { - return (context) -> { - String port = context.getEnvironment().getProperty("local.management.port"); - WebClient client = WebClient.create("http://localhost:" + port); - webClient.accept(client); - }; - } - - @Endpoint(id = "success") - static class SucceedingEndpoint { - - @ReadOperation - String fail() { - return "Success"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationTests.java deleted file mode 100644 index ce30fd72995c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementChildContextConfigurationTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.reactive; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration.AccessLogCustomizer; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ReactiveManagementChildContextConfiguration}. - * - * @author Moritz Halbritter - */ -class ReactiveManagementChildContextConfigurationTests { - - @Test - void accessLogCustomizer() { - AccessLogCustomizer customizer = new AccessLogCustomizer("prefix") { - }; - assertThat(customizer.customizePrefix(null)).isEqualTo("prefix"); - assertThat(customizer.customizePrefix("existing")).isEqualTo("prefixexisting"); - assertThat(customizer.customizePrefix("prefixexisting")).isEqualTo("prefixexisting"); - } - - @Test - void accessLogCustomizerWithNullPrefix() { - AccessLogCustomizer customizer = new AccessLogCustomizer(null) { - }; - assertThat(customizer.customizePrefix(null)).isEqualTo(null); - assertThat(customizer.customizePrefix("existing")).isEqualTo("existing"); - } - - @Test - // gh-45857 - void failsWithoutManagementServerPropertiesBeanFromParent() { - new ReactiveWebApplicationContextRunner() - .run((parent) -> new ReactiveWebApplicationContextRunner().withParent(parent) - .withUserConfiguration(ReactiveManagementChildContextConfiguration.class) - .run((context) -> assertThat(context).hasFailed())); - } - - @Test - // gh-45857 - void succeedsWithManagementServerPropertiesBeanFromParent() { - new ReactiveWebApplicationContextRunner().withBean(ManagementServerProperties.class) - .run((parent) -> new ReactiveWebApplicationContextRunner().withParent(parent) - .withUserConfiguration(ReactiveManagementChildContextConfiguration.class) - .run((context) -> assertThat(context).hasNotFailed())); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializerAotTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializerAotTests.java index a69d31a3f3e7..97b75c875514 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializerAotTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ChildManagementContextInitializerAotTests.java @@ -18,24 +18,31 @@ import java.util.function.Consumer; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.aot.AotDetector; import org.springframework.aot.test.generate.TestGenerationContext; +import org.springframework.boot.WebApplicationType; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.servlet.MockServletWebServer; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.aot.ApplicationContextAotGenerator; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.test.tools.CompileWithForkedClassLoader; @@ -44,6 +51,7 @@ import org.springframework.util.StringUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.willAnswer; /** * AOT tests for {@link ChildManagementContextInitializer}. @@ -51,7 +59,6 @@ * @author Phillip Webb */ @ExtendWith(OutputCaptureExtension.class) -@DirtiesUrlFactories class ChildManagementContextInitializerAotTests { @Test @@ -61,8 +68,8 @@ void aotContributedInitializerStartsManagementContext(CapturedOutput output) { WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)); + WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)) + .withUserConfiguration(WebServerConfiguration.class, TestServletManagementContextConfiguration.class); contextRunner.withPropertyValues("server.port=0", "management.server.port=0").prepare((context) -> { TestGenerationContext generationContext = new TestGenerationContext(TestTarget.class); ClassName className = new ApplicationContextAotGenerator().processAheadOfTime( @@ -75,10 +82,10 @@ void aotContributedInitializerStartsManagementContext(CapturedOutput output) { ApplicationContextInitializer initializer = compiled .getInstance(ApplicationContextInitializer.class, className.toString()); initializer.initialize(freshApplicationContext); - assertThat(output).satisfies(numberOfOccurrences("Tomcat started on port", 0)); + assertThat(output).satisfies(numberOfOccurrences("WebServer started", 0)); TestPropertyValues.of(AotDetector.AOT_ENABLED + "=true") .applyToSystemProperties(freshApplicationContext::refresh); - assertThat(output).satisfies(numberOfOccurrences("Tomcat started on port", 2)); + assertThat(output).satisfies(numberOfOccurrences("WebServer started", 2)); }); }); } @@ -94,4 +101,40 @@ static class TestTarget { } + @Configuration(proxyBeanMethods = false) + static class TestServletManagementContextConfiguration { + + @Bean + ManagementContextFactory managementContextFactory() { + return new ManagementContextFactory(WebApplicationType.SERVLET, LogOnStartServletWebServerFactory.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class WebServerConfiguration { + + @Bean + LogOnStartServletWebServerFactory servletWebServerFactory() { + return new LogOnStartServletWebServerFactory(); + } + + } + + static class LogOnStartServletWebServerFactory extends MockServletWebServerFactory { + + private static final Log log = LogFactory.getLog(LogOnStartServletWebServerFactory.class); + + @Override + public MockServletWebServer getWebServer(ServletContextInitializer... initializers) { + WebServer webServer = super.getWebServer(initializers); + willAnswer((invocation) -> { + log.info("WebServer started"); + return null; + }).given(webServer).start(); + return (MockServletWebServer) webServer; + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java deleted file mode 100644 index 949261ff4c69..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.server; - -import java.util.function.Consumer; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.util.StringUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ManagementContextAutoConfiguration}. - * - * @author Madhura Bhave - * @author Andy Wilkinson - */ -@ExtendWith(OutputCaptureExtension.class) -class ManagementContextAutoConfigurationTests { - - @Test - void childManagementContextShouldStartForEmbeddedServer(CapturedOutput output) { - WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)); - contextRunner.withPropertyValues("server.port=0", "management.server.port=0") - .run((context) -> assertThat(output).satisfies(numberOfOccurrences("Tomcat started on port", 2))); - } - - @Test - void childManagementContextShouldNotStartWithoutEmbeddedServer(CapturedOutput output) { - WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)); - contextRunner.withPropertyValues("server.port=0", "management.server.port=0").run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(output).doesNotContain("Tomcat started"); - }); - } - - @Test - void childManagementContextShouldRestartWhenParentIsStoppedThenStarted(CapturedOutput output) { - WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)); - contextRunner.withPropertyValues("server.port=0", "management.server.port=0").run((context) -> { - assertThat(output).satisfies(numberOfOccurrences("Tomcat started on port", 2)); - context.getSourceApplicationContext().stop(); - context.getSourceApplicationContext().start(); - assertThat(output).satisfies(numberOfOccurrences("Tomcat started on port", 4)); - }); - } - - @Test - void givenSamePortManagementServerWhenManagementServerAddressIsConfiguredThenContextRefreshFails() { - WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class, - DispatcherServletAutoConfiguration.class)); - contextRunner.withPropertyValues("server.port=0", "management.server.address=127.0.0.1") - .run((context) -> assertThat(context).getFailure() - .hasMessageStartingWith("Management-specific server address cannot be configured")); - } - - private Consumer numberOfOccurrences(String substring, int expectedCount) { - return (charSequence) -> { - int count = StringUtils.countOccurrencesOf(charSequence.toString(), substring); - assertThat(count).isEqualTo(expectedCount); - }; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextConfigurationImportSelectorTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextConfigurationImportSelectorTests.java index 2568d2b0a751..0faed22268fb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextConfigurationImportSelectorTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextConfigurationImportSelectorTests.java @@ -74,7 +74,7 @@ void selectImportsLoadsFromResources() { // Remove JerseySameManagementContextConfiguration, as it specifies // ManagementContextType.SAME and we asked for ManagementContextType.CHILD expected.remove( - "org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration"); + "org.springframework.boot.jersey.actuate.autoconfigure.web.JerseySameManagementContextConfiguration"); assertThat(imports).containsExactlyInAnyOrderElementsOf(expected); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementServerPropertiesTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementServerPropertiesTests.java index 668c30248593..f71aa068c29d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementServerPropertiesTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementServerPropertiesTests.java @@ -69,12 +69,4 @@ void slashOfBasePathIsDefaultValue() { assertThat(properties.getBasePath()).isEmpty(); } - @Test - void accessLogsArePrefixedByDefault() { - ManagementServerProperties properties = new ManagementServerProperties(); - assertThat(properties.getTomcat().getAccesslog().getPrefix()).isEqualTo("management_"); - assertThat(properties.getJetty().getAccesslog().getPrefix()).isEqualTo("management_"); - assertThat(properties.getUndertow().getAccesslog().getPrefix()).isEqualTo("management_"); - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementChildContextConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementChildContextConfigurationTests.java deleted file mode 100644 index 404ce09a2209..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementChildContextConfigurationTests.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.web.servlet; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration.AccessLogCustomizer; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ServletManagementChildContextConfiguration}. - * - * @author Moritz Halbritter - */ -class ServletManagementChildContextConfigurationTests { - - @Test - void accessLogCustomizer() { - AccessLogCustomizer customizer = new AccessLogCustomizer("prefix") { - }; - assertThat(customizer.customizePrefix(null)).isEqualTo("prefix"); - assertThat(customizer.customizePrefix("existing")).isEqualTo("prefixexisting"); - assertThat(customizer.customizePrefix("prefixexisting")).isEqualTo("prefixexisting"); - } - - @Test - void accessLogCustomizerWithNullPrefix() { - AccessLogCustomizer customizer = new AccessLogCustomizer(null) { - }; - assertThat(customizer.customizePrefix(null)).isEqualTo(null); - assertThat(customizer.customizePrefix("existing")).isEqualTo("existing"); - } - - @Test - // gh-45857 - void failsWithoutManagementServerPropertiesBeanFromParent() { - new WebApplicationContextRunner().run((parent) -> new WebApplicationContextRunner().withParent(parent) - .withUserConfiguration(ServletManagementChildContextConfiguration.class) - .run((context) -> assertThat(context).hasFailed())); - } - - @Test - // gh-45857 - void succeedsWithManagementServerPropertiesBeanFromParent() { - new WebApplicationContextRunner().withBean(ManagementServerProperties.class) - .run((parent) -> new WebApplicationContextRunner().withParent(parent) - .withUserConfiguration(ServletManagementChildContextConfiguration.class) - .run((context) -> assertThat(context).hasNotFailed())); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/security/servlet/saml-certificate b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/security/servlet/saml-certificate deleted file mode 100644 index c04a9c1602fa..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/security/servlet/saml-certificate +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEEzCCAvugAwIBAgIJAIc1qzLrv+5nMA0GCSqGSIb3DQEBCwUAMIGfMQswCQYD -VQQGEwJVUzELMAkGA1UECAwCQ08xFDASBgNVBAcMC0Nhc3RsZSBSb2NrMRwwGgYD -VQQKDBNTYW1sIFRlc3RpbmcgU2VydmVyMQswCQYDVQQLDAJJVDEgMB4GA1UEAwwX -c2ltcGxlc2FtbHBocC5jZmFwcHMuaW8xIDAeBgkqhkiG9w0BCQEWEWZoYW5pa0Bw -aXZvdGFsLmlvMB4XDTE1MDIyMzIyNDUwM1oXDTI1MDIyMjIyNDUwM1owgZ8xCzAJ -BgNVBAYTAlVTMQswCQYDVQQIDAJDTzEUMBIGA1UEBwwLQ2FzdGxlIFJvY2sxHDAa -BgNVBAoME1NhbWwgVGVzdGluZyBTZXJ2ZXIxCzAJBgNVBAsMAklUMSAwHgYDVQQD -DBdzaW1wbGVzYW1scGhwLmNmYXBwcy5pbzEgMB4GCSqGSIb3DQEJARYRZmhhbmlr -QHBpdm90YWwuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4cn62 -E1xLqpN34PmbrKBbkOXFjzWgJ9b+pXuaRft6A339uuIQeoeH5qeSKRVTl32L0gdz -2ZivLwZXW+cqvftVW1tvEHvzJFyxeTW3fCUeCQsebLnA2qRa07RkxTo6Nf244mWW -RDodcoHEfDUSbxfTZ6IExSojSIU2RnD6WllYWFdD1GFpBJOmQB8rAc8wJIBdHFdQ -nX8Ttl7hZ6rtgqEYMzYVMuJ2F2r1HSU1zSAvwpdYP6rRGFRJEfdA9mm3WKfNLSc5 -cljz0X/TXy0vVlAV95l9qcfFzPmrkNIst9FZSwpvB49LyAVke04FQPPwLgVH4gph -iJH3jvZ7I+J5lS8VAgMBAAGjUDBOMB0GA1UdDgQWBBTTyP6Cc5HlBJ5+ucVCwGc5 -ogKNGzAfBgNVHSMEGDAWgBTTyP6Cc5HlBJ5+ucVCwGc5ogKNGzAMBgNVHRMEBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAvMS4EQeP/ipV4jOG5lO6/tYCb/iJeAduO -nRhkJk0DbX329lDLZhTTL/x/w/9muCVcvLrzEp6PN+VWfw5E5FWtZN0yhGtP9R+v -ZnrV+oc2zGD+no1/ySFOe3EiJCO5dehxKjYEmBRv5sU/LZFKZpozKN/BMEa6CqLu -xbzb7ykxVr7EVFXwltPxzE9TmL9OACNNyF5eJHWMRMllarUvkcXlh4pux4ks9e6z -V9DQBy2zds9f1I3qxg0eX6JnGrXi/ZiCT+lJgVe3ZFXiejiLAiKB04sXW3ti0LW3 -lx13Y1YlQ4/tlpgTgfIJxKV6nyPiLoK0nywbMd+vpAirDt2Oc+hk ------END CERTIFICATE----- \ No newline at end of file diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/WithTestEndpointOutcomeExposureContributor.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/WithTestEndpointOutcomeExposureContributor.java similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/WithTestEndpointOutcomeExposureContributor.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/WithTestEndpointOutcomeExposureContributor.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/AbstractHealthEndpointAdditionalPathIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/integrationtest/AbstractHealthEndpointAdditionalPathIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/AbstractHealthEndpointAdditionalPathIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/integrationtest/AbstractHealthEndpointAdditionalPathIntegrationTests.java index 0b6dd159defa..c1efa3e75a19 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/AbstractHealthEndpointAdditionalPathIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/integrationtest/AbstractHealthEndpointAdditionalPathIntegrationTests.java @@ -37,11 +37,11 @@ * @param the assertions * @author Madhura Bhave */ -abstract class AbstractHealthEndpointAdditionalPathIntegrationTests, C extends ConfigurableApplicationContext, A extends ApplicationContextAssertProvider> { +public abstract class AbstractHealthEndpointAdditionalPathIntegrationTests, C extends ConfigurableApplicationContext, A extends ApplicationContextAssertProvider> { private final T runner; - AbstractHealthEndpointAdditionalPathIntegrationTests(T runner) { + protected AbstractHealthEndpointAdditionalPathIntegrationTests(T runner) { this.runner = runner; } diff --git a/spring-boot-project/spring-boot-actuator-docs/build.gradle b/spring-boot-project/spring-boot-actuator-docs/build.gradle new file mode 100644 index 000000000000..12ce9e4274b5 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-docs/build.gradle @@ -0,0 +1,77 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java" + id "org.springframework.boot.antora-contributor" +} + +description = "Spring Boot Actuator Docs" + +dependencies { + testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + testImplementation(project(":spring-boot-project:spring-boot-cache")) + testImplementation(project(":spring-boot-project:spring-boot-flyway")) + testImplementation(project(":spring-boot-project:spring-boot-health")) + testImplementation(project(":spring-boot-project:spring-boot-http-converter")) + testImplementation(project(":spring-boot-project:spring-boot-integration")) + testImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-jdbc")) + testImplementation(project(":spring-boot-project:spring-boot-liquibase")) + testImplementation(project(":spring-boot-project:spring-boot-metrics")) + testImplementation(project(":spring-boot-project:spring-boot-quartz")) + testImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) + testImplementation(project(":spring-boot-project:spring-boot-session")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-web-server-test")) + testImplementation(project(":spring-boot-project:spring-boot-webflux")) + testImplementation(project(":spring-boot-project:spring-boot-webmvc")) + testImplementation("io.micrometer:micrometer-core") + testImplementation("io.micrometer:micrometer-registry-prometheus") + testImplementation("io.prometheus:prometheus-metrics-exposition-formats") + testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc") + testImplementation("org.springframework.restdocs:spring-restdocs-webtestclient") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") +} + +tasks.named("test") { + outputs.dir(layout.buildDirectory.dir("generated-snippets")) +} + +tasks.named("generateAntoraPlaybook") { + antoraExtensions.xref.stubs = ["appendix:.*", "api:.*", "reference:.*"] +} + +antoraContributions { + 'actuator-rest-api' { + aggregateContent { + from(tasks.named('test').map { layout.buildDirectory.dir("generated-snippets") }) { + into "modules/api/partials/rest/actuator" + } + } + localAggregateContent { + from(tasks.named("generateAntoraYml")) { + into "modules" + } + } + source() + } +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/antora.yml b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/antora.yml similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/antora.yml rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/antora.yml diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/local-nav.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/local-nav.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/local-nav.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/local-nav.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/auditevents.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/auditevents.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/auditevents.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/auditevents.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/beans.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/beans.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/beans.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/beans.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/caches.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/caches.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/caches.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/caches.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/conditions.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/conditions.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/conditions.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/conditions.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/configprops.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/configprops.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/configprops.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/configprops.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/env.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/env.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/env.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/env.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/flyway.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/flyway.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/flyway.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/flyway.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/health.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/health.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/health.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/health.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/heapdump.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/heapdump.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/heapdump.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/heapdump.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/httpexchanges.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/httpexchanges.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/httpexchanges.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/httpexchanges.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/index.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/index.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/index.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/index.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/info.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/info.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/info.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/info.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/integrationgraph.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/integrationgraph.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/integrationgraph.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/integrationgraph.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/liquibase.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/liquibase.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/liquibase.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/liquibase.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/logfile.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/logfile.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/logfile.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/logfile.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/loggers.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/loggers.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/loggers.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/loggers.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/mappings.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/mappings.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/mappings.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/mappings.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/metrics.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/metrics.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/metrics.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/metrics.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/prometheus.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/prometheus.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/prometheus.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/prometheus.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/quartz.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/quartz.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/quartz.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/quartz.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/sbom.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/sbom.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/sbom.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/sbom.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/scheduledtasks.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/scheduledtasks.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/scheduledtasks.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/scheduledtasks.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/sessions.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/sessions.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/sessions.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/sessions.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/shutdown.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/shutdown.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/shutdown.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/shutdown.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/startup.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/startup.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/startup.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/startup.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/threaddump.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/threaddump.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/pages/rest/actuator/threaddump.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/pages/rest/actuator/threaddump.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/partials/nav-actuator-rest-api.adoc b/spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/partials/nav-actuator-rest-api.adoc similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/antora/modules/api/partials/nav-actuator-rest-api.adoc rename to spring-boot-project/spring-boot-actuator-docs/src/docs/antora/modules/api/partials/nav-actuator-rest-api.adoc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/AbstractEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/AbstractEndpointDocumentationTests.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/AbstractEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/AbstractEndpointDocumentationTests.java index 501b2ccbff2b..06c1c64928c1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/AbstractEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/AbstractEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation; +package org.springframework.boot.actuate.docs; import java.io.IOException; import java.util.HashMap; @@ -31,18 +31,18 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.jackson.JacksonEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.AbstractEndpointDocumentationTests.BaseDocumentationConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration; +import org.springframework.boot.actuate.docs.AbstractEndpointDocumentationTests.BaseDocumentationConfiguration; import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxEndpointManagementContextConfiguration; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.actuate.web.WebMvcEndpointManagementContextConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MockMvcEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/MockMvcEndpointDocumentationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MockMvcEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/MockMvcEndpointDocumentationTests.java index 59e70e1ee384..9ddacb02b1b3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MockMvcEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/MockMvcEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation; +package org.springframework.boot.actuate.docs; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/audit/AuditEventsEndpointDocumentationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/audit/AuditEventsEndpointDocumentationTests.java index 0576fb4555d7..97f6b790788b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/audit/AuditEventsEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.audit; +package org.springframework.boot.actuate.docs.audit; import java.time.Instant; import java.time.format.DateTimeFormatter; @@ -26,7 +26,7 @@ import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.boot.actuate.audit.AuditEventRepository; import org.springframework.boot.actuate.audit.AuditEventsEndpoint; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.bean.override.mockito.MockitoBean; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/beans/BeansEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/beans/BeansEndpointDocumentationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/beans/BeansEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/beans/BeansEndpointDocumentationTests.java index 2f1c19e59c87..1c73c08d9c13 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/beans/BeansEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/beans/BeansEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.beans; +package org.springframework.boot.actuate.docs.beans; import java.util.Collection; import java.util.List; @@ -23,8 +23,8 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.beans.BeansEndpoint; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/cache/CachesEndpointDocumentationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/cache/CachesEndpointDocumentationTests.java index f9a421f03d53..bf95361dc703 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/cache/CachesEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cache; +package org.springframework.boot.actuate.docs.cache; import java.util.Collections; import java.util.HashMap; @@ -23,9 +23,9 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; -import org.springframework.boot.actuate.cache.CachesEndpoint; -import org.springframework.boot.actuate.cache.CachesEndpointWebExtension; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpoint; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpointWebExtension; import org.springframework.cache.CacheManager; import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/condition/ConditionsReportEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/condition/ConditionsReportEndpointDocumentationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/condition/ConditionsReportEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/condition/ConditionsReportEndpointDocumentationTests.java index 8dd51a2453b6..7f4cdad51860 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/condition/ConditionsReportEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/condition/ConditionsReportEndpointDocumentationTests.java @@ -14,13 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.condition; +package org.springframework.boot.actuate.docs.condition; import java.util.List; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpoint; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.context.ConfigurableApplicationContext; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/ShutdownEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/context/ShutdownEndpointDocumentationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/ShutdownEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/context/ShutdownEndpointDocumentationTests.java index f928df5f0524..3a0a69d30ca3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/ShutdownEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/context/ShutdownEndpointDocumentationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.context; +package org.springframework.boot.actuate.docs.context; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.context.ShutdownEndpoint; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/context/properties/ConfigurationPropertiesReportEndpointDocumentationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/context/properties/ConfigurationPropertiesReportEndpointDocumentationTests.java index 61d710fc7b2a..8253681acb3a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/context/properties/ConfigurationPropertiesReportEndpointDocumentationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.context.properties; +package org.springframework.boot.actuate.docs.context.properties; import java.util.Collections; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.endpoint.Show; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/env/EnvironmentEndpointDocumentationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/env/EnvironmentEndpointDocumentationTests.java index c4bf25796ce5..cad6f3de1105 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/env/EnvironmentEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/env/EnvironmentEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.env; +package org.springframework.boot.actuate.docs.env; import java.io.IOException; import java.util.Collections; @@ -28,7 +28,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.endpoint.Show; import org.springframework.boot.actuate.env.EnvironmentEndpoint; import org.springframework.context.annotation.Bean; @@ -56,8 +56,7 @@ * * @author Andy Wilkinson */ -@TestPropertySource( - properties = "spring.config.location=classpath:/org/springframework/boot/actuate/autoconfigure/env/") +@TestPropertySource(properties = "spring.config.location=classpath:/org/springframework/boot/actuate/docs/env/") class EnvironmentEndpointDocumentationTests extends MockMvcEndpointDocumentationTests { private static final FieldDescriptor activeProfiles = fieldWithPath("activeProfiles") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/flyway/FlywayEndpointDocumentationTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/flyway/FlywayEndpointDocumentationTests.java index 7300533fbcda..8d68fe05088d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/flyway/FlywayEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.flyway; +package org.springframework.boot.actuate.docs.flyway; import java.util.List; @@ -23,10 +23,10 @@ import org.flywaydb.core.api.MigrationState; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; -import org.springframework.boot.actuate.flyway.FlywayEndpoint; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.flyway.endpoint.FlywayEndpoint; import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -45,8 +45,7 @@ * * @author Andy Wilkinson */ -@TestPropertySource( - properties = "spring.flyway.locations=classpath:org/springframework/boot/actuate/autoconfigure/flyway") +@TestPropertySource(properties = "spring.flyway.locations=classpath:org/springframework/boot/actuate/docs/flyway") class FlywayEndpointDocumentationTests extends MockMvcEndpointDocumentationTests { @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/health/HealthEndpointDocumentationTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/health/HealthEndpointDocumentationTests.java index 3dbfff895b29..477cc980b8ae 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/health/HealthEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.health; +package org.springframework.boot.actuate.docs.health; import java.io.File; import java.util.Collections; @@ -26,26 +26,27 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.health.AdditionalHealthEndpointPath; -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.DefaultHealthContributorRegistry; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthContributorRegistry; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroup; import org.springframework.boot.actuate.health.HealthEndpointGroups; -import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.HttpCodeStatusMapper; import org.springframework.boot.actuate.health.SimpleHttpCodeStatusMapper; import org.springframework.boot.actuate.health.SimpleStatusAggregator; import org.springframework.boot.actuate.health.StatusAggregator; -import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator; import org.springframework.boot.actuate.system.DiskSpaceHealthIndicator; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorNameGenerator; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.registry.DefaultHealthContributorRegistry; +import org.springframework.boot.health.registry.HealthContributorRegistry; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.health.DataSourceHealthIndicator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; @@ -106,7 +107,9 @@ static class TestConfiguration { @Bean HealthEndpoint healthEndpoint(Map healthContributors) { - HealthContributorRegistry registry = new DefaultHealthContributorRegistry(healthContributors); + HealthContributorRegistry registry = new DefaultHealthContributorRegistry( + HealthContributorNameGenerator.withoutStandardSuffixes().apply(healthContributors), + Collections.emptyList()); HealthEndpointGroup primary = new TestHealthEndpointGroup(); HealthEndpointGroups groups = HealthEndpointGroups.of(primary, Collections.emptyMap()); return new HealthEndpoint(registry, groups, null); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/info/InfoEndpointDocumentationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/info/InfoEndpointDocumentationTests.java index e0ae86398e7c..0d11d51829b7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/info/InfoEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/info/InfoEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.info; +package org.springframework.boot.actuate.docs.info; import java.time.Instant; import java.util.List; @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.info.BuildInfoContributor; import org.springframework.boot.actuate.info.GitInfoContributor; import org.springframework.boot.actuate.info.InfoContributor; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/integration/IntegrationGraphEndpointDocumentationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/integration/IntegrationGraphEndpointDocumentationTests.java index f58d89ab46e5..1f52ee8463a6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/integration/IntegrationGraphEndpointDocumentationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integration; +package org.springframework.boot.actuate.docs.integration; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; -import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; +import org.springframework.boot.integration.endpoint.IntegrationGraphEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/liquibase/LiquibaseEndpointDocumentationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/liquibase/LiquibaseEndpointDocumentationTests.java index 521119b49fc5..e4414dc672a2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/liquibase/LiquibaseEndpointDocumentationTests.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.liquibase; +package org.springframework.boot.actuate.docs.liquibase; import java.util.List; import liquibase.changelog.ChangeSet.ExecType; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; -import org.springframework.boot.actuate.liquibase.LiquibaseEndpoint; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; +import org.springframework.boot.liquibase.endpoint.LiquibaseEndpoint; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -44,7 +44,7 @@ * @author Andy Wilkinson */ @TestPropertySource( - properties = "spring.liquibase.change-log=classpath:org/springframework/boot/actuate/autoconfigure/liquibase/db.changelog-master.yaml") + properties = "spring.liquibase.change-log=classpath:org/springframework/boot/actuate/docs/liquibase/db.changelog-master.yaml") class LiquibaseEndpointDocumentationTests extends MockMvcEndpointDocumentationTests { @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/LogFileWebEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/logging/LogFileWebEndpointDocumentationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/LogFileWebEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/logging/LogFileWebEndpointDocumentationTests.java index 059bf179da64..9ee4f19269a2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/LogFileWebEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/logging/LogFileWebEndpointDocumentationTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.logging; +package org.springframework.boot.actuate.docs.logging; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.logging.LogFileWebEndpoint; import org.springframework.boot.logging.LogFile; import org.springframework.context.annotation.Bean; @@ -56,7 +56,7 @@ static class TestConfiguration { LogFileWebEndpoint endpoint() { MockEnvironment environment = new MockEnvironment(); environment.setProperty("logging.file.name", - "src/test/resources/org/springframework/boot/actuate/autoconfigure/logging/sample.log"); + "src/test/resources/org/springframework/boot/actuate/docs/logging/sample.log"); return new LogFileWebEndpoint(LogFile.get(environment), null); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/LoggersEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/logging/LoggersEndpointDocumentationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/LoggersEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/logging/LoggersEndpointDocumentationTests.java index 6118601e06d8..c599865496ad 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/logging/LoggersEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/logging/LoggersEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.logging; +package org.springframework.boot.actuate.docs.logging; import java.util.Collections; import java.util.EnumSet; @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.logging.LoggersEndpoint; import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.LoggerConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/HeapDumpWebEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/management/HeapDumpWebEndpointDocumentationTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/HeapDumpWebEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/management/HeapDumpWebEndpointDocumentationTests.java index 243b8291ad9d..f975c03562fe 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/HeapDumpWebEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/management/HeapDumpWebEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.management; +package org.springframework.boot.actuate.docs.management; import java.io.File; import java.io.FileWriter; @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.management.HeapDumpWebEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/management/ThreadDumpEndpointDocumentationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/management/ThreadDumpEndpointDocumentationTests.java index 3bd4299e4b80..48dc6d361c8b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/management/ThreadDumpEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.management; +package org.springframework.boot.actuate.docs.management; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.management.ThreadDumpEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/metrics/MetricsEndpointDocumentationTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/metrics/MetricsEndpointDocumentationTests.java index dc508f50a7d4..21c974674342 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/metrics/MetricsEndpointDocumentationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.actuate.docs.metrics; import io.micrometer.core.instrument.Statistic; import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; -import org.springframework.boot.actuate.metrics.MetricsEndpoint; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; +import org.springframework.boot.metrics.actuate.endpoint.MetricsEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusScrapeEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/metrics/export/prometheus/PrometheusScrapeEndpointDocumentationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusScrapeEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/metrics/export/prometheus/PrometheusScrapeEndpointDocumentationTests.java index 4011e15c7116..afae426170d0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusScrapeEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/metrics/export/prometheus/PrometheusScrapeEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; +package org.springframework.boot.actuate.docs.metrics.export.prometheus; import java.util.Properties; @@ -25,7 +25,7 @@ import io.prometheus.metrics.model.registry.PrometheusRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/quartz/QuartzEndpointDocumentationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/quartz/QuartzEndpointDocumentationTests.java index edc3cb529dbb..2ce8eb0ef4a9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/quartz/QuartzEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.quartz; +package org.springframework.boot.actuate.docs.quartz; import java.time.Instant; import java.util.ArrayList; @@ -52,11 +52,11 @@ import org.quartz.impl.matchers.GroupMatcher; import org.quartz.spi.OperableTrigger; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.endpoint.Show; -import org.springframework.boot.actuate.quartz.QuartzEndpoint; -import org.springframework.boot.actuate.quartz.QuartzEndpointWebExtension; import org.springframework.boot.json.JsonWriter; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint; +import org.springframework.boot.quartz.endpoint.QuartzEndpointWebExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/sbom/SbomEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/sbom/SbomEndpointDocumentationTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/sbom/SbomEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/sbom/SbomEndpointDocumentationTests.java index 15274848902a..0f397fddffde 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/sbom/SbomEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/sbom/SbomEndpointDocumentationTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.sbom; +package org.springframework.boot.actuate.docs.sbom; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.sbom.SbomEndpoint; import org.springframework.boot.actuate.sbom.SbomEndpointWebExtension; import org.springframework.boot.actuate.sbom.SbomProperties; @@ -58,7 +58,7 @@ static class TestConfiguration { SbomProperties sbomProperties() { SbomProperties properties = new SbomProperties(); properties.getApplication() - .setLocation("classpath:org/springframework/boot/actuate/autoconfigure/sbom/cyclonedx.json"); + .setLocation("classpath:org/springframework/boot/actuate/docs/sbom/cyclonedx.json"); return properties; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/scheduling/ScheduledTasksEndpointDocumentationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/scheduling/ScheduledTasksEndpointDocumentationTests.java index f354e6bc5770..b6518c77ea60 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/scheduling/ScheduledTasksEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.scheduling; +package org.springframework.boot.actuate.docs.scheduling; import java.time.Instant; import java.util.Collection; @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/session/SessionsEndpointDocumentationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/session/SessionsEndpointDocumentationTests.java index a3c4b5dcf035..d1ee3e18ae39 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/session/SessionsEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.session; +package org.springframework.boot.actuate.docs.session; import java.time.Instant; import java.util.HashMap; @@ -24,9 +24,9 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.context.ShutdownEndpoint; -import org.springframework.boot.actuate.session.SessionsEndpoint; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; +import org.springframework.boot.session.endpoint.SessionsEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/startup/StartupEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/startup/StartupEndpointDocumentationTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/startup/StartupEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/startup/StartupEndpointDocumentationTests.java index bc3694f0b80a..3806ed875b23 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/startup/StartupEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/startup/StartupEndpointDocumentationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.startup; +package org.springframework.boot.actuate.docs.startup; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.startup.StartupEndpoint; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/exchanges/HttpExchangesEndpointDocumentationTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/exchanges/HttpExchangesEndpointDocumentationTests.java index 91279097868a..13a85909d3ad 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/exchanges/HttpExchangesEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/exchanges/HttpExchangesEndpointDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.exchanges; +package org.springframework.boot.actuate.docs.web.exchanges; import java.net.URI; import java.security.Principal; @@ -29,7 +29,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.MockMvcEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.MockMvcEndpointDocumentationTests; import org.springframework.boot.actuate.web.exchanges.HttpExchange; import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; import org.springframework.boot.actuate.web.exchanges.HttpExchangesEndpoint; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointReactiveDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/mappings/MappingsEndpointReactiveDocumentationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointReactiveDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/mappings/MappingsEndpointReactiveDocumentationTests.java index 43aad5712a58..f412a87a0c22 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointReactiveDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/mappings/MappingsEndpointReactiveDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.mappings; +package org.springframework.boot.actuate.docs.web.mappings; import java.time.Duration; import java.util.ArrayList; @@ -25,14 +25,14 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.AbstractEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.AbstractEndpointDocumentationTests; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; -import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.webflux.actuate.mappings.DispatcherHandlersMappingDescriptionProvider; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointServletDocumentationTests.java b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/mappings/MappingsEndpointServletDocumentationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointServletDocumentationTests.java rename to spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/mappings/MappingsEndpointServletDocumentationTests.java index 0bbd54a62626..d42727be9821 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointServletDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/java/org/springframework/boot/actuate/docs/web/mappings/MappingsEndpointServletDocumentationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.mappings; +package org.springframework.boot.actuate.docs.web.mappings; import java.time.Duration; import java.util.ArrayList; @@ -25,16 +25,16 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation.AbstractEndpointDocumentationTests; +import org.springframework.boot.actuate.docs.AbstractEndpointDocumentationTests; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; -import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.FiltersMappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider; +import org.springframework.boot.servlet.actuate.mappings.FiltersMappingDescriptionProvider; +import org.springframework.boot.servlet.actuate.mappings.ServletsMappingDescriptionProvider; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.webmvc.actuate.mappings.DispatcherServletsMappingDescriptionProvider; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/env/application.properties b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/env/application.properties new file mode 100644 index 000000000000..2574e2ee85d6 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/env/application.properties @@ -0,0 +1 @@ +com.example.cache.max-size: 1000 diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/flyway/V1__init.sql b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/flyway/V1__init.sql similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/flyway/V1__init.sql rename to spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/flyway/V1__init.sql diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/liquibase/db.changelog-master.yaml b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/liquibase/db.changelog-master.yaml similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/liquibase/db.changelog-master.yaml rename to spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/liquibase/db.changelog-master.yaml diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/logging/sample.log b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/logging/sample.log similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/logging/sample.log rename to spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/logging/sample.log diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/logging/sample.log.2021-06-15.0.gz b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/logging/sample.log.2021-06-15.0.gz similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/logging/sample.log.2021-06-15.0.gz rename to spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/logging/sample.log.2021-06-15.0.gz diff --git a/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/sbom/cyclonedx.json b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/sbom/cyclonedx.json new file mode 100644 index 000000000000..d5c78df8ea6f --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/org/springframework/boot/actuate/docs/sbom/cyclonedx.json @@ -0,0 +1,4615 @@ +{ + "bomFormat" : "CycloneDX", + "specVersion" : "1.5", + "serialNumber" : "urn:uuid:13862013-3360-43e5-8055-3645aa43c548", + "version" : 1, + "metadata" : { + "timestamp" : "2024-01-12T11:10:49Z", + "tools" : [ + { + "vendor" : "CycloneDX", + "name" : "cyclonedx-gradle-plugin", + "version" : "1.8.1" + } + ], + "component" : { + "group" : "org.example", + "name" : "cyclonedx", + "version" : "0.0.1-SNAPSHOT", + "purl" : "pkg:maven/org.example/cyclonedx@0.0.1-SNAPSHOT?type=jar", + "type" : "library", + "bom-ref" : "pkg:maven/org.example/cyclonedx@0.0.1-SNAPSHOT?type=jar" + } + }, + "components" : [ + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-aop", + "version" : "6.1.2", + "description" : "Spring AOP", + "hashes" : [ + { + "alg" : "MD5", + "content" : "c9b8757051ed6c1cc9fda0e379283348" + }, + { + "alg" : "SHA-1", + "content" : "a247bd81df8fa9c6a002b95969692bfd146a70b2" + }, + { + "alg" : "SHA-256", + "content" : "e47b66833ebec281374d55b4e36352b80fe3fa64c94252481a8a7e8d31d9d601" + }, + { + "alg" : "SHA-512", + "content" : "b1cb69feb2931bd4af48b2329614f8e2a0d1afe77267af5f5ea9717ab24c83fd524c8bc7aa8d357a6ccbc497535c4fd282ddfb6d78364a349895a14825af8b9c" + }, + { + "alg" : "SHA-384", + "content" : "09c3c2711a054993922d28b76357c376649a942bf0d7410915e540339c3fa42d5a498211b02e0b09493e68fac7a0d833" + }, + { + "alg" : "SHA3-384", + "content" : "b30a6ea50e454373bd74779d983fc941bb1775368ea67ff0464edbdf0dd3d1c137760bee64a620bd51daf5b65281f15e" + }, + { + "alg" : "SHA3-256", + "content" : "291404410acd2cfbcc804bd91a9777276f622fb3b82788298254c0bf1856b49f" + }, + { + "alg" : "SHA3-512", + "content" : "8101ef2cc88af43b2bfc6126547de4e4a4cc29bf49bffd83aa9d299cab9e9cdb6a5246d46c00119dd88ca02dbf7959c3076dbd32d23e8e1366144ccbbda13316" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar" + }, + { + "group" : "com.fasterxml.jackson.datatype", + "name" : "jackson-datatype-jdk8", + "version" : "2.15.3", + "description" : "Add-on module for Jackson (http://jackson.codehaus.org) to support JDK 8 data types.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "3b6579ff944e128c4eccb34e76ff67e0" + }, + { + "alg" : "SHA-1", + "content" : "80158cb020c7bd4e4ba94d8d752a65729dc943b2" + }, + { + "alg" : "SHA-256", + "content" : "29995d3677f72dde74bf32bbf268b96beb952492b742d93f4c70af6c44b2156e" + }, + { + "alg" : "SHA-512", + "content" : "1b13d4f0a955af18a2c68ca45deca79c38d7f9f065d7053bddf2a3dc2fafe729b3355676f7442012451e363aa0da0cd8a0b7a44ded7057cf513df98a475cbbf6" + }, + { + "alg" : "SHA-384", + "content" : "9a29961097a15d3aeabc1ab870699dce827511df9902fc66fe9f836d294c8cea68617498d52fe7dbe920bb5c745f2789" + }, + { + "alg" : "SHA3-384", + "content" : "55570097f9979197eafda91156db909f25dd1b37387656893564060a673dcbc6d85c1f5dc6fd5c8b379b48a4974e6757" + }, + { + "alg" : "SHA3-256", + "content" : "362c3a494e16016f7adc3f512ebe8c8f8da4dbdfc1ca285d05ac085a9198258f" + }, + { + "alg" : "SHA3-512", + "content" : "1aebbe19a11236b7dbf85fd4c457e1a9b5a60fad9c818cc9fd462d7eb489dd5d3a378b4c7c42c6e3777e0b70263968c964cf1aaf8247fc97ec445481af2418a8" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.15.3?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.15.3?type=jar" + }, + { + "group" : "org.apiguardian", + "name" : "apiguardian-api", + "version" : "1.1.2", + "description" : "@API Guardian", + "hashes" : [ + { + "alg" : "MD5", + "content" : "8c7de3f82037fa4a2e8be2a2f13092af" + }, + { + "alg" : "SHA-1", + "content" : "a231e0d844d2721b0fa1b238006d15c6ded6842a" + }, + { + "alg" : "SHA-256", + "content" : "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38" + }, + { + "alg" : "SHA-512", + "content" : "d7ccd0e7019f1a997de39d66dc0ad4efe150428fdd7f4c743c93884f1602a3e90135ad34baea96d5b6d925ad6c0c8487c8e78304f0a089a12383d4a62e2c9a61" + }, + { + "alg" : "SHA-384", + "content" : "5ae11cfedcee7da43a506a67946ddc8a7a2622284a924ba78f74541e9a22db6868a15f5d84edb91a541e38afded734ea" + }, + { + "alg" : "SHA3-384", + "content" : "c146116b3dfd969200b2ce52d96b92dd02d6f5a45a86e7e85edf35600ddbc2f3c6e8a1ad7e2db4dcd2c398c09fad0927" + }, + { + "alg" : "SHA3-256", + "content" : "b4b436d7f615fc0b820204e69f83c517d1c1ccc5f6b99e459209ede4482268de" + }, + { + "alg" : "SHA3-512", + "content" : "7b95b7ac68a6891b8901b5507acd2c24a0c1e20effa63cd513764f513eab4eb55f8de5178edbe0a400c11f3a18d3f56243569d6d663100f06dd98288504c09c5" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/apiguardian-team/apiguardian" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar" + }, + { + "group" : "jakarta.annotation", + "name" : "jakarta.annotation-api", + "version" : "2.1.1", + "description" : "Jakarta Annotations API", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5dac2f68e8288d0add4dc92cb161711d" + }, + { + "alg" : "SHA-1", + "content" : "48b9bda22b091b1f48b13af03fe36db3be6e1ae3" + }, + { + "alg" : "SHA-256", + "content" : "5f65fdaf424eee2b55e1d882ba9bb376be93fb09b37b808be6e22e8851c909fe" + }, + { + "alg" : "SHA-512", + "content" : "eabe8b855b735663684052ec4cc357cc737936fa57cebf144eb09f70b3b6c600db7fa6f1c93a4f36c5994b1b37dad2dfcec87a41448872e69552accfd7f52af6" + }, + { + "alg" : "SHA-384", + "content" : "798597a6b80b423844d70609c54b00d725a357031888da7e5c3efd3914d1770be69aa7135de13ddb89a4420a5550e35b" + }, + { + "alg" : "SHA3-384", + "content" : "9629b8ca82f61674f5573723bbb3c137060e1442062eb52fa9c90fc8f57ea7d836eb2fb765d160ec8bf300bcb6b820be" + }, + { + "alg" : "SHA3-256", + "content" : "f71ffc2a2c2bd1a00dfc00c4be67dbe5f374078bd50d5b24c0b29fbcc6634ecb" + }, + { + "alg" : "SHA3-512", + "content" : "aa4e29025a55878db6edb0d984bd3a0633f3af03fa69e1d26c97c87c6d29339714003c96e29ff0a977132ce9c2729d0e27e36e9e245a7488266138239bdba15e" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + }, + { + "license" : { + "id" : "GPL-2.0-with-classpath-exception" + } + } + ], + "purl" : "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://github.com/eclipse-ee4j/common-annotations-api/issues" + }, + { + "type" : "mailing-list", + "url" : "https://dev.eclipse.org/mhonarc/lists/ca-dev" + }, + { + "type" : "vcs", + "url" : "https://github.com/eclipse-ee4j/common-annotations-api" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar" + }, + { + "group" : "com.fasterxml.jackson.core", + "name" : "jackson-annotations", + "version" : "2.15.3", + "description" : "Core annotations used for value types, used by Jackson data binding package.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "f478f693731e4a2f0f0d3c7bba119b32" + }, + { + "alg" : "SHA-1", + "content" : "79baf4e605eb3bbb60b1c475d44a7aecceea1d60" + }, + { + "alg" : "SHA-256", + "content" : "aae865c3d88256d61b11523cb1e88bd48d5b9ad5855fa1fc859504fd2204708a" + }, + { + "alg" : "SHA-512", + "content" : "c496afd736fa8acbf8126887e2ff375f162212f451326451fbb4b9194231d814e25bccacbaead9db98beec454f6b8d9ed706c5c88e2145bf7e1a37e13fd81af0" + }, + { + "alg" : "SHA-384", + "content" : "13b4d153cc113a69008147974d8887f868f2f3f0a551ef0bacaccf0add17a3168465a94a471e075913f9c6649980a3cb" + }, + { + "alg" : "SHA3-384", + "content" : "dcf8ed73f748eb32e1ab25eba3c294344cc0ddb2cc7bb4376814f1866df42c3093f1336291ce9ed9e1c8730663e0017c" + }, + { + "alg" : "SHA3-256", + "content" : "59f42bc85ee3a8a5b422085b0462aed2a770cf52d7a3660f2cd6dd257ec6e694" + }, + { + "alg" : "SHA3-512", + "content" : "1d1a6fd0e6851d419e79f82170f4060981c233ec8dc61656b84ce7988e9b71bbeecd7364cdadac066ddaf0b3de4dc8aa5acc411ebd1641f549a3af5ba214667b" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/FasterXML/jackson-annotations" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-jcl", + "version" : "6.1.2", + "description" : "Spring Commons Logging Bridge", + "hashes" : [ + { + "alg" : "MD5", + "content" : "1638acc7030a001c37f803185dbd6eaf" + }, + { + "alg" : "SHA-1", + "content" : "285eb725861c9eacf2a3e4965d4e897932e335ea" + }, + { + "alg" : "SHA-256", + "content" : "eb9ebadb1581f0fe598216f7cf032a3b44a84c96de06ffa8d6f41bcc47305134" + }, + { + "alg" : "SHA-512", + "content" : "2e80d7485b7ad4de6cc372d86ed73db9808be6a5a33e3c9fabccc7915fe57b73011bed75b4567c44456fedad5ae2186658a7f5cc331b4aad64e2a7cc78acdcfa" + }, + { + "alg" : "SHA-384", + "content" : "a6a6422a6c2654eff951af0d6dfb6e93501bdcb4e38ec353d515ca8de919a34b9e1fe37c562106f3f33f844cf071e010" + }, + { + "alg" : "SHA3-384", + "content" : "71098eb263af3ab42d93b8e7a96ceb90fb2069f2ecca85754e702b82f9876255abf5e3f9b48beb4a200f2d9e13599794" + }, + { + "alg" : "SHA3-256", + "content" : "7f49ddd5db9841bb2d7ca8cb5ce52fa1e8982c7c37bc0c6e987eca8f5fc70d38" + }, + { + "alg" : "SHA3-512", + "content" : "4a417d058ecd3619a9716c5d47ecc506f4cb9c3684ee589c443c7b7996b630949932295186135cb3ce5fb0154c29436de4b6c1dbf7f135563449050973510200" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-jcl@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-jcl@6.1.2?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-webmvc", + "version" : "6.1.2", + "description" : "Spring Web MVC", + "hashes" : [ + { + "alg" : "MD5", + "content" : "0fcf00ac160e0d42ad9cd242c796e47a" + }, + { + "alg" : "SHA-1", + "content" : "906ee995372076e22ef9666d8628845c75bf5c42" + }, + { + "alg" : "SHA-256", + "content" : "de42748c3c94c06131c3fe97d81f5c685e4492b9e986baa88af768bb12ea7738" + }, + { + "alg" : "SHA-512", + "content" : "8e7ad7afa2a605d8dbb6cb36c11caf0e626a5ca5849c06f0b35524e5ad6a13eec1ddff8625e1cc278b3082555a940ec3865657828458ab8d60d1c99d513aba0f" + }, + { + "alg" : "SHA-384", + "content" : "5ec328ff12f857baf85ce6f44c849f8818658aaabb4e4d0940ea6b5ad2b009ce3c7717b6b02843f641f8125d0cec4291" + }, + { + "alg" : "SHA3-384", + "content" : "75605b286d839df688bbfb9594dbb83d1eb22f2cae52a6f4b35d485e91ab94a55e94158086684ef3b059f1346af6dc85" + }, + { + "alg" : "SHA3-256", + "content" : "2e67bcc31eede462f5105a09dbf5b40a3e0ccc52d637c6e2720b43412da01525" + }, + { + "alg" : "SHA3-512", + "content" : "d7c5330069c3c0f5eda1417a52384a4b5adc4451c405315a992ed147f26466a19487ffc5e39b90a1ec4cb0df3f804a4d26203f9aaf4e74cf906d1e811abfbf3b" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-webmvc@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-webmvc@6.1.2?type=jar" + }, + { + "group" : "org.apache.tomcat.embed", + "name" : "tomcat-embed-websocket", + "version" : "10.1.17", + "description" : "Core Tomcat implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "cfc1778713fba9b5bc33d3db64071dff" + }, + { + "alg" : "SHA-1", + "content" : "9ee2f34b51144b75878c9b42768e17de8fbdc74b" + }, + { + "alg" : "SHA-256", + "content" : "00b16e507bea58c6e8a7cb64f129cd2ffd62da092a67a693a8a6af1efdc7dd6d" + }, + { + "alg" : "SHA-512", + "content" : "72da073d4ec4f7473c9a91b4d11607d02a3d18ca8af10348f9130a280f898814625a5865cb44244e6be6d6ab915099805bf06a60f80fd9b8ff2c47840d5266e9" + }, + { + "alg" : "SHA-384", + "content" : "3f4c1d108ca60a7a658839b8ac45eba94354ad20e641d36d2ecf777bac252d371df1e8806a5460ccaf9da222f72a4a9c" + }, + { + "alg" : "SHA3-384", + "content" : "2d0703de58338d38fbae7f4a38390a766d66e3875e3a6a7f2620ae478c838c8f306a39cdac8652890e1116a3859e56e1" + }, + { + "alg" : "SHA3-256", + "content" : "e594abbc4cb6dc0896c08a89cb3fa376980587d5995bace2b3c0798d99c1e454" + }, + { + "alg" : "SHA3-512", + "content" : "3a35964398627fc8bcd323dd9fb6d4e51ea183b704074320822906c074aeb50a0f8732e42b98bdad9c5f0aa4eb421da96dde7e97f094ccdbcb70f668c6d4ff6e" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.17?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.17?type=jar" + }, + { + "group" : "net.bytebuddy", + "name" : "byte-buddy", + "version" : "1.14.10", + "description" : "Byte Buddy is a Java library for creating Java classes at run time. This artifact is a build of Byte Buddy with all ASM dependencies repackaged into its own name space.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "4e5bd83559bf8533b51f92dcd911d16c" + }, + { + "alg" : "SHA-1", + "content" : "8117daf4a612122eb4f517f66adff778cb8b4737" + }, + { + "alg" : "SHA-256", + "content" : "30e6e0446437a67db37e2b7f7d33f50787ddfd970359319dfd05469daa2dcbce" + }, + { + "alg" : "SHA-512", + "content" : "583512f3c47513cf17735aad4e600be44c97e9978c9f6a45227de8a160a879960b1fe01672751e7583176935e0db5477aba581bf68ef5c94f52436a0683a306e" + }, + { + "alg" : "SHA-384", + "content" : "efcce5a139f498de410e182a52e5b2465823a2ebf845001c9a733d87418118342c3854d00a0fae7945ae8dcb1916ba90" + }, + { + "alg" : "SHA3-384", + "content" : "cace3217b1c2c77a4bc194ecc602a28886d9e448efa26b1985e9fd09d90c92bc2e1b50ed70475106ddf266f8c2d14160" + }, + { + "alg" : "SHA3-256", + "content" : "71647273afb1561b70d2cfa519f707a98711f9ae5b891249ae5803c00c25a788" + }, + { + "alg" : "SHA3-512", + "content" : "4aba6f5dcac177c8f8aed902307c62916c32be61841adcf12b9c9885de2de9795a965c0b939729ed67ee7d49b0fbfaf0dfd922be1bf1cdbfbe7b1f09e083831b" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-test-autoconfigure", + "version" : "3.2.1", + "description" : "Spring Boot Test AutoConfigure", + "hashes" : [ + { + "alg" : "MD5", + "content" : "d6f93aa42df4cb27a58835750597d835" + }, + { + "alg" : "SHA-1", + "content" : "bfc34c523b3ab295fb01f46373e903f9729cdd43" + }, + { + "alg" : "SHA-256", + "content" : "86c51c743babfc591be09af7fedcd778410706e567e9ed27218448ccd2297ef4" + }, + { + "alg" : "SHA-512", + "content" : "701b6ee27c87081e4a65ba76fe721f74e917a655575b19b9205b314f4a561889564e09ceadaa880aaf30f70cd8b48dc70fc5e32f511204b1ea031a12349fd9be" + }, + { + "alg" : "SHA-384", + "content" : "74d4cf202399e946789a5572007aa4fbf1daf26cfac27f83a3d8550711f99700083029b1f900037b8f263543ac9824a1" + }, + { + "alg" : "SHA3-384", + "content" : "ac0b64ec94b558b4f806c09f68247eff80bcc8e33b97f5d09f5517a2339187e4b11c8e2287400a173cb128e3fdb4ab06" + }, + { + "alg" : "SHA3-256", + "content" : "5ca85cd0c052076d625c262cf445e4e8fb255b13323ba4ab08cbfcf32ec236b3" + }, + { + "alg" : "SHA3-512", + "content" : "04ce88c724852938057c723a7ec637af2f8e601879a592a6fe135eaa26940f8fd9d9ac8f6917e761cb0ff31547bb849ff88a66e1f6e93c1032a4009fe1fdef1d" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.2.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-json", + "version" : "3.2.1", + "description" : "Starter for reading and writing json", + "hashes" : [ + { + "alg" : "MD5", + "content" : "bea54cf408b022894c0b1b013c58c0a9" + }, + { + "alg" : "SHA-1", + "content" : "ecda50de20ab6d3c49ea30df4c1982048f5d31ac" + }, + { + "alg" : "SHA-256", + "content" : "572f1a4171dff33b5a9260bbd704473442adf24f890386abe33ecc18c047836a" + }, + { + "alg" : "SHA-512", + "content" : "c611e0d07093d99dbcded7a00e7c00355a7c13c24a69d33105ca88ec63cc68ba76339b5a96b84f2b666bb883849980776e1e24ee2df9c7dd07b2dde0992289b5" + }, + { + "alg" : "SHA-384", + "content" : "ed40ffb527cf8442dbe3eb7b542970317e4827ed00196387d78f123490a77b08b3bc2fd5f53b83f6bee1d4eed29215bf" + }, + { + "alg" : "SHA3-384", + "content" : "26d5852f479f1c72f501569a8ea0c0e4c93f9049676921dca94b467e68f221214e4485c41647e6a92005e5090a6a7c80" + }, + { + "alg" : "SHA3-256", + "content" : "dc69eefb2f1441bbec58c219ccedd895b863b1e1d25cc3805936f0c9b072f2e6" + }, + { + "alg" : "SHA3-512", + "content" : "bf6fce60937e78550fb3d411c19aad2200d8129138fade809e9d0abc307c7f06b54732f1e94fa86ebb82d4da0293f7bce43345416b3fdae1b3c2edbac6706310" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-json@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-json@3.2.1?type=jar" + }, + { + "group" : "com.fasterxml.jackson.datatype", + "name" : "jackson-datatype-jsr310", + "version" : "2.15.3", + "description" : "Add-on module to support JSR-310 (Java 8 Date & Time API) data types.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "acd8ae6da000eb831a69b4acdc182b7f" + }, + { + "alg" : "SHA-1", + "content" : "4a20a0e104931bfa72f24ef358c2eb63f1ef2aaf" + }, + { + "alg" : "SHA-256", + "content" : "bea1d78009ebc4e5d54918a3f7aec5da9fbd09f662c191a217ffcf37e8527c5e" + }, + { + "alg" : "SHA-512", + "content" : "1c5bde6c91a2a89f3c1f231f4e17c435063d9012babbfcba509a3b25363b1fd99f0dcd4234f1e00559e43d3dc8e6c71834282c72f2ebf15484ae900754c5d757" + }, + { + "alg" : "SHA-384", + "content" : "cc72f54d89bc0f7ffae9af36dfba38e5a61ac83db2f0d8de3c74e405a0bfd77b6d463217ece19c64eeb16291d80a69f5" + }, + { + "alg" : "SHA3-384", + "content" : "096944bac7583e5c97e8afcfbc928ca4a87a7d3e5eb74cc77394a19ca8bc6f26185da7fdf5d6bd2179582bf51940edc5" + }, + { + "alg" : "SHA3-256", + "content" : "0301cf719fd327643b3228b91c36688aaea3fccf3487c3e09bae3de636340dc7" + }, + { + "alg" : "SHA3-512", + "content" : "b9a4a8c9785e8ec2786690bfede18c76e08d81fc9c77bb2dad88e1a034f97f7d20020531ac1cb9b0b6e61645b08ea441aba35fc0732edc2fc1dc4b36d6f1695c" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar" + }, + { + "group" : "org.hdrhistogram", + "name" : "HdrHistogram", + "version" : "2.1.12", + "description" : "HdrHistogram supports the recording and analyzing sampled data value counts across a configurable integer value range with configurable value precision within the range. Value precision is expressed as the number of significant digits in the value recording, and provides control over value quantization behavior across the value range and the subsequent value resolution at any given level.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "4b1acf3448b750cb485da7e37384fcd8" + }, + { + "alg" : "SHA-1", + "content" : "6eb7552156e0d517ae80cc2247be1427c8d90452" + }, + { + "alg" : "SHA-256", + "content" : "9b47fbae444feaac4b7e04f0ea294569e4bc282bc69d8c2ce2ac3f23577281e2" + }, + { + "alg" : "SHA-512", + "content" : "b03b7270eb7962c88324858f94313adb3a53876f1e11568a78a5b7e00a9419e4d7ab8774747427bff6974b971b6dfc47a127fca11cb30eaf7d83b716e09b1a0d" + }, + { + "alg" : "SHA-384", + "content" : "06977d680dafd803d32441994474e598384a584411a67c95ab4a64698c9e4cbd613e0119b54685cea275b507a0a6f362" + }, + { + "alg" : "SHA3-384", + "content" : "b5ccb4d39bf7cc8ccc33f0f8fcbab0a63c99a94feda840b5d80fc3ae061127f1475cfb869b060933783a1f2eafb103a1" + }, + { + "alg" : "SHA3-256", + "content" : "ef2113f27862af1d24d90c2028fc566902720248468d3c0f2f1807cc86918882" + }, + { + "alg" : "SHA3-512", + "content" : "4fca2f75bdfd3f2ac40dc227ae2ef0272142802b1546d4f5edf9155eaeed84eff07b0c3a978291a1df096ec94724b0defb045365e6a51acfdd5da68d72c5a8eb" + } + ], + "licenses" : [ + { + "license" : { + "id" : "CC0-1.0" + } + }, + { + "license" : { + "id" : "BSD-2-Clause", + "url" : "https://opensource.org/licenses/BSD-2-Clause" + } + } + ], + "purl" : "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://github.com/HdrHistogram/HdrHistogram/issues" + }, + { + "type" : "vcs", + "url" : "scm:git:git://github.com/HdrHistogram/HdrHistogram.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12?type=jar" + }, + { + "group" : "io.micrometer", + "name" : "micrometer-commons", + "version" : "1.12.1", + "description" : "Module containing common code", + "hashes" : [ + { + "alg" : "MD5", + "content" : "2518ae277e56aea5e37e3fc2f578dfa4" + }, + { + "alg" : "SHA-1", + "content" : "abcc6b294e60582afdfae6c559c94ad1d412ce2d" + }, + { + "alg" : "SHA-256", + "content" : "295785b04cd4de7711bb16730da5e9829bac55a8879d52120625dac6c89904ed" + }, + { + "alg" : "SHA-512", + "content" : "25d65699a25fe3b90de17a0539233fdad37df864f6d493475976e9a513bd7767520a882cbf6bbd98714a1fe94acdb77a160cd68f549475d2b93624ffe8672a00" + }, + { + "alg" : "SHA-384", + "content" : "8523ae45ce6dd4a068cce108cd31da24629839d3d293fca92353cf45db9eae88107744c9e66b82ed14abb96782c562da" + }, + { + "alg" : "SHA3-384", + "content" : "9af1fc3aad2d0131c337b843c38b05510d31e7931a48841a4bdb618257f185286ed393f8a4418ae4c5f91da7f9c76cbf" + }, + { + "alg" : "SHA3-256", + "content" : "d5dbeadc5f629430202c81a6736dff2efbfbf3ea2c09844b1194f316772a93f7" + }, + { + "alg" : "SHA3-512", + "content" : "c7b1dd1727000936bf51c02f9bf9b262a412e2b815531df4a9f7aad675ef0f728d4492327a404b37b1ef36d41a240b83dbfeea3367b3b4faa22cdc2decc5bac9" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar" + }, + { + "group" : "org.mockito", + "name" : "mockito-core", + "version" : "5.7.0", + "description" : "Mockito mock objects library core API and implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "4df8dd230071bc192161d0e54a76f6b5" + }, + { + "alg" : "SHA-1", + "content" : "a1c258331ab91d66863c983aff7136357e9de056" + }, + { + "alg" : "SHA-256", + "content" : "dbad5e746654910a11a59ecb4d01e38461f3e5d16161689dc2588d5554432521" + }, + { + "alg" : "SHA-512", + "content" : "5a2f00df2b1b2dbca06686f88806b86990f1eea6f7c25281c0e7ec7cf7904a0a9227477279b11630d80f8e88d6b6e9dbdb40ad094a4077cc6a44cd2072d12662" + }, + { + "alg" : "SHA-384", + "content" : "3f2caa05fe4a5d5b385654ce60d0655724200fdd333652459b86848c3b895a9ad0b0daca8a014851d6b5c744cd0e9372" + }, + { + "alg" : "SHA3-384", + "content" : "06ba4583220a4aaa47d79ccab11783d48900d8850a346e4a1efc61c057630fcf0bb9c95cec74833ab5e6ee08e55625ec" + }, + { + "alg" : "SHA3-256", + "content" : "f1f9899edf629fffaf8b4483ac04430945996393f4fdcedc38eba22a9a5c715d" + }, + { + "alg" : "SHA3-512", + "content" : "d6f479d52534b382088012e3d1a83fa267dfb046322a72e84438d21973165617d1d710bb42f1cb2d2d3d7f891969320232031be33f4abb2ea1526217e16e8c63" + } + ], + "licenses" : [ + { + "license" : { + "id" : "MIT", + "url" : "https://opensource.org/licenses/MIT" + } + } + ], + "purl" : "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "build-system", + "url" : "https://github.com/mockito/mockito/actions" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/mockito/mockito/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/mockito/mockito.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-actuator-autoconfigure", + "version" : "3.2.1", + "description" : "Spring Boot Actuator AutoConfigure", + "hashes" : [ + { + "alg" : "MD5", + "content" : "3afea56b25f872cee2c929c761b0790d" + }, + { + "alg" : "SHA-1", + "content" : "0fe81034352a15731322fba326447ba70bfa3962" + }, + { + "alg" : "SHA-256", + "content" : "3850d85c0f6074fe9286dece9b44f8bded5e194e9b816860735e0fc728173d65" + }, + { + "alg" : "SHA-512", + "content" : "7197158ef14a580edc836ab7af10a9f5f567ba60e21267b624fc4143debd2638c7b8bd8e2e5973fdd5c5d512be73df96500fb0a4273f20a21b42161e9f7add75" + }, + { + "alg" : "SHA-384", + "content" : "4a35eb1f124d8d7812d32f87b16a24dd56d4cb43278ce66f216f4a4af34db357e7481fc1b26de9bde7c2dd6847687721" + }, + { + "alg" : "SHA3-384", + "content" : "8369a8b49cae80b92abbfcc0218d55b9cecd86778735c66b9b0cc6fbc7251784725249392e716c314e3ec08c995557bb" + }, + { + "alg" : "SHA3-256", + "content" : "ee742160e4951e1f6145d575f6c6ebb908a46f38a8b3b81b7d61aac7c111a87f" + }, + { + "alg" : "SHA3-512", + "content" : "dcb1b214577203c9b3e2e5dcb3aaef8e46aec5f75a40a606f42e230c6e1af39c37250d58de6bf694c5a62d70fb1a6dcba436d696f71d7aa1a52b9f4dea5aa9a9" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.2.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-tomcat", + "version" : "3.2.1", + "description" : "Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web", + "hashes" : [ + { + "alg" : "MD5", + "content" : "db4df0f653e84bfd545894c4567b19ff" + }, + { + "alg" : "SHA-1", + "content" : "d8efc48034015522958cb3fea5831b4cbcd4fcfb" + }, + { + "alg" : "SHA-256", + "content" : "bf93da73a8fb4caf9fa68e4f3b97adcc9dbb8c79220a828b3d70ecf12d410117" + }, + { + "alg" : "SHA-512", + "content" : "d2bce5bb0271525766283e17160513de530c20e0452cecc3c9d5be3890986cc071c1423a3c11c54a36d2f83bd3a238b0fcbcc6218976a5633f0753a313418f6f" + }, + { + "alg" : "SHA-384", + "content" : "1f9ae7504b1345595377a4d35163315824dcf25f29ac9d522385e6e1672b813719655989708eb03b419e808f1f102be9" + }, + { + "alg" : "SHA3-384", + "content" : "9d890c3314b5ec30f39de30bf70471aef5f19e64d6d2f60b6fe66b3c57978bbda0a981cf92e42f18f27b72ed2ddb3574" + }, + { + "alg" : "SHA3-256", + "content" : "43d38219fbe556c2bac8670fa0aa4f89e2ac273fda77d8bceac8d9d34d7b27c2" + }, + { + "alg" : "SHA3-512", + "content" : "6a4e9a2ff89293c60c8a05cb79a65695dbe9823978be93f1b309d702338f87f108aabeaeafe8ff0ebf08bcd5483efbbb4a85c566e1357acd1d2fab565c910a80" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-tomcat@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-tomcat@3.2.1?type=jar" + }, + { + "group" : "org.apache.logging.log4j", + "name" : "log4j-to-slf4j", + "version" : "2.21.1", + "description" : "The Apache Log4j binding between Log4j 2 API and SLF4J.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "00b957af4a40bea6a7bf61400b6ccf63" + }, + { + "alg" : "SHA-1", + "content" : "d77b2ba81711ed596cd797cc2b5b5bd7409d841c" + }, + { + "alg" : "SHA-256", + "content" : "de143c565ba78b0f2c0be58f132c7aec75e6e1a10845ebda5a4f17c2a35d9990" + }, + { + "alg" : "SHA-512", + "content" : "8a7a682dc5ae6a123c8de6002f1470ad2682795c65b47b06397d9ad9a31729e588c406013bfa989f9c2a51750c353cd7a147bc036f2d66b0f8f0b3f13798a637" + }, + { + "alg" : "SHA-384", + "content" : "8f3e4f1eea069f47b2c6111f1233448ea9ccc723b7c8a8bd308b7317a6ec1f47008d2952c1cb274152a38d3e21da750b" + }, + { + "alg" : "SHA3-384", + "content" : "822f93c3bba450b89a7f64b4d81aab48a7f5c2f693b53a4dcc83eba3a8300ff90c9e7727223f3491c782c80bee9dc707" + }, + { + "alg" : "SHA3-256", + "content" : "1f3f3aace32b45e9a6271c7b4ac76ddf86eb4f32e28e147a3e054dc8c836def1" + }, + { + "alg" : "SHA3-512", + "content" : "bb61c16d22aeed2d6b18972f68a6c4670fb8a07eeb79407748a7d499bc64e8ad8eb9774d372d9286227665686fe90878f2ef7e7f8595b74cd448d0f847aec02e" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0", + "url" : "https://www.apache.org/licenses/LICENSE-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.21.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.21.1?type=jar" + }, + { + "group" : "jakarta.xml.bind", + "name" : "jakarta.xml.bind-api", + "version" : "4.0.1", + "hashes" : [ + { + "alg" : "MD5", + "content" : "e62084f1afb23eccde6645bf3a9eb06f" + }, + { + "alg" : "SHA-1", + "content" : "ca2330866cbc624c7e5ce982e121db1125d23e15" + }, + { + "alg" : "SHA-256", + "content" : "287f3b6d0600082e0b60265d7de32be403ee7d7269369c9718d9424305b89d95" + }, + { + "alg" : "SHA-512", + "content" : "dcc70e8301a7f274bbb6d6b3fe84ad8c9e5beda318699c05aeac0c42b9e1e210fc6953911be2cb1a2ef49ac5159c331608365b1b83a14a8e86f89f630830dd28" + }, + { + "alg" : "SHA-384", + "content" : "16ff377d0cfd7d8f23f45417e1e0df72de7f77780832ae78a1d2c51d77c4b2f8d270bd9ce4b73d07b70b060a9c39c56e" + }, + { + "alg" : "SHA3-384", + "content" : "773fd2d1e1a647bea7a5365490483fd56e7a49d9b731298d3202b4f93602c9a1a7add0eee868bc5a7ac961da7dda8c8e" + }, + { + "alg" : "SHA3-256", + "content" : "26214bba5cee45014859be8018dc631c14146e0a5959bb88e05d98472c88de8b" + }, + { + "alg" : "SHA3-512", + "content" : "32bdc043b7d616d73bbc26e0b36308126b15658cd032a354770760c5b5656429a4240dd3ddcea835556e813b6ae8618307ebeb96e2e46ba8ab16f6a485fa4d32" + } + ], + "licenses" : [ + { + "license" : { + "id" : "BSD-3-Clause" + } + } + ], + "purl" : "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.1?type=jar" + }, + { + "group" : "org.yaml", + "name" : "snakeyaml", + "version" : "2.2", + "description" : "YAML 1.1 parser and emitter for Java", + "hashes" : [ + { + "alg" : "MD5", + "content" : "d78aacf5f2de5b52f1a327470efd1ad7" + }, + { + "alg" : "SHA-1", + "content" : "3af797a25458550a16bf89acc8e4ab2b7f2bfce0" + }, + { + "alg" : "SHA-256", + "content" : "1467931448a0817696ae2805b7b8b20bfb082652bf9c4efaed528930dc49389b" + }, + { + "alg" : "SHA-512", + "content" : "11547e75cc80bee26f532e2598bc6e4ffa802941496dc0d8ce017f1b15e01ebbb80e91ed17d1047916e32bf2fc58da532bc71a1dfe93afccc277a296d86634ba" + }, + { + "alg" : "SHA-384", + "content" : "dae0cb1a7ab9ccc75413f46f18ae160e12e91dfef0c17a07ea547a365e9fb422c071aa01579f2a320f15ce6ee4c29038" + }, + { + "alg" : "SHA3-384", + "content" : "654b418f330fa02f1111a20c27395ec5c7f463907ae44f60057c94da04f81e815cf1c3959f005026381ef79030049694" + }, + { + "alg" : "SHA3-256", + "content" : "2c4deb8d79876b80b210ef72dc5de2b19607e50fbe3abf09a4324576ca0881fc" + }, + { + "alg" : "SHA3-512", + "content" : "0d9be5610b2bcb6bb7562ee8bcc0d68f81d3771958ce9299c5e57e8ec952c96906d711587b7f72936328c72fb41687b4f908c4de3070b78cc1f3e257cf4b715e" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.yaml/snakeyaml@2.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://bitbucket.org/snakeyaml/snakeyaml/issues" + }, + { + "type" : "vcs", + "url" : "https://bitbucket.org/snakeyaml/snakeyaml/src" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.yaml/snakeyaml@2.2?type=jar" + }, + { + "group" : "org.junit.platform", + "name" : "junit-platform-commons", + "version" : "1.10.1", + "description" : "Module \"junit-platform-commons\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "cd430f3f7345c0888f8408ce8795c751" + }, + { + "alg" : "SHA-1", + "content" : "2bfcd4a4e38b10c671b6916d7e543c20afe25579" + }, + { + "alg" : "SHA-256", + "content" : "7d9855ee3f3f71f015eb1479559bf923783243c24fbfbd8b29bed8e8099b5672" + }, + { + "alg" : "SHA-512", + "content" : "4aa83350e7a6df21feb9ba8756bb4a68986f33f8c6e384720d1daa448444016c0def1781729788e3e884664abd6703b1e3c0ec6b79893a9d5645c3a4809c0ad2" + }, + { + "alg" : "SHA-384", + "content" : "d264f2c8ceaff384b0f22ee77890195ed3d918b01f338e35fc2ee12f82df15e59533918509f535883b4f4befed28595e" + }, + { + "alg" : "SHA3-384", + "content" : "d1fa76d6b2567e831b37ff7843df6d7d65028d4e53c570c6f580cbbf13269d2aa2afedfedfe5a3f2cf92d7de6d3c89b2" + }, + { + "alg" : "SHA3-256", + "content" : "eef0f968f2d2fc31f8b4a4ed43bafeb46977de1ac3d59477ab6e2b014f97e070" + }, + { + "alg" : "SHA3-512", + "content" : "93340cc2c378c830c755b25006bc4f73ec77ad10661f05625b23efa0854d456da8e62bdbe7e7edf3418dda864e6e0d7a6b9d34cea23d525b8991258f3d75fc9c" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.platform/junit-platform-commons@1.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.platform/junit-platform-commons@1.10.1?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-web", + "version" : "6.1.2", + "description" : "Spring Web", + "hashes" : [ + { + "alg" : "MD5", + "content" : "a39761bc7a706c70f6ca3ab805a97b34" + }, + { + "alg" : "SHA-1", + "content" : "0f26b98778376cc39afb04fbb6fdd7543bef89f2" + }, + { + "alg" : "SHA-256", + "content" : "3f2012a24c6213f155b6bc69aa3ecafe2a373c1e92a26dbecc62ff575c3a1fb3" + }, + { + "alg" : "SHA-512", + "content" : "f07f054feaf53c2a97b82150882281035824cf0b815f317a22ba1954afa721bc5d57cb07faa19bad99fc235373b62edd7013f7ac2cd0a3d0db91faf49f216741" + }, + { + "alg" : "SHA-384", + "content" : "57418cf2a9b3256201c0874e7721966b09929030c64f5e5a85007bd645294dfbf1a14d4632a5aa5fcf70af5bf733d542" + }, + { + "alg" : "SHA3-384", + "content" : "83daa608abc0124ec237f65231d5f1dd1a5d751e459d3ea255a3d12a56e92ac83037fb72c5793f497fbecb9e389eb299" + }, + { + "alg" : "SHA3-256", + "content" : "1a17acdfa8920b1849a16e4260bb4b960f60da07732148a5281cfcba21d1e4a8" + }, + { + "alg" : "SHA3-512", + "content" : "3e5e020cb1068250eb0e58e9bc0368c44db96d59022047ecffe286a51b0896e4320d9696f2f9136b4c0aed547d8dd1af1bbc2b4b053aa994246bb43bd7397f05" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-web@6.1.2?type=jar" + }, + { + "group" : "org.objenesis", + "name" : "objenesis", + "version" : "3.3", + "description" : "A library for instantiating Java objects", + "hashes" : [ + { + "alg" : "MD5", + "content" : "ab0e0b2ab81affdd7f38bcc60fd85571" + }, + { + "alg" : "SHA-1", + "content" : "1049c09f1de4331e8193e579448d0916d75b7631" + }, + { + "alg" : "SHA-256", + "content" : "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb" + }, + { + "alg" : "SHA-512", + "content" : "1fa990d15bd179f07ffbc460d580a6fd0562e45dee8bd4a9405917536b78f45c0d6f644b67f85d781c758aa56eff90aef23eedcc9bd7f5ff887a67b716083e61" + }, + { + "alg" : "SHA-384", + "content" : "2f6878f91a12db32c244afcee619d57c3ad6ff0297f4e41c2247e737c1ccc5fcc1ce03256b479b0f9b87900410bc4502" + }, + { + "alg" : "SHA3-384", + "content" : "a3dd9f6908fe732900d50eb209988183ffcf511afb4e401ef95b75c51777709d2d10e1dc9ee386b7357c5c2cbcf8c00e" + }, + { + "alg" : "SHA3-256", + "content" : "fd2b66d174ed68cbfcda41d5cbd29db766c5676866d6b2324b446a87afab3a9f" + }, + { + "alg" : "SHA3-512", + "content" : "ef509e8bcea73bc282287205ffc7625508080be44c16948137274f189459624891dcf109118c9feff109e1aa99becf176f8db837ac4fd586201510c3ae2ea30a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.objenesis/objenesis@3.3?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.objenesis/objenesis@3.3?type=jar" + }, + { + "group" : "com.vaadin.external.google", + "name" : "android-json", + "version" : "0.0.20131108.vaadin1", + "description" : "  JSON (JavaScript Object Notation) is a lightweight data-interchange format. This is the org.json compatible Android implementation extracted from the Android SDK  ", + "hashes" : [ + { + "alg" : "MD5", + "content" : "10612241a9cc269501a7a2b8a984b949" + }, + { + "alg" : "SHA-1", + "content" : "fa26d351fe62a6a17f5cda1287c1c6110dec413f" + }, + { + "alg" : "SHA-256", + "content" : "dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79" + }, + { + "alg" : "SHA-512", + "content" : "c4a06a0a3ce7bdbee702c06944265c050a4c8d2fbd21c248936e2edfdab63acea30f2cf3568d3c21a559940d939985a8b10d30aff972a3e8cbeb392c0b02da3a" + }, + { + "alg" : "SHA-384", + "content" : "60d1044b5439cdf5eb621118cb0581365ab4f023a30998b238b87854236f03d8395d45b0262fb812335ff904cb77f25f" + }, + { + "alg" : "SHA3-384", + "content" : "b80ebdbec2127279ca402ca52e50374d3ca773376258f6aa588b442822ee7362de8cca206db71b79862bde84018cf450" + }, + { + "alg" : "SHA3-256", + "content" : "6285b1ac8ec5fd339c7232affd9c08e6daf91dfa18ef8ae7855f52281d76627e" + }, + { + "alg" : "SHA3-512", + "content" : "de7ed83f73670213b4eeacfd7b3ceb7fec7d88ac877f41aeaacf43351d04b34572f2edc9a8f623af5b3fccab3dac2cc048f5c8803c1d4dcd1ff975cd6005124d" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0", + "url" : "https://www.apache.org/licenses/LICENSE-2.0" + } + } + ], + "purl" : "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "distribution", + "url" : "http://oss.sonatype.org/content/repositories/vaadin-releases/" + }, + { + "type" : "vcs", + "url" : "http://developer.android.com/sdk/" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-logging", + "version" : "3.2.1", + "description" : "Starter for logging using Logback. Default logging starter", + "hashes" : [ + { + "alg" : "MD5", + "content" : "7ac01b9dee045285c365cf6a3d8d8451" + }, + { + "alg" : "SHA-1", + "content" : "0df8ec78dc87885298998ca3c9bd603ee7bfe5b8" + }, + { + "alg" : "SHA-256", + "content" : "0b7e411cfc44a15fc63a36cd05a73b34c3558f1b06e4f297b1919361b8a351a7" + }, + { + "alg" : "SHA-512", + "content" : "23baf0a59d56809db43101fbddb712b515012c64530362665cebe84c53bbd716218d3602024315f3250dea923138845c09d5c56dd9c7fb26a53d5e21a325e52e" + }, + { + "alg" : "SHA-384", + "content" : "f5ff55d346828eaec7b535bdd1d6096acc3819e81f6fa0a3d2396d523616e2e356d58115de8b8c49adf035216fa6ea83" + }, + { + "alg" : "SHA3-384", + "content" : "6e5bd5c09d127a2984a55bbfc296cc515e399f35ee2ca949b10639c5ef583bee58dc9eeb60f6bec1f05904f8b91b4a26" + }, + { + "alg" : "SHA3-256", + "content" : "99b21628e6efb820b4955e0e17bb54345a6974dc785b79abb7af8186a261159e" + }, + { + "alg" : "SHA3-512", + "content" : "91625907d0200fb80f025aa6ed098372955053bfb277db124d95ce2dd5049c20e9e7f2b97cffd6f247d9ae8da1bc26c004b688687056a87ccb3033d57a7c20f3" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.2.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-actuator", + "version" : "3.2.1", + "description" : "Spring Boot Actuator", + "hashes" : [ + { + "alg" : "MD5", + "content" : "d5ede97972b567fe75db1d2bbfc035d8" + }, + { + "alg" : "SHA-1", + "content" : "9089b9fff0c17eae54aabc466b78e010eac3a04f" + }, + { + "alg" : "SHA-256", + "content" : "b870c0a601dc0d6d98b33a6b59d41799285848de267f7cfb466a6f167f30c4d2" + }, + { + "alg" : "SHA-512", + "content" : "9577f4ba268b688ad100d4038f6dba97139a29b82127f6a581b948f0ee08fc8159f51fa5f7deb200e5a61559fd321559d2255af75c3e28cf293e815b8b1bb8ac" + }, + { + "alg" : "SHA-384", + "content" : "96adde3cd5a4f729a6d382566800e62e89c93d1c3b9120ffefcd9a666d755fc5d6dc3dd12577f927bcaf03b7f1b0922b" + }, + { + "alg" : "SHA3-384", + "content" : "c3f71bfae2d560ec46f76e833aee6964b5ad57639cb4ded937cd6d1e39b213a4c255d9b83ba59882d22dd31a4ef7b5f5" + }, + { + "alg" : "SHA3-256", + "content" : "d7a251040e99b14a5d926f86bdcb1fcf505518d31cb421e6aaf32d59d8f7f2eb" + }, + { + "alg" : "SHA3-512", + "content" : "3b642b5433989ba548cffebd7c155d5ada680b96996eac432895de56a27d7529c795d7263e8419854c9d118cddc0492d142d260a2e5434058134c9bc17ab8253" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-actuator@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-actuator@3.2.1?type=jar" + }, + { + "group" : "ch.qos.logback", + "name" : "logback-core", + "version" : "1.4.14", + "description" : "logback-core module", + "hashes" : [ + { + "alg" : "MD5", + "content" : "7367629d307fa3d0b82d76b9d3f1d09a" + }, + { + "alg" : "SHA-1", + "content" : "4d3c2248219ac0effeb380ed4c5280a80bf395e8" + }, + { + "alg" : "SHA-256", + "content" : "f8c2f05f42530b1852739507c1792f0080167850ed8f396444c6913d6617a293" + }, + { + "alg" : "SHA-512", + "content" : "d18159d4b378973e49182c4711b3d5b1f3600674ddd7bde26793247854bbd3a7233df7f74c356ecc86e4160ac6f866e0b32c109df6e1b428a10cddd4bc7f44e8" + }, + { + "alg" : "SHA-384", + "content" : "afe21cf21e8804d069514a1f0d57c92b4caf56f8b010bd681d19fff67f237fcf0bbe1e1c9bfc4cedcfe602a3ea859b57" + }, + { + "alg" : "SHA3-384", + "content" : "38cc28c8a578f4053412440d88b41938fa029a8ee3d350fe7474b34afa0f17889298d00f3c2cec4510d72d3342d29a77" + }, + { + "alg" : "SHA3-256", + "content" : "6c7d3be575969be97a49e90a97a8dc1bb25380b1b302073e00d2e21cb266e6a6" + }, + { + "alg" : "SHA3-512", + "content" : "8e9ce45d599bffac71e35a0d59c4dcff067f628157a75e9e28c1930f31537fb1dd058ddd9906322c1154f29436252a36bc50595578bfee9bcad4a9705c85726a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-1.0" + } + }, + { + "license" : { + "name" : "GNU Lesser General Public License", + "url" : "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" + } + } + ], + "purl" : "pkg:maven/ch.qos.logback/logback-core@1.4.14?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/ch.qos.logback/logback-core@1.4.14?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-test", + "version" : "3.2.1", + "description" : "Spring Boot Test", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5c793b3b61ba2637840a6c865aa2901e" + }, + { + "alg" : "SHA-1", + "content" : "142fbe3cfe3370c57d0ed55cca0d8d96e1d6f26e" + }, + { + "alg" : "SHA-256", + "content" : "0fb27aeb59ab757e60c48f9810d0ab54dc858a4c1cd9cc75b4ad07456c9c3e7c" + }, + { + "alg" : "SHA-512", + "content" : "975428c3f753ec1375f9c0ca2c47756a22896cc510193b53f7a8501255634a2e0d2165e699055667f4127cbaa8e79c9c128aef6de0854fccd4e158dce4422939" + }, + { + "alg" : "SHA-384", + "content" : "c3abb4c4a9961cab0fde6119d5b86755ea0c43fdd266b51d369a8544818463ce1876df2b13b0a2478f36b1e5282a305d" + }, + { + "alg" : "SHA3-384", + "content" : "641f9090f373f299d61bf54dd06e7ea15217c5b06424e970ddaed1f64e2a25aae74bdc10e04c9c4e934f2a3a5ab95c4b" + }, + { + "alg" : "SHA3-256", + "content" : "45d05dd704757c997b11f13961762e371309bec11292b32af3f244ca3b49642c" + }, + { + "alg" : "SHA3-512", + "content" : "53001dd1610347d6cf92f737067271fe3c638828a0b1e0b6aca62429e97a85018daf6ab3e10f065acd79ed7c93dc3a4c57f89eda3e2feb48ab548ca7e906b414" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar" + }, + { + "group" : "io.micrometer", + "name" : "micrometer-jakarta9", + "version" : "1.12.1", + "description" : "Module for Jakarta 9+ based instrumentations", + "hashes" : [ + { + "alg" : "MD5", + "content" : "0e247019d91d3c357b440436e1af2fba" + }, + { + "alg" : "SHA-1", + "content" : "2dc7257970669fa45e342b0b36902d868af2dbed" + }, + { + "alg" : "SHA-256", + "content" : "e8c66d7aee8fbc8a9d2e15c6c53df92bd7ecbf94f1ca8562d62d9a2693aa4633" + }, + { + "alg" : "SHA-512", + "content" : "3a481de081b216d42bd9b741b3a830c93d917c5ae8a11f670785b53b55cff601e1cdfd037b12d8b95cd8557c4493d6e04e51980860e421f444f2b4a953070969" + }, + { + "alg" : "SHA-384", + "content" : "cdbca1958c2502bcdad18446401f7f21ec2bc2c4055fd2fafa8fdad30cb8c8fd9aa9863de5ddd9cb852cafda487d29b0" + }, + { + "alg" : "SHA3-384", + "content" : "13f29eca056350277ee80d786945386abdd1c8b7c04dc35a94c7ac8146e7b6cafa617652fca15e79b8376341ae5576d0" + }, + { + "alg" : "SHA3-256", + "content" : "f095b2247aa3ada3c824121b4720dcceb3b65f7a2b9e880acdedc613a62d9be6" + }, + { + "alg" : "SHA3-512", + "content" : "773cd6f711b68a27d958ecb01f85d8480835014d23d3484e69e1c63bc736f50697bd6cf7d5e7776a13ae946ed10621334cb84ba8357b26d45cb6c9990826f993" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/io.micrometer/micrometer-jakarta9@1.12.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/io.micrometer/micrometer-jakarta9@1.12.1?type=jar" + }, + { + "group" : "com.fasterxml.jackson.module", + "name" : "jackson-module-parameter-names", + "version" : "2.15.3", + "description" : "Add-on module for Jackson (http://jackson.codehaus.org) to support introspection of method/constructor parameter names, without having to add explicit property name annotation.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "495868f770056602bfe13ea781656f03" + }, + { + "alg" : "SHA-1", + "content" : "8d251b90c5358677e7d8161e0c2488e6f84f49da" + }, + { + "alg" : "SHA-256", + "content" : "baf1a3156a23cb407e05374161a07ed8560f78a7ae249955de04a9a2fa2d0f2b" + }, + { + "alg" : "SHA-512", + "content" : "497b08f55f601b7ff6294e0b8307e015e60ad45c7949bd80ed3f5ee19daa93fad7f0b5a93abb8082ec46480667ab8539337633213d0fd5992e4a10c710f0a7aa" + }, + { + "alg" : "SHA-384", + "content" : "1a50ca6c0e0b4e3ecf83e3f327670a3b36f2b847b46ab5e193e9bccc36fee3bd41c1aa937dda88c4936339eafc73fc93" + }, + { + "alg" : "SHA3-384", + "content" : "30d05f1dd78a796ba4abb79be93dae2d7e4e5269de18d85a9d89b1c92f6ff8fe09ac1953a48a0b2b51906bbaadb56fca" + }, + { + "alg" : "SHA3-256", + "content" : "9e50d137efbe3de957a64fa4b90532cbb67efc2b09ba11824362315d1f57b812" + }, + { + "alg" : "SHA3-512", + "content" : "9418c5c18e429e201d7f6a4d5f05a52a433dbe4bf72a82e3ea69010c1d4b9ec99fc651804f2f8339a53841f88416318e3ab7fb1a07391cde5ea745ebbfcf98bc" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.15.3?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.15.3?type=jar" + }, + { + "group" : "org.junit.platform", + "name" : "junit-platform-engine", + "version" : "1.10.1", + "description" : "Module \"junit-platform-engine\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "4d571057589cd109f3f4bedf7bbf5e7a" + }, + { + "alg" : "SHA-1", + "content" : "f32ae4af74fde68414b8a3d2b7cf1fb43824a83a" + }, + { + "alg" : "SHA-256", + "content" : "baa48e470d6dee7369a0a8820c51da89c1463279eda6e13a304d11f45922c760" + }, + { + "alg" : "SHA-512", + "content" : "52ea2f11ec2ef0457384335d1b09263f4efecf63d9df99c5f8396f74d972722c51f8f766370e85e030f4476e805dac72603296942593c5bbe56993454b9d8e30" + }, + { + "alg" : "SHA-384", + "content" : "7c520e04c995a47c19c94fdcbbcba9bb117696191e6a989a82d9f960e0e315e5cf87d28022ac5cb2701c85d5f38eefde" + }, + { + "alg" : "SHA3-384", + "content" : "79d4f2fb987d6a44174dda99b1bd827e8dfd0399495c3e994371d4f69631212768dee8b891313aac89045388a1bed9db" + }, + { + "alg" : "SHA3-256", + "content" : "5c3fcec688368188688cb6949c1230c2822211e53f3a65b7b3abf4a38051798b" + }, + { + "alg" : "SHA3-512", + "content" : "30a0834e88bbc62287e5f49302c4a07b6da1bf4d9774faddbe7e606fb296c0dcd71c7e90ef8fff3e18dd050e5a19f7b903c91674ff4806cdb97111e4f0cfc199" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.platform/junit-platform-engine@1.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.platform/junit-platform-engine@1.10.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-autoconfigure", + "version" : "3.2.1", + "description" : "Spring Boot AutoConfigure", + "hashes" : [ + { + "alg" : "MD5", + "content" : "29fb14fe1d383588e87a73da4508604d" + }, + { + "alg" : "SHA-1", + "content" : "b100d2d21d45dddd740d496357ca6f3813d777d0" + }, + { + "alg" : "SHA-256", + "content" : "371f0f36d226a8db972c37c73f0a0896ee4d3e77c29b54dbce8a64af731a6e53" + }, + { + "alg" : "SHA-512", + "content" : "42bc3a99f9c9ffc9fd08447303a946fce1c81e3a869a5788c7d3b669536455eedc8009428ae4660d66b0d74ab170968b6aad905455b53342d7c521e7ec4c262f" + }, + { + "alg" : "SHA-384", + "content" : "f47603c4009bb767f9d5cb0bf3fcba69167daab53cbfafd217450977464073e8b814c76aa545b1eccee587201fe93eef" + }, + { + "alg" : "SHA3-384", + "content" : "bbd77376c9a46de290522662f327a8e6b0221a6c0105632e73b527799bec8a162d98948d0d05b32509650b4f47a6465e" + }, + { + "alg" : "SHA3-256", + "content" : "9e9549dda419ad6f482e3b376c595c69ccb93cebf365c1b18a59bf226c3264db" + }, + { + "alg" : "SHA3-512", + "content" : "1473f0de013447eb40d0b6d2a30013d2a7d262ce1e0259d4a27f88e421e5538234a46704f88b27c227aab7ae2261995a73f4075a6a43124e39c7234c6d164fe2" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar" + }, + { + "group" : "org.junit.jupiter", + "name" : "junit-jupiter-engine", + "version" : "5.10.1", + "description" : "Module \"junit-jupiter-engine\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "71d86cd027062c4da0796c2493ae94fe" + }, + { + "alg" : "SHA-1", + "content" : "6c9ff773f9aa842b91d1f2fe4658973252ce2428" + }, + { + "alg" : "SHA-256", + "content" : "02930dfe495f93fe70b26550ace3a28f7e1b900c84426c2e4626ce020c7282d6" + }, + { + "alg" : "SHA-512", + "content" : "1fcc9406d1e0301e27538757c9649545d784e83743a8800932971881cfd78a14a264ad13c0b92fad9ae1be50963c540427a19cb2d1fee06888ef48105aad4c8b" + }, + { + "alg" : "SHA-384", + "content" : "6657ac1bb11d7a40bbcb020add01e57edbbc521645116908d857074d9ea319eab3e7b7f2e9fa1ff8df08b5db3774f4dc" + }, + { + "alg" : "SHA3-384", + "content" : "607313914c11274c577b0aaaae6c68aa6ecf25d8302f55d4e334aa6b58df2e543d2399785e2019a56b85aac7716c9623" + }, + { + "alg" : "SHA3-256", + "content" : "be3560971111d3f548bef24aa6660ec2a126fd17b3bd68b7deeb1ab48735a9d1" + }, + { + "alg" : "SHA3-512", + "content" : "4ba6cb70f8fc1918dcedc874340488909c48e0f976d1834ec433f4b5c6cff55b16a996a0443a1b68a0d0ad84a37bf51386633905628728bde08b5820ee67dfaa" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.jupiter/junit-jupiter-engine@5.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-engine@5.10.1?type=jar" + }, + { + "group" : "io.micrometer", + "name" : "micrometer-observation", + "version" : "1.12.1", + "description" : "Module containing Observation related code", + "hashes" : [ + { + "alg" : "MD5", + "content" : "b55c9caac5c8f778996937c3f6cf4101" + }, + { + "alg" : "SHA-1", + "content" : "fbd0e0e9b6a36effd53e0eee35b050ed1f548ae5" + }, + { + "alg" : "SHA-256", + "content" : "48f6607b248e8b77ee9f7b3934f70124471daf947b30480c1b9c0e9d9f996c83" + }, + { + "alg" : "SHA-512", + "content" : "3e12e101b161715e5c30eb166578de7ae76749a2c4d22435bc57395be14d1313073d5fa76dcc883ed807d4982d343addfa24540e283cd0432f1428ff00962d98" + }, + { + "alg" : "SHA-384", + "content" : "791f99b503d7fa16733a74d92ebd02e72dfce4d648245f149f5363019beabe7e317e7ef0df0bcb67832dbab03943ff53" + }, + { + "alg" : "SHA3-384", + "content" : "ccb83eb15cd8004295bdb40b948cb9d3efaa4281b0d02a97b49970a2699822d7cd15b83206c236c3a41e49063caa5ded" + }, + { + "alg" : "SHA3-256", + "content" : "773e3647329d707d79efcb92c88cbe0719b4dcd820f06983e6e283e666875acc" + }, + { + "alg" : "SHA3-512", + "content" : "922f6c81c3a7b8e8c1296eb3359723161e91bac646d4bef954904c70a40ccfd9dc95c783715fcedc788f67ef06ea5514a918c7cc6811f2bdd39eb011a36698e7" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar" + }, + { + "group" : "org.awaitility", + "name" : "awaitility", + "version" : "4.2.0", + "description" : "A Java DSL for synchronizing asynchronous operations", + "hashes" : [ + { + "alg" : "MD5", + "content" : "8f3644827b9e3037de42068c57006260" + }, + { + "alg" : "SHA-1", + "content" : "2c39784846001a9cffd6c6b89c78de62c0d80fb8" + }, + { + "alg" : "SHA-256", + "content" : "2d23b79211fdd19036f6940cc783543779320aaf86f38d6e385a2ff26da41272" + }, + { + "alg" : "SHA-512", + "content" : "4c422b4aef3dfceb040898f45cd1b2efb7bbf213ef9487334a0d0e674e494e120fef61348f8a81ce726f2f66dc426e133917de20c52b5d39d792e2dca7bc82d8" + }, + { + "alg" : "SHA-384", + "content" : "11d15d6efb32707cae528eefb8fa4ab7820649ed528c3447660efd984518ee2906421af5ee76ea8181c904d594e8e719" + }, + { + "alg" : "SHA3-384", + "content" : "71eff4441379fb1d13bec42264d48dd1ed4817c7a226a4ef1e5255e5afcc8e5e61aa92677ae98fdce2bf4824b4dbe4fc" + }, + { + "alg" : "SHA3-256", + "content" : "4fc8b38b34625336be520d2be1edcab4c8dd8e0667fecb2aa6aea83b9bad7f28" + }, + { + "alg" : "SHA3-512", + "content" : "074f8629ab499c28155e505513e0a25c83ce722747d196966eac6327de604853503ca5f54b84effe8e2e3ab78d9ce285bdba82bf738ff8bff0f1009549230521" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.awaitility/awaitility@4.2.0?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.awaitility/awaitility@4.2.0?type=jar" + }, + { + "group" : "org.hamcrest", + "name" : "hamcrest", + "version" : "2.2", + "description" : "Core API and libraries of hamcrest matcher framework.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "10b47e837f271d0662f28780e60388e8" + }, + { + "alg" : "SHA-1", + "content" : "1820c0968dba3a11a1b30669bb1f01978a91dedc" + }, + { + "alg" : "SHA-256", + "content" : "5e62846a89f05cd78cd9c1a553f340d002458380c320455dd1f8fc5497a8a1c1" + }, + { + "alg" : "SHA-512", + "content" : "6b1141329b83224f69f074cb913dbff6921d6b8693ede8d2599acb626481255dae63de42eb123cbd5f59a261ac32faae012be64e8e90406ae9215543fbca5546" + }, + { + "alg" : "SHA-384", + "content" : "89bdcfdb28da13eaa09a40f5e3fd5667c3cf789cf43e237b8581d1cd814fee392ada66a79cbe77295950e996f485f887" + }, + { + "alg" : "SHA3-384", + "content" : "0d011b75ed22fe456ff683b420875636c4c05b3b837d8819f3f38fd33ec52b3ce2f854acfb7bebffc6659046af8fa204" + }, + { + "alg" : "SHA3-256", + "content" : "92d05019d2aec2c45f0464df5bf29a2e41c1af1ee3de05ec9d8ca82e0ee4f0b0" + }, + { + "alg" : "SHA3-512", + "content" : "4c5cbbe0dcaa9878e1dc6d3caa523c795a96280cb53843577164e5af458572cde0e82310cf5b52c1ea370c434d5631f02e06980d63126843d9b16e357a5f7483" + } + ], + "licenses" : [ + { + "license" : { + "id" : "BSD-3-Clause", + "url" : "https://opensource.org/licenses/BSD-3-Clause" + } + } + ], + "purl" : "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/hamcrest/JavaHamcrest" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar" + }, + { + "group" : "org.junit.jupiter", + "name" : "junit-jupiter-api", + "version" : "5.10.1", + "description" : "Module \"junit-jupiter-api\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "c6b8b04f2910f6cef6ac10846f43a92d" + }, + { + "alg" : "SHA-1", + "content" : "eb90c7d8bfaae8fdc97b225733fcb595ddd72843" + }, + { + "alg" : "SHA-256", + "content" : "60d5c398c32dc7039b99282514ad6064061d8417cf959a1f6bd2038cc907c913" + }, + { + "alg" : "SHA-512", + "content" : "b1fef44d4aa781bb119ab723c3c2a6f0d27efc4493a1fa26b603c7c7a8884c4d6274bccec6536f120d55f876f8d052aaf6cc003074c27cc704deb2c4bc08b6f0" + }, + { + "alg" : "SHA-384", + "content" : "0fd81f893be859a50766bfbf3bd74bd7d359c6d481b7fe3099e220402f585d3d46b6ad42a36b1d88eefbb6fd27a3cefa" + }, + { + "alg" : "SHA3-384", + "content" : "5e13ba92f757499ca52d719869d318cade9bde9c948ee9c68d753a21ec273f7b56ad68ff8cb281614efeef1d4c479db0" + }, + { + "alg" : "SHA3-256", + "content" : "997c9e0cc57d61a85a8eec568d0f014d47af5bf655602a2c3518b6530b089905" + }, + { + "alg" : "SHA3-512", + "content" : "e97c3e2c1faa1f77b174ef6ce7b24a2339e547f5976a4e40348653e84498e0c3bb96068447facef6df6b54d4af34b807f19b4d2bb1d31e26f97d6dae07843bf6" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar" + }, + { + "group" : "org.skyscreamer", + "name" : "jsonassert", + "version" : "1.5.1", + "description" : "A library to develop RESTful but flexible APIs", + "hashes" : [ + { + "alg" : "MD5", + "content" : "60a7d3d352b233487d735f4b86802717" + }, + { + "alg" : "SHA-1", + "content" : "6d842d0faf4cf6725c509a5e5347d319ee0431c3" + }, + { + "alg" : "SHA-256", + "content" : "1e9a7c443d0dd579906646d767f3701918a78cb88a93112f528305fc9095d261" + }, + { + "alg" : "SHA-512", + "content" : "51221bbeb30ed47840494d31128e605e29a96249f3e4b9c00985a865f8ed58b73e045772e3b0af74a35018a9dd004b5cc2182344b9154d9a50604ad1a073f2dd" + }, + { + "alg" : "SHA-384", + "content" : "941cec8d4ce1fab19f32b36f0afd2c7de27325659c5f85ab90948182098de4afe327b49cea57b946f18671af8037aefd" + }, + { + "alg" : "SHA3-384", + "content" : "3fb46460472c82901ec6fa5deab84eea18369e74aad920e3ee9e0fb8a859e8397a287428d0bf1c2b137368b6579c5c4b" + }, + { + "alg" : "SHA3-256", + "content" : "24b6c0f73ee51c19d5fdae62588dff9d0bf172da7e6ad1595e275920c8de829c" + }, + { + "alg" : "SHA3-512", + "content" : "686fb7b0ee0849bc78b6eeb74a941795252cec9a62ea153e6bd1e77d51fb6ee14f64970cb52cc13f581d21b166c6f1b28b8fbc4c7ae0c3b225df385a92635f0c" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.skyscreamer/jsonassert@1.5.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.skyscreamer/jsonassert@1.5.1?type=jar" + }, + { + "group" : "org.mockito", + "name" : "mockito-junit-jupiter", + "version" : "5.7.0", + "description" : "Mockito JUnit 5 support", + "hashes" : [ + { + "alg" : "MD5", + "content" : "ab44b412aa650651eedf323e945fe367" + }, + { + "alg" : "SHA-1", + "content" : "ac2d6a3431747a7986b8f4abef465f72bf3a21ae" + }, + { + "alg" : "SHA-256", + "content" : "e2416a260c3a45ba77d674cfe27d49428e57efe21a7b2ddeae733ebb5c5d85bf" + }, + { + "alg" : "SHA-512", + "content" : "39cccb119c0767f4e443567873af78d882c4a1e99c553ad39d4efae2698933de602d9c0046a70a05be552793569d4b43e75c2a798fd1f7f0a8c5ab34db8b9c94" + }, + { + "alg" : "SHA-384", + "content" : "f02eeae7fe867ff8580164b4d20d269efbad2a18ba2ffc8ba9744c603c589fb5155399361b14ab2a6549d605d26a4694" + }, + { + "alg" : "SHA3-384", + "content" : "6b95b5f5efcc97a2531c9c108e53fe5465ae0249d46988fe7fd47df7ad4d154de40a66471a996ae7abd75bd0c1f6c9b4" + }, + { + "alg" : "SHA3-256", + "content" : "30978340a8749b094a5b0f42dffbb91e72f7d7eaea6924efce13f47a44048fdf" + }, + { + "alg" : "SHA3-512", + "content" : "80601cb4de8850a0255b7c28cb7993be667a238d961fd281c7152b7ba40eec399240a2ab9d686cd1463872652876e88ef221d699acb61a2acf041c9f187053ab" + } + ], + "licenses" : [ + { + "license" : { + "id" : "MIT", + "url" : "https://opensource.org/licenses/MIT" + } + } + ], + "purl" : "pkg:maven/org.mockito/mockito-junit-jupiter@5.7.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "build-system", + "url" : "https://github.com/mockito/mockito/actions" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/mockito/mockito/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/mockito/mockito.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.mockito/mockito-junit-jupiter@5.7.0?type=jar" + }, + { + "group" : "org.apache.logging.log4j", + "name" : "log4j-api", + "version" : "2.21.1", + "description" : "The Apache Log4j API", + "hashes" : [ + { + "alg" : "MD5", + "content" : "b5e9bf76dd128b37666ecd9a252b50ec" + }, + { + "alg" : "SHA-1", + "content" : "74c65e87b9ce1694a01524e192d7be989ba70486" + }, + { + "alg" : "SHA-256", + "content" : "1db48e180881bef1deb502022006a025a248d8f6a26186789b0c7ce487c602d6" + }, + { + "alg" : "SHA-512", + "content" : "4cbf72fbea7009ec2fc363aae2ccfe11ea2023967d65be39335eedd1d8917b7402eeb2219efd5a1f11d03833dd1f57eecab428616b03124ef2266c6cca06ac56" + }, + { + "alg" : "SHA-384", + "content" : "edd8429f2f88476afbfa63314f7846d1341a4cfc58d3abe55b3cda236613feb6859f711e0ae60bd7821b74e488fb0666" + }, + { + "alg" : "SHA3-384", + "content" : "b67292ff0c7ca988a4b40b6ec14582ef579990d275a37944ac9572ecdfd4bf6e9fff2ab982b21d159a1135c21a32495f" + }, + { + "alg" : "SHA3-256", + "content" : "b2641c2db75d3c676e451a53b5f60dfaf030a84e0230747bd50d00414f8a27b3" + }, + { + "alg" : "SHA3-512", + "content" : "f1f4d9c48a9d088460e1ad3d71126b243069e522588cdc5534ac8f201ec0574287e8f1fba182f8925ee75b78726269487cc0160f7f8bd1aa21cc8e587fdb5c4a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0", + "url" : "https://www.apache.org/licenses/LICENSE-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.logging.log4j/log4j-api@2.21.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.logging.log4j/log4j-api@2.21.1?type=jar" + }, + { + "group" : "org.assertj", + "name" : "assertj-core", + "version" : "3.24.2", + "description" : "Rich and fluent assertions for testing in Java", + "hashes" : [ + { + "alg" : "MD5", + "content" : "b596a91049e6ce526bc5595c1bebea2c" + }, + { + "alg" : "SHA-1", + "content" : "ebbf338e33f893139459ce5df023115971c2786f" + }, + { + "alg" : "SHA-256", + "content" : "df3d0b348f1fe806bdddcb10fa4ae63c6679e9888d4bc7055f09848517976aa3" + }, + { + "alg" : "SHA-512", + "content" : "d8e3159effc7954258f2398e26c34eab6c243675408c7b5fcd7ed04a7b7dc06006514510ad15be9e7725f724cbf6e5c534cb22cbfb7c0aed71b81d4ed5755220" + }, + { + "alg" : "SHA-384", + "content" : "4f06196b5329e215282476d8e3aa5065092924bccb91da4eb0aa2e8fcd2509f249369654f0c17b59c38f11b878a305e3" + }, + { + "alg" : "SHA3-384", + "content" : "3029ae58aef975843e9205f130dcdd8f8e7da5ff1bfad62b7d918ffe52b74a3c34a859af13393abe122124a9132f3feb" + }, + { + "alg" : "SHA3-256", + "content" : "2db6965251a03be26f5baa83792a002444b4de34aaaefb0e6cf3cccf0a20939e" + }, + { + "alg" : "SHA3-512", + "content" : "fa3ffb87bc40c3f881fb477d41c8565cbc1ce46ead2030442674bb86a425c722b75fce5bb3c22425b21cc3122ac46e0f28b2eaba2bcf5d5ddcb31f47d967b890" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.assertj/assertj-core@3.24.2?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.assertj/assertj-core@3.24.2?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-web", + "version" : "3.2.1", + "description" : "Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container", + "hashes" : [ + { + "alg" : "MD5", + "content" : "8a6aea9e1fbdbabbd00e35038739200f" + }, + { + "alg" : "SHA-1", + "content" : "e27e36d4222fd4d589e634e1c7f5f09f0316147c" + }, + { + "alg" : "SHA-256", + "content" : "2f14d3a4a0ae3ad634bcfa07117542001c1789c0bdce3504baee8f2bc45ef006" + }, + { + "alg" : "SHA-512", + "content" : "2fcfc8d9abfcd0518b6755737c6e520544600b3c26b42b60d1ab3fcfceb31582d5dbcd5d86a98ec312442d335e49f0db0ecf21d8e99089ef41d962ece42d97ae" + }, + { + "alg" : "SHA-384", + "content" : "e3c8cb02b18ea5b7aa2a7c9c97c62385fcaa8fc53f41d7bf0b98d262a10473e9674924ad287964f6e58fb9c5915da8d1" + }, + { + "alg" : "SHA3-384", + "content" : "713c9200480f14fd4bcd073d43ac7900771c9d36b4e72b50ddf80733670948ad57700ea37336de5078d16557e426de79" + }, + { + "alg" : "SHA3-256", + "content" : "3346906c7b4b455c00226fd9804a237d3a667523800e0c2083413fde4592b7c3" + }, + { + "alg" : "SHA3-512", + "content" : "99ba750d8e1c97636eb47122ce259b1bc9b91c51fecc50d13604f7ae7096a20f1fa38562d83786c1d4c3ba07ff94b286d869d671a5f0d00fd6c378f032332f63" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-web@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-web@3.2.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-test", + "version" : "3.2.1", + "description" : "Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito", + "hashes" : [ + { + "alg" : "MD5", + "content" : "f808bed72032367a1170477e74e57f7e" + }, + { + "alg" : "SHA-1", + "content" : "e6a20062864e3a9a0bba0ac3b0c5a819453045b9" + }, + { + "alg" : "SHA-256", + "content" : "2e0a11d69fed912dd6f5a6b0f492ce1530e2ac932de9588d4b7df0ab548eea0a" + }, + { + "alg" : "SHA-512", + "content" : "83c1f7e7b404be7b9f603a386ca2d0c84c7e0b73190ffb19ef2b0dff5cbc1ebd57ce73be663ee01ed28f1c4f41d91db7f070d7b37a3f2ae6b9b6814dd930a089" + }, + { + "alg" : "SHA-384", + "content" : "3a5159cad10587b250f0a1f7cf6ebea9f2cbda539c008094fec1dff47eeced5b2119be3ad007eab0598445b9282164f4" + }, + { + "alg" : "SHA3-384", + "content" : "9303b808eed6e0425d5c7e968601960d9ff2e0c2fd840ffd041b01f0499b1f86ae05c50e968e925374a54b26e9298410" + }, + { + "alg" : "SHA3-256", + "content" : "a18f18bd0a077a38ea0b3aeae85730b9f104d65d4d48f88210f2954c45739eae" + }, + { + "alg" : "SHA3-512", + "content" : "e021bfc51b8d6b8cdc1b44cf5042778c208db09b349250e33630b28ace2ed97d52bd89750ab70e14b650578f379a7e6172838c83bbb2c974394132cb80381f27" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.2.1?type=jar" + }, + { + "group" : "jakarta.activation", + "name" : "jakarta.activation-api", + "version" : "2.1.2", + "description" : "${project.name} ${spec.version} Specification", + "hashes" : [ + { + "alg" : "MD5", + "content" : "1af11450fafc7ee26c633d940286bc16" + }, + { + "alg" : "SHA-1", + "content" : "640c0d5aff45dbff1e1a1bc09673ff3a02b1ba12" + }, + { + "alg" : "SHA-256", + "content" : "f53f578dd0eb4170c195a4e215c59a38abfb4123dcb95dd902fef92876499fbb" + }, + { + "alg" : "SHA-512", + "content" : "383283f469aba01a274591e29f1aa398fefa273bca180162d9d11c87509ffb55cb2dde51783bd6cae6f2c4347e0ac7358cf11f4c85787d5d2857354b9e29d877" + }, + { + "alg" : "SHA-384", + "content" : "e34ac294c104cb67ac06f7fc60752e54a881c04f68271b758899739a5df5be2d2d0e707face2705b95fa5a26cedf9313" + }, + { + "alg" : "SHA3-384", + "content" : "ffd74b0335a4bfdd9a0c733c77ecdfa967d5280500c7d2f01e2be8499d39a9f0cd29c9063ae634223347bb00f4e60c33" + }, + { + "alg" : "SHA3-256", + "content" : "c97236eaebb15b8aefa034b23834eaeed848dacf119746c6d87832c47581e74d" + }, + { + "alg" : "SHA3-512", + "content" : "147dfa2bf46bb47c81462c36ac6612f9f807169ffb785e2bbd45538205c5713f33af4373f3324a2063350c2367baff37e9c2cf085c38c96870ad88c60a7fbea4" + } + ], + "licenses" : [ + { + "license" : { + "id" : "BSD-3-Clause" + } + } + ], + "purl" : "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://github.com/jakartaee/jaf-api/issues/" + }, + { + "type" : "vcs", + "url" : "https://github.com/jakartaee/jaf-api" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2?type=jar" + }, + { + "group" : "io.micrometer", + "name" : "micrometer-core", + "version" : "1.12.1", + "description" : "Core module of Micrometer containing instrumentation API and implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "30dcc7ea6a0e99663e5908bce7371206" + }, + { + "alg" : "SHA-1", + "content" : "b72e9a2f26355ecb8ababa0148a5c3c4ac648f14" + }, + { + "alg" : "SHA-256", + "content" : "97d0a5309e9c584f4dec6f549a383ae25d8727abff43cff8e0b90580ee797b67" + }, + { + "alg" : "SHA-512", + "content" : "2acd080a1b40cb5a1ca0b7266af829392e318291dab57e6239ca97d15112cc206992b78316f4c02400454124519a084341e4de55dd729c96805b3fb196707a64" + }, + { + "alg" : "SHA-384", + "content" : "9a3998a9a219fc049ace5731fde94944948332eccbe589dbc34456057a2df173ef17e3b0642233e513d3118bcfba565f" + }, + { + "alg" : "SHA3-384", + "content" : "22c97b3fb49d299ebc36674a6e32d9fd05726d88109ede3323e3e97e82100d1ed6d7010e86749a2b07ffe994fb3b7833" + }, + { + "alg" : "SHA3-256", + "content" : "3b272686c89e274b5944715db002871e072f0f8c7099228f6d6909656b6ba3f4" + }, + { + "alg" : "SHA3-512", + "content" : "b1d82086950a2e61ed3e016fa962af2e9c3b2d543c4c311d40d9f7fc402b9beb3e5d09261d336cb1634b186f723bf584874f3fb8a29c38198d5ddd2b386c4413" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/io.micrometer/micrometer-core@1.12.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/io.micrometer/micrometer-core@1.12.1?type=jar" + }, + { + "group" : "org.junit.jupiter", + "name" : "junit-jupiter-params", + "version" : "5.10.1", + "description" : "Module \"junit-jupiter-params\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5e8e17f6f2a5dedb42d9846a3352dd31" + }, + { + "alg" : "SHA-1", + "content" : "c8f15d4e99940c4564098af78c10809c00fdca06" + }, + { + "alg" : "SHA-256", + "content" : "c8cf62debcbb354deefe1ffd0671eff785514907567d22a615ff8a8de4522b21" + }, + { + "alg" : "SHA-512", + "content" : "dbd8a3bca0a03b6eef54de2b489685c8125e0c6f23cbdb633174b21e07cc7b97a24b55dcb5b60ec1a496683a918bfdf1ea0459950689e3755aa965ea9e106ee9" + }, + { + "alg" : "SHA-384", + "content" : "882b3106163d7c195867e08db9948a0997e1469a23c847bff523efa30a9b274c0588f8228fca98c78abf9b61709a7ff2" + }, + { + "alg" : "SHA3-384", + "content" : "6e4e9a7dbb32cc3f16f21a14fe036aa13488c5b94e3cb6cc53b417c4588b90b5ae118caa3eb9f4bc9c513d06e2c1f408" + }, + { + "alg" : "SHA3-256", + "content" : "171a08027b527e3be1ad66082405eacf4a55746dd983c46d9ff7ee5552276615" + }, + { + "alg" : "SHA3-512", + "content" : "c435b4a17208b67f6fa35ebe74872c3d2c3557b290437bb682ac86701402bbe17d0e53446c674bb94c7feaae4bbfa99d888c7bf7181707e27fe08ff7934c00f6" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.10.1?type=jar" + }, + { + "group" : "com.fasterxml.jackson.core", + "name" : "jackson-databind", + "version" : "2.15.3", + "description" : "General data-binding functionality for Jackson: works on core streaming API", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5f453c55f127690fa8491ce347aa055c" + }, + { + "alg" : "SHA-1", + "content" : "a734bc2c47a9453c4efa772461a3aeb273c010d9" + }, + { + "alg" : "SHA-256", + "content" : "c3c53333a2172a80678bda1803e39cff45bec6ae3e9c7d4f44a81ec4e2ab18dc" + }, + { + "alg" : "SHA-512", + "content" : "490ccc99a9c28238fe28455bae08196b83df034cae8a1947d27ff89e500a5d812cf4be36c61942e647c62ad540d8eb4428f49855f0cc8db0ee9e7a5b12ba2454" + }, + { + "alg" : "SHA-384", + "content" : "b53f4a6fddbf677a8d02c65e9f0a96372140c68286d68740987fb462f946de878abaeea421d3e4716751f04d88c16ad1" + }, + { + "alg" : "SHA3-384", + "content" : "5a407605544e303abf8a212651bf5e5594fa313804a399bf03401f449c0baf26ef965def518b05c275b2f38f18457739" + }, + { + "alg" : "SHA3-256", + "content" : "d0880002ac261d181e663499627fcce5763f3a9120bb76e758adfb9939d17c98" + }, + { + "alg" : "SHA3-512", + "content" : "e97bfe0e9117dad82e0799cb2c105c4553c6aa5ce9abdefee4fd5b584876555309aafa9a19ca586e928e292e32f23452849a10da7364966e11e4f7afcc6aec78" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/FasterXML/jackson-databind" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + }, + { + "group" : "org.slf4j", + "name" : "jul-to-slf4j", + "version" : "2.0.9", + "description" : "JUL to SLF4J bridge", + "hashes" : [ + { + "alg" : "MD5", + "content" : "24f86e89ee3f71ea91f644150c507740" + }, + { + "alg" : "SHA-1", + "content" : "09ef7c70b248185845f013f49a33ff9ca65b7975" + }, + { + "alg" : "SHA-256", + "content" : "69b4e5f8d3bd3f6f54367d19f2c1ee95dd5877802f12d868282e218dd76b00bf" + }, + { + "alg" : "SHA-512", + "content" : "c1cdfbc0c867917d65ab58e039b01c5b119368aef82abcb406d91646da208a4bfad91831a5a425eacfa8253ccd5713a9d4325d45665288483929cce7a6a56eb7" + }, + { + "alg" : "SHA-384", + "content" : "a8d45375ec27c0833a441f28055ba2c07b601fb7a9bc54945672fc2f7b957d8ada5d574ab607ef3f9a279c32c0a7b0a5" + }, + { + "alg" : "SHA3-384", + "content" : "d65edaa8f6ad8bbea84617e414ede438ec4aafffa3734f2d38e6dd0a01c1f42f9397acaf6291a73489fb252d7369c71e" + }, + { + "alg" : "SHA3-256", + "content" : "69416188261a8af7cb686a6d68a809f4e7cab668f6b12d4456ce8fd9df7a1c25" + }, + { + "alg" : "SHA3-512", + "content" : "52d54c80e3934913a184efc091978201934b0ee47a6b4f9c8555a4d549becd26957e17592aff46dfdcfcbcb2313bfad09699ee84cfd7112ed2a00422c87399e8" + } + ], + "licenses" : [ + { + "license" : { + "id" : "MIT", + "url" : "https://opensource.org/licenses/MIT" + } + } + ], + "purl" : "pkg:maven/org.slf4j/jul-to-slf4j@2.0.9?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.slf4j/jul-to-slf4j@2.0.9?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot", + "version" : "3.2.1", + "description" : "Spring Boot", + "hashes" : [ + { + "alg" : "MD5", + "content" : "6f7384977eae04c804b1062df9217959" + }, + { + "alg" : "SHA-1", + "content" : "faa2ce019bee68a8d17529d0a08ebc427f927e13" + }, + { + "alg" : "SHA-256", + "content" : "6fde604399114e77b12519b3d117117c607cb73b89a88800856fb0e0cc82ea7a" + }, + { + "alg" : "SHA-512", + "content" : "8619959d143ef38f5c846591b8b10b0c50906a3301a5e9ed3e3df44124bdfbe3197cd4ecfb214c3250f40a0c1b11138b7a3f6865755445879f0685d2e88a6846" + }, + { + "alg" : "SHA-384", + "content" : "e237fdf6fdb8d21f2fc19fc15a370901c368266ae8d2b157f41b5eeed50b211a871fabc352dda10bb3aec60975d233f5" + }, + { + "alg" : "SHA3-384", + "content" : "cd6240fc102daf1efcd9fdd6532ce21297d5477e9bde3f5651cc9ec9505d526f63ea2284e484c2aee2a8e63841137839" + }, + { + "alg" : "SHA3-256", + "content" : "3959b52aebe7405a95f82d8990b8122cf21b89967f691dad851b85191973f9cb" + }, + { + "alg" : "SHA3-512", + "content" : "1b4ef33997158ddb97ccbcec7011cd55f0e019428d25410b01a83ca58c9420f2f8805be955cf704605145abe582522db0c8afb9698ae4efac141a3807a457ae5" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + }, + { + "group" : "org.latencyutils", + "name" : "LatencyUtils", + "version" : "2.0.3", + "description" : "LatencyUtils is a package that provides latency recording and reporting utilities.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "2ad12e1ef7614cecfb0483fa9ac6da73" + }, + { + "alg" : "SHA-1", + "content" : "769c0b82cb2421c8256300e907298a9410a2a3d3" + }, + { + "alg" : "SHA-256", + "content" : "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec" + }, + { + "alg" : "SHA-512", + "content" : "bb81a42498c65389366205f4e07cee336920e2f05cc0daae213f2784b1d0ce9a908b038daec20478f23eb00b2bf704f96c5b00f63c99615193ab2a3cc4a9f890" + }, + { + "alg" : "SHA-384", + "content" : "16ca4640dc9d848e6c6d15441897e1b5a9f27f34207b0bb456dd54d8f267b73b348092e548e78634144de44ba3515205" + }, + { + "alg" : "SHA3-384", + "content" : "406c2b5c6f64b0c090568e479b5e6136a04a4e77f8eea65d32b4e2b01deebcdf6a0a851240cdb740c25b5a5e61e6c179" + }, + { + "alg" : "SHA3-256", + "content" : "50ae828358301033542fd7c412e86ee318d5451f89a182e2a679aaf18099d26d" + }, + { + "alg" : "SHA3-512", + "content" : "456c337b9fb385579aae707409ed6a04d08e5fc87b1a46733dca617c22c625bf253dc4747e0cdbf5e7d8b48102d2938cb482b6b688a79aab645a7459c592258f" + } + ], + "licenses" : [ + { + "license" : { + "id" : "CC0-1.0" + } + } + ], + "purl" : "pkg:maven/org.latencyutils/LatencyUtils@2.0.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://github.com/LatencyUtils/LatencyUtils/issues" + }, + { + "type" : "vcs", + "url" : "scm:git:git://github.com/LatencyUtils/LatencyUtils.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.latencyutils/LatencyUtils@2.0.3?type=jar" + }, + { + "group" : "org.apache.tomcat.embed", + "name" : "tomcat-embed-el", + "version" : "10.1.17", + "description" : "Core Tomcat implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "f9171a84574782d1d68acd8b07177172" + }, + { + "alg" : "SHA-1", + "content" : "9ad7312421535d7d3aabe0f541e852baccb59726" + }, + { + "alg" : "SHA-256", + "content" : "bac12b9c993a9181ffc88ea8ba085491a482729e64ae105750a7475a7b85e549" + }, + { + "alg" : "SHA-512", + "content" : "77cf7be4536d7f1f4761fec33562134150c0ebc74d582160ff913c8be37b1502ed63e90bce81bc8617cfcd76c774903c2dca4209a972146f4c976f786456c596" + }, + { + "alg" : "SHA-384", + "content" : "62b14b49de8ee6efb41831ff172114af56a18379a797de732915ac356bce3e5582764253852c9831a3c3b6c1e52dea65" + }, + { + "alg" : "SHA3-384", + "content" : "05cb21cbf8b221332d7ad588cc6aa2087c60e8ce92c5ff2bddcd16465ef2a0198f74d4595dc3313d1acc68ea945c8672" + }, + { + "alg" : "SHA3-256", + "content" : "c18e9b240138c21a23b0bf2f502d1d667084c5a50d7b3340a4a08799a3175de9" + }, + { + "alg" : "SHA3-512", + "content" : "663d02ece35a989d8da1cdbdea002974f0115ae8c727dd71f0505f299c63f04c0e83b718e4c3e65412bea1c79d872e9ca7d9431c7deb63a312d3191d419620ab" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.17?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.17?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-context", + "version" : "6.1.2", + "description" : "Spring Context", + "hashes" : [ + { + "alg" : "MD5", + "content" : "ca23d3013c2afc6d3b30b993f3c5cd69" + }, + { + "alg" : "SHA-1", + "content" : "15df19852991220556b4462a366269b8e15278eb" + }, + { + "alg" : "SHA-256", + "content" : "af22a435469956415bbee873de6c05995ef12f2d29622abf510a94581ea52de2" + }, + { + "alg" : "SHA-512", + "content" : "eca3cb14e8c0fb65d27bc21a8041aab3baea14f278fb546356fcec9874d0dcd10353fe697e94ebc35a78abb3387d5a41b67c1cbc9341eb05359c1b535147a9c9" + }, + { + "alg" : "SHA-384", + "content" : "374207d989f7f27ded5468f35867d0aace78927cdaf98c31b2b6345210fbbe960ae5e5143bb0308347b7ef386159fa04" + }, + { + "alg" : "SHA3-384", + "content" : "236c1d366734b231ef4a334da4220b311dd58b1707ae854b2a50ff89b6b348913458fecdab14d196128b695de6dc9832" + }, + { + "alg" : "SHA3-256", + "content" : "e1e1e87df37dbc064315d7afaa59480c830a0f445ed0df2ff5968931f96e9e86" + }, + { + "alg" : "SHA3-512", + "content" : "a600b2720ed8e5c6ecbb2a68b6a5fb5320811818e2128016b9888df705901a8d0f38dfa99b8d458724a85e769b4da2ce14d461133e085f8aab23f59e9e520c11" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-context@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-context@6.1.2?type=jar" + }, + { + "group" : "org.opentest4j", + "name" : "opentest4j", + "version" : "1.3.0", + "description" : "Open Test Alliance for the JVM", + "hashes" : [ + { + "alg" : "MD5", + "content" : "03c404f727531f3fd3b4c73997899327" + }, + { + "alg" : "SHA-1", + "content" : "152ea56b3a72f655d4fd677fc0ef2596c3dd5e6e" + }, + { + "alg" : "SHA-256", + "content" : "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b" + }, + { + "alg" : "SHA-512", + "content" : "78fc698a7871bb50305e3657893c10500595f043348d875f57bc39ca4a6a51eda3967b7c8c8a7ec3e8f85f2171bca4aa98823e912e416e87e81c6ba5b70a37c3" + }, + { + "alg" : "SHA-384", + "content" : "10398b6998c9202a0731e2e19ae1c3f9d8a83582c2663fe7bdda15794ee6fa816727dbd8f7c7164bd5395ee1cfe7c97e" + }, + { + "alg" : "SHA3-384", + "content" : "3abe706fd78509c25a402c7bbf6f9ddf71ffb5b35054864ba0fdf7902207115f888a0ba728fd71d2e87a9360d2498121" + }, + { + "alg" : "SHA3-256", + "content" : "d961907a1bfa1dcda329dca494ffbc251b31fabcaca5ab7095661a8ce3c1d654" + }, + { + "alg" : "SHA3-512", + "content" : "0ad661617bcac51bcd26f7ad4611c69b1fd9811b50dbf734e041a3243ab1f845e7796620e8a7c40c4a2df3946864598b1251396c7d9bd813203d82710788cce0" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.opentest4j/opentest4j@1.3.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/ota4j-team/opentest4j" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.opentest4j/opentest4j@1.3.0?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-core", + "version" : "6.1.2", + "description" : "Spring Core", + "hashes" : [ + { + "alg" : "MD5", + "content" : "98bedebd5de314d344ed3a7dcad01c66" + }, + { + "alg" : "SHA-1", + "content" : "e43c71a9eaca454654621f7d272f15b53c68d583" + }, + { + "alg" : "SHA-256", + "content" : "8e3f7378e98c26500bdb5ecd6865778f57a22787eb2f11b9bd5fb8e438a0c631" + }, + { + "alg" : "SHA-512", + "content" : "9654f2d77899116d66dbf5808815c866da0bc7a965532da059c7819bde3928e8d3692f0dc97e06f94c44e5452b785b50eb364a1cb7e46385653ba0e2c7195306" + }, + { + "alg" : "SHA-384", + "content" : "3b63b4a26c5706ef2e379ff7bce89df983e7ae449a927905ce23ecf26e22bbcf8e91dc53cc75f4f7cd72bc09d7e7bb20" + }, + { + "alg" : "SHA3-384", + "content" : "ca29e88f0764a6a9279fc93d5cb9284a04c6ccca6a8a5beaa404079b90674286fc6458d14b0b0a727d31e00b8009e4f9" + }, + { + "alg" : "SHA3-256", + "content" : "861fc1147deae5a55165bd32c3fd4e18687afcc37876205c10bf1feede582ff9" + }, + { + "alg" : "SHA3-512", + "content" : "659a0d2e5ba153be219e1ebbafb28f9b48c44a2acd78d695e7479551a1c1641b7893d7df071a3cc7436de03735b0c8024b2f758bd0286711eae64ab005f6e929" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-core@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + }, + { + "group" : "com.jayway.jsonpath", + "name" : "json-path", + "version" : "2.8.0", + "description" : "A library to query and verify JSON", + "hashes" : [ + { + "alg" : "MD5", + "content" : "501b9f34e6a05c20dd74e6b40e066617" + }, + { + "alg" : "SHA-1", + "content" : "b4ab3b7a9e425655a0ca65487bbbd6d7ddb75160" + }, + { + "alg" : "SHA-256", + "content" : "9601707e95cd79fb98570a01ea8cfb857b5cde948744d6e0edf733c11002c95b" + }, + { + "alg" : "SHA-512", + "content" : "8d1521092a2acb13a2667774b8b81debc1f2a0e937007e27e5bd28bb222910774b64d6e269f33473f765c810c03a34e715d16065dc9a4be8d8d081436282ba7e" + }, + { + "alg" : "SHA-384", + "content" : "aeea493be7c23574a77df50a0652776b768d52e4238efd504b8ef3b142bbe6caf0dae8955b30c2173a54f70243d36a36" + }, + { + "alg" : "SHA3-384", + "content" : "c11c80614c007f350fa2fe758c0f4505e7ed7d25590622f133abc59ccffeb4e0b2abfd393b83e58dff4668307f28704f" + }, + { + "alg" : "SHA3-256", + "content" : "d7a7d1d7845dde343617ec009dd0d76e6bf012f182324e3b9d0f23c52bb7f67f" + }, + { + "alg" : "SHA3-512", + "content" : "da023255dfa2271a0b6b35b7d35980c3c502f3f63b3d515714f7dea54046f527bd6cbd903fec9492aad88ad03a1b85dc2b05fca4b34ded3c3b427c4cbfab02fe" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.jayway.jsonpath/json-path@2.8.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "scm:git:git://github.com/jayway/JsonPath.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.jayway.jsonpath/json-path@2.8.0?type=jar" + }, + { + "group" : "org.slf4j", + "name" : "slf4j-api", + "version" : "2.0.9", + "description" : "The slf4j API", + "hashes" : [ + { + "alg" : "MD5", + "content" : "45630e54b0f0ac2b3c80462515ad8fda" + }, + { + "alg" : "SHA-1", + "content" : "7cf2726fdcfbc8610f9a71fb3ed639871f315340" + }, + { + "alg" : "SHA-256", + "content" : "0818930dc8d7debb403204611691da58e49d42c50b6ffcfdce02dadb7c3c2b6c" + }, + { + "alg" : "SHA-512", + "content" : "069e6ddce79617e37d61758120c7e68348ee62f255781948937f7bec3058e46244026d7f6a11e90fbc15cd4288c4bb1acee4f242af521c721a9e68a05e64d526" + }, + { + "alg" : "SHA-384", + "content" : "fd6f7ad85d02ac63cd1a586c8bb158c1fc000495f512f097731ea9f749b5da2637615b821294962805ba312c738f40aa" + }, + { + "alg" : "SHA3-384", + "content" : "17cd61f59a162250b52a89c7c56eb60da253b776210500313c7b82744483ff84717946f969251fb4d76f9bb12a2458fe" + }, + { + "alg" : "SHA3-256", + "content" : "9dcb04582c64c79e788f9191195834ec75bb3457133d22a176a0ccb069b97103" + }, + { + "alg" : "SHA3-512", + "content" : "990faffa454598a3fa82affe30f1323db769d2e1fff20d9c7163ef6fd95ac7a0874c06a634207a2eaed9e5afbdee68b225138fc75018717ba97efe3ffe92c88a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "MIT", + "url" : "https://opensource.org/licenses/MIT" + } + } + ], + "purl" : "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar" + }, + { + "group" : "ch.qos.logback", + "name" : "logback-classic", + "version" : "1.4.14", + "description" : "logback-classic module", + "hashes" : [ + { + "alg" : "MD5", + "content" : "204b49a7fa041b2b2c455193079dc1d2" + }, + { + "alg" : "SHA-1", + "content" : "d98bc162275134cdf1518774da4a2a17ef6fb94d" + }, + { + "alg" : "SHA-256", + "content" : "8e832f7263ca606ae36dabb2d8b24c2f43d82cf634e81dad9d1640fa6ee3c596" + }, + { + "alg" : "SHA-512", + "content" : "77b535f2cf5a2fdb807017cb6fe456c40dcb11491e743ff86f99df2714a1b12bb9182ac193d37c8a6dd7eb2bf4c7d24390a6d551d02a280083673516eecdabc4" + }, + { + "alg" : "SHA-384", + "content" : "606400251082b8193a57bb20f1774ee2d6e439fab2ddb0207643fe9cee66cf61edba5e5c80d4b3bc9785a7bab910f8df" + }, + { + "alg" : "SHA3-384", + "content" : "d9d9b1412d2fea3eeb5d110a0e7d44c9bc13459fd2b2f5cbb30b95174081f0184758abe43b5e6b6197a716c3ba7b310f" + }, + { + "alg" : "SHA3-256", + "content" : "e1b0d59a9a91fd7878c92b3680cde8c34896823612a2f04715c05e977c09db82" + }, + { + "alg" : "SHA3-512", + "content" : "e0a39dacbb91b7d9f00bdf78829918079f6f2e749c28f31a359064bac9ac7eb65c87e581795946814460f787e33b8829a9cf0e933a0f87dd7d48f288d45f5064" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-1.0" + } + }, + { + "license" : { + "name" : "GNU Lesser General Public License", + "url" : "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" + } + } + ], + "purl" : "pkg:maven/ch.qos.logback/logback-classic@1.4.14?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/ch.qos.logback/logback-classic@1.4.14?type=jar" + }, + { + "publisher" : "Chemouni Uriel", + "group" : "net.minidev", + "name" : "accessors-smart", + "version" : "2.5.0", + "description" : "Java reflect give poor performance on getter setter an constructor calls, accessors-smart use ASM to speed up those calls.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "fc814b28882dd9f2552eda21add0698f" + }, + { + "alg" : "SHA-1", + "content" : "aca011492dfe9c26f4e0659028a4fe0970829dd8" + }, + { + "alg" : "SHA-256", + "content" : "12314fc6881d66a413fd66370787adba16e504fbf7e138690b0f3952e3fbd321" + }, + { + "alg" : "SHA-512", + "content" : "77b21fdd3401a0557d2d04a14c27563897afe9e001fc520398e22083bc18afee5e48dd9f5fc6561d0f327a30a9303bf5cc20f0a2ce741d80b3792e258276faac" + }, + { + "alg" : "SHA-384", + "content" : "7464bf3917d11712b235c7e1af339766d01cb4b41ec98941c3c69bc4ab9a4d0e6c832cbf01482425100dc8f1611ce3a0" + }, + { + "alg" : "SHA3-384", + "content" : "be26dc2bfc5fdc1a45e14f1c2fcfe224994e66d39049e235ea83c714fb90bb685d3f2209c0d550528e2cd9b2d9d95a6e" + }, + { + "alg" : "SHA3-256", + "content" : "6a914eb757ec313842f13c837eeb628e606323cc63dc24127e7a9804e2746d12" + }, + { + "alg" : "SHA3-512", + "content" : "edbddef0538aac87bf6af714e12c4078fd6ada069b6fd0e1e5c1038b060999764e06c28b3ca38b8d540d0f60c72f7321ddc22d2537156999bad5098c89b6975a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/net.minidev/accessors-smart@2.5.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://urielch.github.io/" + }, + { + "type" : "distribution", + "url" : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + }, + { + "type" : "vcs", + "url" : "https://github.com/netplex/json-smart-v2" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/net.minidev/accessors-smart@2.5.0?type=jar" + }, + { + "group" : "com.fasterxml.jackson.core", + "name" : "jackson-core", + "version" : "2.15.3", + "description" : "Core Jackson processing abstractions (aka Streaming API), implementation for JSON", + "hashes" : [ + { + "alg" : "MD5", + "content" : "c86c75392bf138d54d2a219bb1d0cbcd" + }, + { + "alg" : "SHA-1", + "content" : "60d600567c1862840397bf9ff5a92398edc5797b" + }, + { + "alg" : "SHA-256", + "content" : "51fab7aad51ed588482edc507fd542747936c5094d1ab76ed21ddb63b96b610d" + }, + { + "alg" : "SHA-512", + "content" : "112de40a31dc7d011f256f1d2fe0d9e2afc301a1f31974318f8d070c3e362b2ba96005167384244f630b915451db6694bd3cf6a9b793872351bc18f21c9de5e4" + }, + { + "alg" : "SHA-384", + "content" : "9daaf08467525e462234c53ddbf7287bcef15d8df7fbc64bcd558a91d11e8335b3a79368d194b126d3c8fb846800025b" + }, + { + "alg" : "SHA3-384", + "content" : "0b4fdc8d11fc060461e74e773fce2e64d1a98bed7db6edf51784bb1b801da4bae744a2958e81c2e24cb992fec892fb6c" + }, + { + "alg" : "SHA3-256", + "content" : "751ad4f10a78cb36fccbbe1dfe208816f17619edd5adeabc86b7509201e03c3d" + }, + { + "alg" : "SHA3-512", + "content" : "aa5807b7d92d150fada6a4ecdbfce998bbea825a09af8381127ba3736de029ae9923f54d770b2e5c3f5c85d9b4bcf21e6893a5a3089db2d02f1432b85dfa0fe7" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/FasterXML/jackson-core" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar" + }, + { + "group" : "org.xmlunit", + "name" : "xmlunit-core", + "version" : "2.9.1", + "description" : "XMLUnit for Java", + "hashes" : [ + { + "alg" : "MD5", + "content" : "011288450a3905a7d97e3957b69e713e" + }, + { + "alg" : "SHA-1", + "content" : "e5833662d9a1279a37da3ef6f62a1da29fcd68c4" + }, + { + "alg" : "SHA-256", + "content" : "7e70f23d4f75e05f0ee79f0f6b9e13b6cf51d34f36c5fc3a6b839429dde1efef" + }, + { + "alg" : "SHA-512", + "content" : "1d07dc1582a1930664ab3cffd1443e85c83fec138c663f3070a9d3b283f818157b2cdd1589595867281a96d3b444b18c22c1ee3249a75c857c6ee9682785e8a3" + }, + { + "alg" : "SHA-384", + "content" : "f54a506a08b66776d92d4379712ae9f7658cc89bd7b780eb629bd37143ff68e28cb2314539dc3c1ff13dc9cccba394f2" + }, + { + "alg" : "SHA3-384", + "content" : "7fd679371624f72417612491bac721a49f229744df3fc7455e5fd3983bd2de452a4eaabb707be7bac328f3beeea88d99" + }, + { + "alg" : "SHA3-256", + "content" : "c517aa9c543a4a3df361c30ba6609082a1dd5dc2abc351643ad5b733a1282773" + }, + { + "alg" : "SHA3-512", + "content" : "3797bade2087f791697f6736296381f8b158a2a93f50faeabcd96b4c9f48ad26fd78af56cc1036c449c35e624181961d54acdd7623b84c23c81c72d5d0fa57f1" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.xmlunit/xmlunit-core@2.9.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.xmlunit/xmlunit-core@2.9.1?type=jar" + }, + { + "publisher" : "OW2", + "group" : "org.ow2.asm", + "name" : "asm", + "version" : "9.3", + "description" : "ASM, a very small and fast Java bytecode manipulation framework", + "hashes" : [ + { + "alg" : "MD5", + "content" : "e1c3b96035117ab516ffe0de9bd696e0" + }, + { + "alg" : "SHA-1", + "content" : "8e6300ef51c1d801a7ed62d07cd221aca3a90640" + }, + { + "alg" : "SHA-256", + "content" : "1263369b59e29c943918de11d6d6152e2ec6085ce63e5710516f8c67d368e4bc" + }, + { + "alg" : "SHA-512", + "content" : "04362f50a2b66934c2635196bf8e6bd2adbe4435f312d1d97f4733c911e070f5693941a70f586928437043d01d58994325e63744e71886ae53a62c824927a4d4" + }, + { + "alg" : "SHA-384", + "content" : "304aa6673d587a68a06dd8601c6db0dc4d387f89a058b7600459522d94780e9e8d87a2778604fc41b81c43a57bf49ad6" + }, + { + "alg" : "SHA3-384", + "content" : "9744884ed03ced46ed36c68c7bb1f523678bcbb4f32ebeaa220157b8631e862d6573066dfc2092ed77dc7826ad17aef2" + }, + { + "alg" : "SHA3-256", + "content" : "2be2d22fdbafe87b7cdda0498fc4f45db8d77a720b63ec1f7ffe8351e173b77b" + }, + { + "alg" : "SHA3-512", + "content" : "a3ff403dd3eefbb7511d2360ab1ca3d1bf33b2f9d1c5738284be9d132eb6ad869f2d97e790ed0969132af30271e544d3725c02252267fe55e0339f89f3669ce1" + } + ], + "licenses" : [ + { + "license" : { + "id" : "BSD-3-Clause", + "url" : "https://opensource.org/licenses/BSD-3-Clause" + } + } + ], + "purl" : "pkg:maven/org.ow2.asm/asm@9.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "http://www.ow2.org/" + }, + { + "type" : "issue-tracker", + "url" : "https://gitlab.ow2.org/asm/asm/issues" + }, + { + "type" : "mailing-list", + "url" : "https://mail.ow2.org/wws/arc/asm/" + }, + { + "type" : "vcs", + "url" : "https://gitlab.ow2.org/asm/asm/" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.ow2.asm/asm@9.3?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter", + "version" : "3.2.1", + "description" : "Core starter, including auto-configuration support, logging and YAML", + "hashes" : [ + { + "alg" : "MD5", + "content" : "d9eb815815944bcdaeed5e63f32e5d7f" + }, + { + "alg" : "SHA-1", + "content" : "bc03d7075fb9d9d4877218db48d5dae3dd72a65d" + }, + { + "alg" : "SHA-256", + "content" : "a25f2f4172c34f46b73fff03293370c3daf231a1db2883ef8032aa471779fb8b" + }, + { + "alg" : "SHA-512", + "content" : "35cc80f9b10e81624324083a024c97e247e12f54762cfaadf40504903b0ebdc76d0226af1e4646bca445211b039913709ff48289dd57e27ecab18fd6e427d306" + }, + { + "alg" : "SHA-384", + "content" : "9acae9f3f77733a83d37641d3bd32d762225a08dcb20d61ff33a9038e8a4fe2dd39026bb08026cdb618437f68fc11382" + }, + { + "alg" : "SHA3-384", + "content" : "1e605937a46c8371423b7876d5dae4363f718f70200a1276056bd6466d03096aa580708c7abc76618a141a542df29b24" + }, + { + "alg" : "SHA3-256", + "content" : "331b3c120493fb5d9dd628beb8aa10382772a08d0a687103a2e87a4516fffde6" + }, + { + "alg" : "SHA3-512", + "content" : "9f2612fbecec4664979896868e4766b1f66aaebc914e46a07a7ef7e5ff76786e5a73ae9ca5f364d23ae41f8bea2fb44e5034014950423fdc3a438ae1dc275820" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar" + }, + { + "group" : "org.apache.tomcat.embed", + "name" : "tomcat-embed-core", + "version" : "10.1.17", + "description" : "Core Tomcat implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "81d2d784780b1fe54275ab4f3d0c3830" + }, + { + "alg" : "SHA-1", + "content" : "5b9185ee002f9e194d2cb21ddcf8bc5f3d4a69da" + }, + { + "alg" : "SHA-256", + "content" : "5d70fa6ae0548f89fb4c070423ecc2db050cebf248b0d5f3f2294375a6762382" + }, + { + "alg" : "SHA-512", + "content" : "9fb1726f3a10f5e0bdd1cafcdc9532536679d04e5cdde9e54bdf18819ea2651bcaac0efddd6a8b5dbf3cfb8dfcd7ab0453f2ff3fa4e21a0f3796d4dd6d630433" + }, + { + "alg" : "SHA-384", + "content" : "e644a094c17574fc9334772913aeabd6de0be8eacb0718981dbd97ee197a21f43ff3efe2c073f8863a4ff111f4ccb303" + }, + { + "alg" : "SHA3-384", + "content" : "2e8d5d4b1e202e19529270adc7992e9d187ad34bdd62ab7633359f3394059cdade69c88dddd3879dea40487cb17702da" + }, + { + "alg" : "SHA3-256", + "content" : "25826af7f0a6fd192e83cd14481055b0c5477c325e51d17355d9ff97963380a0" + }, + { + "alg" : "SHA3-512", + "content" : "0b2513e578a484562ad47a8a1a4d1fe8253a9a276fac49ea9732877d976a2d1827037caa5a6401d5659c765317acb94127e62f99373a4efea63b44ab4a1824be" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar" + }, + { + "group" : "net.bytebuddy", + "name" : "byte-buddy-agent", + "version" : "1.14.10", + "description" : "The Byte Buddy agent offers convenience for attaching an agent to the local or a remote VM.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "389b6aca1ee862684592f6f041f81724" + }, + { + "alg" : "SHA-1", + "content" : "90ed94ac044ea8953b224304c762316e91fd6b31" + }, + { + "alg" : "SHA-256", + "content" : "67993a89d47ca58ff868802a4448ddd150e5fe4e5a5645ded990d7b4d557a6b9" + }, + { + "alg" : "SHA-512", + "content" : "7f1a1310b1a0f60d6ff07dee8d9b7e404e8fb9a25a5c0c186e00cafc834e5a026a7694fb65279367dabfa1789c1f16192d0ea794b7f511f0bb3414b8d519e9a5" + }, + { + "alg" : "SHA-384", + "content" : "ed1e1d594a7c2837311accf3f718cbc7c6e2034afcab13c63d72313ee1ffd18a53863f1ccd194b85b7e0ffed78bafc9c" + }, + { + "alg" : "SHA3-384", + "content" : "b3baeae67826ec4e4f71b2870220c362f153d2a126b04557302b5b8e24a58b9741bef7afa9c4e4f0fa1ea9371cbcb1df" + }, + { + "alg" : "SHA3-256", + "content" : "01ccb9e430868deef5b51124073643eaf6dd2c8c7e4d6e70b59042c9d28e3361" + }, + { + "alg" : "SHA3-512", + "content" : "b621fa443ade355b10cc45329a5e0f700942dd39e633a8f2343ece00446cd42f5c1217b041a67b3143df86397c363f8dcad226f1e70b8755126512a74f878262" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.10?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.10?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-test", + "version" : "6.1.2", + "description" : "Spring TestContext Framework", + "hashes" : [ + { + "alg" : "MD5", + "content" : "fadfe62dd198a4acce4416acb28e2869" + }, + { + "alg" : "SHA-1", + "content" : "c393079051398e02c20d8b24e02822f365123719" + }, + { + "alg" : "SHA-256", + "content" : "2155779c3e461df55f3b093f0e6e4bda398664e3452efe599690bc9a3f1932f0" + }, + { + "alg" : "SHA-512", + "content" : "5e6e4f76edbf17a321302bf6257c09ed7893e32c50fb3cace37b2271f3c488d397c67b5315ef3019ee6d28544f52cf593e0475bf00927cd67f0c668d6b3909a3" + }, + { + "alg" : "SHA-384", + "content" : "151df7daac9a3e3e74732405bd4feb17ad9ff3e4de196e767f39da675d4480994ed8da13e3b1b27c7b4ee9ebc17feef8" + }, + { + "alg" : "SHA3-384", + "content" : "9069193468f2ae4c65c94d3950541efe37498a4e19245ddc67909181e83e14019f956baba54da0b9d2e8a262db13abd0" + }, + { + "alg" : "SHA3-256", + "content" : "8ccf71564f5ee7e6a578031c7c8530a5ddf136cc1dce483818ebd30d53c851df" + }, + { + "alg" : "SHA3-512", + "content" : "31049da217d1115b589780ffaa3ddfbf676cc58e70bd4cbc1f24c0cb2aea6b155539f8f9b3f6757f19719fed0a6102110f195b34cdd464b5e375132c25e7bb51" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-test@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-test@6.1.2?type=jar" + }, + { + "group" : "org.junit.jupiter", + "name" : "junit-jupiter", + "version" : "5.10.1", + "description" : "Module \"junit-jupiter\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "32fd55a03f648868767c1bebedd198df" + }, + { + "alg" : "SHA-1", + "content" : "6e5c7dd668d6349cb99e52ab8321e73479a309bc" + }, + { + "alg" : "SHA-256", + "content" : "c1a386e901fae28e493185a47c8cea988fb1a37422b353a0f8b4df2e6c5d6037" + }, + { + "alg" : "SHA-512", + "content" : "c97a2f9eefa6f34441fc0c97744873040bbe49d335954edab43bab25876a33f4b3f11347459420569ef660449728aa093bbae5d42c0fa733a0b624706b57a65d" + }, + { + "alg" : "SHA-384", + "content" : "873dfccaf8366ce5b14dc0b5498205debecd90ecba20b1f1c924721764d546b5b9629dd57c486e5a5a2bc38954bf3824" + }, + { + "alg" : "SHA3-384", + "content" : "67f09e3174ae3fac6ddea13b56dcf078165e715cb18afd73d86bb980357e365cef6e62083231f09ae2accddfe62f5bcb" + }, + { + "alg" : "SHA3-256", + "content" : "1c2a60003b13025c959e7728b3f4469b67bad8649d2080c0871418fb52b1c078" + }, + { + "alg" : "SHA3-512", + "content" : "7c03cfaeabed9c57b26e083bcb0ca9a114c491216fc7e9652a39a5468579175e575ace315493610fdc7711c6557eff11933fbd28f5433c237d2277bee102c5a6" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.jupiter/junit-jupiter@5.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.jupiter/junit-jupiter@5.10.1?type=jar" + }, + { + "publisher" : "Chemouni Uriel", + "group" : "net.minidev", + "name" : "json-smart", + "version" : "2.5.0", + "description" : "JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "af9b7eda9c435acaf22e840991c7b10f" + }, + { + "alg" : "SHA-1", + "content" : "57a64f421b472849c40e77d2e7cce3a141b41e99" + }, + { + "alg" : "SHA-256", + "content" : "432b9e545848c4141b80717b26e367f83bf33f19250a228ce75da6e967da2bc7" + }, + { + "alg" : "SHA-512", + "content" : "56284bb3cee2bcc3684cdcc610115c7eacafdbd70aa852cb0209616b0503dfd448c5110b50e11a71b1c61a6e7ea27594ff63cc968230374555cc6f652d69d372" + }, + { + "alg" : "SHA-384", + "content" : "0fbbd6899d344c3158007f2f033165284323f1ecdfa49e17730d9d2bed8b3d77bbdc209a72a388e9e15a5bed9d9c8eef" + }, + { + "alg" : "SHA3-384", + "content" : "0f18f178117f8c640e7e1ac2ed4c2b28e331f658f40eac2f5974e891f7130b760e4f057859a537caaa046ba9c086a24a" + }, + { + "alg" : "SHA3-256", + "content" : "4c91eaa12f7c0ee08264ad95d016cfa41af08c963055b7f9076771da402e93e0" + }, + { + "alg" : "SHA3-512", + "content" : "0c5fad6395cf3fd25c04fd1e2c915351da4849475b463e017b760ef97800addb170d11f89791dd29ab867e343c35fd1f3ea7935622ba728d789c9f2e7fd1da51" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/net.minidev/json-smart@2.5.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://urielch.github.io/" + }, + { + "type" : "distribution", + "url" : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + }, + { + "type" : "vcs", + "url" : "https://github.com/netplex/json-smart-v2" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/net.minidev/json-smart@2.5.0?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-expression", + "version" : "6.1.2", + "description" : "Spring Expression Language (SpEL)", + "hashes" : [ + { + "alg" : "MD5", + "content" : "2f56216dc7ee08cbeafa54ccf18cad35" + }, + { + "alg" : "SHA-1", + "content" : "98786397734b27b7c8843a6b01a7fa34d40d6806" + }, + { + "alg" : "SHA-256", + "content" : "0fef5fb19f375a8632d2a117f4b3aed059b959e9693e90c3b7f57b7cad2f9e0b" + }, + { + "alg" : "SHA-512", + "content" : "a28e984d9ff1d4078d57f139ff28065ffba7f325c891c74c0774cd3ccfe50a9462cd93483c28c8ca4674b581ab723687c37c5c88e7cb080823d5629fa684e7f8" + }, + { + "alg" : "SHA-384", + "content" : "a84fb64144a67b56ce322fc9f4948a9491f6f5876d198eb57c99f38540971a0779a2949b93cc5f32662f97a83823ea87" + }, + { + "alg" : "SHA3-384", + "content" : "b099ce06de6a5543e52a2d43c97c4ed6567e82263db29849ff09cf37bf48e3e9974308698c2f272187508e242f756576" + }, + { + "alg" : "SHA3-256", + "content" : "efa3768de47e3b1ff9257f8367a528e38b3eec9c972eb7ba3dd8f60da626fb17" + }, + { + "alg" : "SHA3-512", + "content" : "95d7011482520e797a25f9d9b8db1b1bf6c24b3ddb3ca4b70fe5a1a58ed04ea870f86f8393f884dad8b893a6fc53ad8da1b21fdc01d9169564c3dc0229824b27" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-actuator", + "version" : "3.2.1", + "description" : "Starter for using Spring Boot's Actuator which provides production ready features to help you monitor and manage your application", + "hashes" : [ + { + "alg" : "MD5", + "content" : "59713236dc4fc4b1562a3ea9788bde1e" + }, + { + "alg" : "SHA-1", + "content" : "ca17ff67e80a230f04d40d73321d623b769e361d" + }, + { + "alg" : "SHA-256", + "content" : "31c28021755feab49cc9310a8353382b3ca35d0adf02926b83e4c44ea4942898" + }, + { + "alg" : "SHA-512", + "content" : "ed618c7f1e3337c90919551ad4f14996bb2a78f773ba00c1e02d5a991d1c578e940d9b73f5e01045115c7b5d3f096f8de6720ba0d28992a586ef834948f17766" + }, + { + "alg" : "SHA-384", + "content" : "45956cbd019f099f96f36391c98fd23ea32698035f90f6e4e4df0d9a43dc03ef6db2954c2871da76a038511280591b43" + }, + { + "alg" : "SHA3-384", + "content" : "3a08b673deb39ab5db9561281245b76e9f57410601e5ce4040cefedb02e2a19abb45a98d2de170fbbac7b7f0b93eceb3" + }, + { + "alg" : "SHA3-256", + "content" : "12151432b32e26bab903572023ea022757a31177e4a6315d8fcd15bbbf34731c" + }, + { + "alg" : "SHA3-512", + "content" : "911f109b63d07f20de51f8a2de8799e32fdff05a52def36d408cb1da72a3bb63ff0878f850a7ad1cc9e85393f24ac58c6b8dd4068f11d9e70bc1e130974db00f" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-actuator@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-actuator@3.2.1?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-beans", + "version" : "6.1.2", + "description" : "Spring Beans", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5ee147f2234968eeab4b469af4d3b5f1" + }, + { + "alg" : "SHA-1", + "content" : "abf52f2254975a3b1e95b2b63fb8b01d891cdc51" + }, + { + "alg" : "SHA-256", + "content" : "742baa41c1b0282ef01b3d542dc1b1de71db2578bd9ddd9a7d57fb191234b194" + }, + { + "alg" : "SHA-512", + "content" : "efd0eb5a073c899515ae144a4fcb4fc97cc53cbd4236d0e6a30df8fa8873fcd9bc509bc3fa88d1bff86a94dc3dbc5106374d0117f64ec8df9e6affe8f98aaa07" + }, + { + "alg" : "SHA-384", + "content" : "6214558d1024fa3b5545079268b0b2fbeda93768a0665d617612ddf4e42e11b770c38c05cb86e3ae558025afa67beea5" + }, + { + "alg" : "SHA3-384", + "content" : "8170ccea30165f25c533e27c0de38b590ca72f285cfc365c60e97745e78532213d6c93bdbea56f561dd180297a8c5ab4" + }, + { + "alg" : "SHA3-256", + "content" : "2761e0814e167de13ed08ce748880006407eda2fa744a347f57684c2bc9bb6fe" + }, + { + "alg" : "SHA3-512", + "content" : "ecdeb4cd558af513ed381942f35bd2d8dfa9b0db446dbc8c5326656ade960682283c71fcaae5578ca431f705f1a86041b0764bd453f30e738be65c4f0bbf37d1" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar" + } + ], + "dependencies" : [ + { + "ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/ch.qos.logback/logback-classic@1.4.14?type=jar", + "dependsOn" : [ + "pkg:maven/ch.qos.logback/logback-core@1.4.14?type=jar", + "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/io.micrometer/micrometer-jakarta9@1.12.1?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-core@1.12.1?type=jar", + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.15.3?type=jar", + "dependsOn" : [ + "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar", + "pkg:maven/com.jayway.jsonpath/json-path@2.8.0?type=jar", + "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.1?type=jar", + "pkg:maven/net.minidev/json-smart@2.5.0?type=jar", + "pkg:maven/org.assertj/assertj-core@3.24.2?type=jar", + "pkg:maven/org.awaitility/awaitility@4.2.0?type=jar", + "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar", + "pkg:maven/org.junit.jupiter/junit-jupiter@5.10.1?type=jar", + "pkg:maven/org.mockito/mockito-junit-jupiter@5.7.0?type=jar", + "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar", + "pkg:maven/org.skyscreamer/jsonassert@1.5.1?type=jar", + "pkg:maven/org.springframework/spring-test@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar", + "pkg:maven/org.xmlunit/xmlunit-core@2.9.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar", + "dependsOn" : [ + "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar", + "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.10?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-actuator@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar", + "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.yaml/snakeyaml@2.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-web@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter-json@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "pkg:maven/org.springframework/spring-webmvc@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter-tomcat@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/net.minidev/accessors-smart@2.5.0?type=jar", + "dependsOn" : [ + "pkg:maven/org.ow2.asm/asm@9.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.xmlunit/xmlunit-core@2.9.1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/io.micrometer/micrometer-core@1.12.1?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar", + "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12?type=jar", + "pkg:maven/org.latencyutils/LatencyUtils@2.0.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.opentest4j/opentest4j@1.3.0?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/net.minidev/json-smart@2.5.0?type=jar", + "dependsOn" : [ + "pkg:maven/net.minidev/accessors-smart@2.5.0?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.junit.platform/junit-platform-commons@1.10.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.17?type=jar", + "dependsOn" : [ + "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.21.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar", + "pkg:maven/org.apache.logging.log4j/log4j-api@2.21.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/ch.qos.logback/logback-classic@1.4.14?type=jar", + "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.21.1?type=jar", + "pkg:maven/org.slf4j/jul-to-slf4j@2.0.9?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.skyscreamer/jsonassert@1.5.1?type=jar", + "dependsOn" : [ + "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1?type=jar" + ] + }, + { + "ref" : "pkg:maven/ch.qos.logback/logback-core@1.4.14?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.15.3?type=jar", + "dependsOn" : [ + "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-webmvc@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-context@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.assertj/assertj-core@3.24.2?type=jar", + "dependsOn" : [ + "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.jayway.jsonpath/json-path@2.8.0?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.17?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-core@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-jcl@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.10.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar", + "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-context@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.slf4j/jul-to-slf4j@2.0.9?type=jar", + "dependsOn" : [ + "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apache.logging.log4j/log4j-api@2.21.1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.10?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.junit.jupiter/junit-jupiter@5.10.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.10.1?type=jar", + "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-tomcat@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar", + "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.17?type=jar", + "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar", + "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.17?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.awaitility/awaitility@4.2.0?type=jar", + "dependsOn" : [ + "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-actuator@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-context@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-jcl@6.1.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-json@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.mockito/mockito-junit-jupiter@5.7.0?type=jar", + "dependsOn" : [ + "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar" + ] + }, + { + "ref" : "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.junit.platform/junit-platform-commons@1.10.1?type=jar", + "pkg:maven/org.opentest4j/opentest4j@1.3.0?type=jar", + "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar", + "dependsOn" : [ + "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.1?type=jar", + "dependsOn" : [ + "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.2.1?type=jar", + "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar", + "pkg:maven/org.yaml/snakeyaml@2.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.latencyutils/LatencyUtils@2.0.3?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-test@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-actuator@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.2.1?type=jar", + "pkg:maven/io.micrometer/micrometer-jakarta9@1.12.1?type=jar", + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar", + "dependsOn" : [ + "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.example/cyclonedx@0.0.1-SNAPSHOT?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter-actuator@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter-web@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.ow2.asm/asm@9.3?type=jar", + "dependsOn" : [ ] + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/reactive/server/test.p12 b/spring-boot-project/spring-boot-actuator-docs/src/test/resources/test.p12 similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/reactive/server/test.p12 rename to spring-boot-project/spring-boot-actuator-docs/src/test/resources/test.p12 diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/build.gradle b/spring-boot-project/spring-boot-actuator-integration-tests/build.gradle new file mode 100644 index 000000000000..ec2cda314330 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/build.gradle @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" +} + +description = "Spring Boot Actuator Integration Tests" + + +dependencies { + testImplementation(project(":spring-boot-project:spring-boot-actuator")) + testImplementation(project(":spring-boot-project:spring-boot-autoconfigure")) + testImplementation(project(":spring-boot-project:spring-boot-health")) + testImplementation(project(":spring-boot-project:spring-boot-http-converter")) + testImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-jersey")) + testImplementation(project(":spring-boot-project:spring-boot-metrics")) + testImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-web-server")) + testImplementation(project(":spring-boot-project:spring-boot-webflux")) + testImplementation(project(":spring-boot-project:spring-boot-webmvc")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) + testImplementation("io.micrometer:micrometer-registry-prometheus") + testImplementation("io.prometheus:prometheus-metrics-exposition-formats") + testImplementation("net.minidev:json-smart") + testImplementation("org.springframework.security:spring-security-web") + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-integration-tests/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/static/custom.css b/spring-boot-project/spring-boot-actuator-integration-tests/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/static/custom.css rename to spring-boot-project/spring-boot-actuator-integration-tests/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/AbstractWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/AbstractWebEndpointIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/AbstractWebEndpointIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/AbstractWebEndpointIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java new file mode 100644 index 000000000000..5e23c718ef6c --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.annotation; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; +import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; +import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.PathMapper; +import org.springframework.boot.tomcat.TomcatEmbeddedWebappClassLoader; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.core.convert.support.DefaultConversionService; + +import static org.mockito.Mockito.mock; + +/** + * Base configuration shared by tests. + * + * @author Andy Wilkinson + */ +@Configuration(proxyBeanMethods = false) +class BaseConfiguration { + + @Bean + AbstractWebEndpointIntegrationTests.EndpointDelegate endpointDelegate() { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader instanceof TomcatEmbeddedWebappClassLoader) { + Thread.currentThread().setContextClassLoader(classLoader.getParent()); + } + try { + return mock(AbstractWebEndpointIntegrationTests.EndpointDelegate.class); + } + finally { + Thread.currentThread().setContextClassLoader(classLoader); + } + } + + @Bean + EndpointMediaTypes endpointMediaTypes() { + List mediaTypes = Arrays.asList("application/vnd.test+json", "application/json"); + return new EndpointMediaTypes(mediaTypes, mediaTypes); + } + + @Bean + WebEndpointDiscoverer webEndpointDiscoverer(EndpointMediaTypes endpointMediaTypes, + ApplicationContext applicationContext, ObjectProvider pathMappers) { + ParameterValueMapper parameterMapper = new ConversionServiceParameterValueMapper( + DefaultConversionService.getSharedInstance()); + return new WebEndpointDiscoverer(applicationContext, parameterMapper, endpointMediaTypes, + pathMappers.orderedStream().toList(), Collections.emptyList(), Collections.emptyList(), + Collections.emptyList(), Collections.emptyList()); + } + + @Bean + static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java new file mode 100644 index 000000000000..42e73b807d74 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java @@ -0,0 +1,172 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.jersey; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.ext.ContextResolver; +import org.glassfish.jersey.jackson.JacksonFeature; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.Resource; +import org.glassfish.jersey.servlet.ServletContainer; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; +import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +/** + * Integration tests for web endpoints exposed using Jersey. + * + * @author Andy Wilkinson + * @see JerseyEndpointResourceFactory + */ +class JerseyWebEndpointIntegrationTests + extends AbstractWebEndpointIntegrationTests { + + JerseyWebEndpointIntegrationTests() { + super(JerseyWebEndpointIntegrationTests::createApplicationContext, + JerseyWebEndpointIntegrationTests::applyAuthenticatedConfiguration); + } + + private static AnnotationConfigServletWebServerApplicationContext createApplicationContext() { + AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); + context.register(JerseyConfiguration.class); + return context; + } + + private static void applyAuthenticatedConfiguration(AnnotationConfigServletWebServerApplicationContext context) { + context.register(AuthenticatedConfiguration.class); + } + + @Override + protected int getPort(AnnotationConfigServletWebServerApplicationContext context) { + return context.getWebServer().getPort(); + } + + @Override + protected void validateErrorBody(WebTestClient.BodyContentSpec body, HttpStatus status, String path, + String message) { + // Jersey doesn't support the general error page handling + } + + @Override + @Test + @Disabled("Jersey does not distinguish between /example and /example/") + protected void operationWithTrailingSlashShouldNotMatch() { + } + + @Configuration(proxyBeanMethods = false) + static class JerseyConfiguration { + + @Bean + TomcatServletWebServerFactory tomcat() { + return new TomcatServletWebServerFactory(0); + } + + @Bean + ServletRegistrationBean servletContainer(ResourceConfig resourceConfig) { + return new ServletRegistrationBean<>(new ServletContainer(resourceConfig), "/*"); + } + + @Bean + ResourceConfig resourceConfig(Environment environment, WebEndpointDiscoverer endpointDiscoverer, + EndpointMediaTypes endpointMediaTypes) { + ResourceConfig resourceConfig = new ResourceConfig(); + String endpointPath = environment.getProperty("endpointPath"); + Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( + new EndpointMapping(endpointPath), endpointDiscoverer.getEndpoints(), endpointMediaTypes, + new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath)); + resourceConfig.registerResources(new HashSet<>(resources)); + resourceConfig.register(JacksonFeature.class); + resourceConfig.register(new ObjectMapperContextResolver(new ObjectMapper()), ContextResolver.class); + return resourceConfig; + } + + } + + @Configuration(proxyBeanMethods = false) + static class AuthenticatedConfiguration { + + @Bean + Filter securityFilter() { + return new OncePerRequestFilter() { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + SecurityContext context = SecurityContextHolder.createEmptyContext(); + context.setAuthentication(new UsernamePasswordAuthenticationToken("Alice", "secret", + Arrays.asList(new SimpleGrantedAuthority("ROLE_ACTUATOR")))); + SecurityContextHolder.setContext(context); + try { + filterChain.doFilter(new SecurityContextHolderAwareRequestWrapper(request, "ROLE_"), response); + } + finally { + SecurityContextHolder.clearContext(); + } + } + + }; + } + + } + + private static final class ObjectMapperContextResolver implements ContextResolver { + + private final ObjectMapper objectMapper; + + private ObjectMapperContextResolver(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public ObjectMapper getContext(Class type) { + return this.objectMapper; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java new file mode 100644 index 000000000000..ee895e5ee807 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java @@ -0,0 +1,250 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.reactive; + +import java.net.URI; +import java.time.Duration; +import java.util.Collections; +import java.util.Map; +import java.util.function.Consumer; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointDiscoverer; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier; +import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.actuate.endpoint.web.ControllerEndpointHandlerMapping; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; +import org.springframework.web.util.DefaultUriBuilderFactory; + +/** + * Integration tests for {@link ControllerEndpointHandlerMapping}. + * + * @author Phillip Webb + * @author Stephane Nicoll + * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support + */ +@SuppressWarnings("removal") +@Deprecated(since = "3.3.5", forRemoval = true) +class ControllerEndpointHandlerMappingIntegrationTests { + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner( + AnnotationConfigReactiveWebServerApplicationContext::new) + .withUserConfiguration(EndpointConfiguration.class, ExampleWebFluxEndpoint.class); + + @Test + void getMapping() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() + .uri("/actuator/example/one") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) + .expectBody(String.class) + .isEqualTo("One"))); + } + + @Test + void getWithUnacceptableContentType() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() + .uri("/actuator/example/one") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isEqualTo(HttpStatus.NOT_ACCEPTABLE))); + } + + @Test + void postMapping() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.post() + .uri("/actuator/example/two") + .bodyValue(Collections.singletonMap("id", "test")) + .exchange() + .expectStatus() + .isCreated() + .expectHeader() + .valueEquals(HttpHeaders.LOCATION, "/example/test"))); + } + + @Test + void postMappingWithReadOnlyAccessRespondsWith404() { + this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") + .run(withWebTestClient((webTestClient) -> webTestClient.post() + .uri("/actuator/example/two") + .bodyValue(Collections.singletonMap("id", "test")) + .exchange() + .expectStatus() + .isNotFound())); + } + + @Test + void getToRequestMapping() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() + .uri("/actuator/example/three") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) + .expectBody(String.class) + .isEqualTo("Three"))); + } + + @Test + void getToRequestMappingWithReadOnlyAccess() { + this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") + .run(withWebTestClient((webTestClient) -> webTestClient.get() + .uri("/actuator/example/three") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) + .expectBody(String.class) + .isEqualTo("Three"))); + } + + @Test + void postToRequestMapping() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.post() + .uri("/actuator/example/three") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) + .expectBody(String.class) + .isEqualTo("Three"))); + } + + @Test + void postToRequestMappingWithReadOnlyAccessRespondsWith405() { + this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") + .run(withWebTestClient((webTestClient) -> webTestClient.post() + .uri("/actuator/example/three") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isEqualTo(HttpStatus.METHOD_NOT_ALLOWED))); + } + + private ContextConsumer withWebTestClient( + Consumer webClient) { + return (context) -> { + int port = ((AnnotationConfigReactiveWebServerApplicationContext) context.getSourceApplicationContext()) + .getWebServer() + .getPort(); + WebTestClient webTestClient = createWebTestClient(port); + webClient.accept(webTestClient); + }; + } + + private WebTestClient createWebTestClient(int port) { + DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://localhost:" + port); + uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE); + return WebTestClient.bindToServer() + .uriBuilderFactory(uriBuilderFactory) + .responseTimeout(Duration.ofMinutes(5)) + .build(); + } + + @Configuration(proxyBeanMethods = false) + @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + WebFluxAutoConfiguration.class }) + static class EndpointConfiguration { + + @Bean + NettyReactiveWebServerFactory netty() { + return new NettyReactiveWebServerFactory(0); + } + + @Bean + HttpHandler httpHandler(ApplicationContext applicationContext) { + return WebHttpHandlerBuilder.applicationContext(applicationContext).build(); + } + + @Bean + ControllerEndpointDiscoverer webEndpointDiscoverer(ApplicationContext applicationContext) { + return new ControllerEndpointDiscoverer(applicationContext, null, Collections.emptyList()); + } + + @Bean + ControllerEndpointHandlerMapping webEndpointHandlerMapping(ControllerEndpointsSupplier endpointsSupplier, + EndpointAccessResolver endpointAccessResolver) { + return new ControllerEndpointHandlerMapping(new EndpointMapping("actuator"), + endpointsSupplier.getEndpoints(), null, endpointAccessResolver); + } + + @Bean + EndpointAccessResolver endpointAccessResolver(Environment environment) { + return (id, defaultAccess) -> environment.getProperty("endpoint-access", Access.class, Access.UNRESTRICTED); + } + + } + + @RestControllerEndpoint(id = "example") + static class ExampleWebFluxEndpoint { + + @GetMapping(path = "one", produces = MediaType.TEXT_PLAIN_VALUE) + String one() { + return "One"; + } + + @PostMapping("/two") + ResponseEntity two(@RequestBody Map content) { + return ResponseEntity.created(URI.create("/example/" + content.get("id"))).build(); + } + + @RequestMapping(path = "/three", produces = MediaType.TEXT_PLAIN_VALUE) + String three() { + return "Three"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java new file mode 100644 index 000000000000..e5ad0e979169 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java @@ -0,0 +1,165 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.reactive; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.reactive.context.ReactiveWebServerInitializedEvent; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; +import org.springframework.boot.webflux.autoconfigure.error.ErrorWebFluxAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import org.springframework.util.StringUtils; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for web endpoints exposed using WebFlux. + * + * @author Andy Wilkinson + * @see WebFluxEndpointHandlerMapping + */ +class WebFluxEndpointIntegrationTests + extends AbstractWebEndpointIntegrationTests { + + WebFluxEndpointIntegrationTests() { + super(WebFluxEndpointIntegrationTests::createApplicationContext, + WebFluxEndpointIntegrationTests::applyAuthenticatedConfiguration); + + } + + private static AnnotationConfigReactiveWebServerApplicationContext createApplicationContext() { + AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext(); + context.register(ReactiveConfiguration.class); + return context; + } + + private static void applyAuthenticatedConfiguration(AnnotationConfigReactiveWebServerApplicationContext context) { + context.register(AuthenticatedConfiguration.class); + } + + @Test + void responseToOptionsRequestIncludesCorsHeaders() { + load(TestEndpointConfiguration.class, + (client) -> client.options() + .uri("/test") + .accept(MediaType.APPLICATION_JSON) + .header("Access-Control-Request-Method", "POST") + .header("Origin", "https://example.com") + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .valueEquals("Access-Control-Allow-Origin", "https://example.com") + .expectHeader() + .valueEquals("Access-Control-Allow-Methods", "GET,POST")); + } + + @Test + void readOperationsThatReturnAResourceSupportRangeRequests() { + load(ResourceEndpointConfiguration.class, (client) -> { + byte[] responseBody = client.get() + .uri("/resource") + .header("Range", "bytes=0-3") + .exchange() + .expectStatus() + .isEqualTo(HttpStatus.PARTIAL_CONTENT) + .expectHeader() + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .returnResult(byte[].class) + .getResponseBodyContent(); + assertThat(responseBody).containsExactly(0, 1, 2, 3); + }); + } + + @Override + protected int getPort(AnnotationConfigReactiveWebServerApplicationContext context) { + return context.getBean(ReactiveConfiguration.class).port; + } + + @Configuration(proxyBeanMethods = false) + @EnableWebFlux + @ImportAutoConfiguration(ErrorWebFluxAutoConfiguration.class) + static class ReactiveConfiguration { + + private int port; + + @Bean + NettyReactiveWebServerFactory netty() { + return new NettyReactiveWebServerFactory(0); + } + + @Bean + HttpHandler httpHandler(ApplicationContext applicationContext) { + return WebHttpHandlerBuilder.applicationContext(applicationContext).build(); + } + + @Bean + WebFluxEndpointHandlerMapping webEndpointHandlerMapping(Environment environment, + WebEndpointDiscoverer endpointDiscoverer, EndpointMediaTypes endpointMediaTypes) { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com")); + corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST")); + String endpointPath = environment.getProperty("endpointPath"); + return new WebFluxEndpointHandlerMapping(new EndpointMapping(endpointPath), + endpointDiscoverer.getEndpoints(), endpointMediaTypes, corsConfiguration, + new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath)); + } + + @Bean + ApplicationListener serverInitializedListener() { + return (event) -> this.port = event.getWebServer().getPort(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class AuthenticatedConfiguration { + + @Bean + WebFilter webFilter() { + return (exchange, chain) -> chain.filter(exchange) + .contextWrite(ReactiveSecurityContextHolder.withAuthentication(new UsernamePasswordAuthenticationToken( + "Alice", "secret", Arrays.asList(new SimpleGrantedAuthority("ROLE_ACTUATOR"))))); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingIntegrationTests.java new file mode 100644 index 000000000000..d8d00c805cbe --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingIntegrationTests.java @@ -0,0 +1,248 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.servlet; + +import java.net.URI; +import java.time.Duration; +import java.util.Collections; +import java.util.Map; +import java.util.function.Consumer; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointDiscoverer; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier; +import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.webmvc.actuate.endpoint.web.ControllerEndpointHandlerMapping; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.util.DefaultUriBuilderFactory; + +/** + * Integration tests for {@link ControllerEndpointHandlerMapping}. + * + * @author Phillip Webb + * @author Stephane Nicoll + * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support + */ +@Deprecated(since = "3.3.5", forRemoval = true) +@SuppressWarnings("removal") +class ControllerEndpointHandlerMappingIntegrationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withUserConfiguration(EndpointConfiguration.class, ExampleMvcEndpoint.class); + + @Test + void getMapping() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() + .uri("/actuator/example/one") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) + .expectBody(String.class) + .isEqualTo("One"))); + } + + @Test + void getWithUnacceptableContentType() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() + .uri("/actuator/example/one") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isEqualTo(HttpStatus.NOT_ACCEPTABLE))); + } + + @Test + void postMapping() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.post() + .uri("/actuator/example/two") + .bodyValue(Collections.singletonMap("id", "test")) + .exchange() + .expectStatus() + .isCreated() + .expectHeader() + .valueEquals(HttpHeaders.LOCATION, "/example/test"))); + } + + @Test + void postMappingWithReadOnlyAccessRespondsWith404() { + this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") + .run(withWebTestClient((webTestClient) -> webTestClient.post() + .uri("/actuator/example/two") + .bodyValue(Collections.singletonMap("id", "test")) + .exchange() + .expectStatus() + .isNotFound())); + } + + @Test + void getToRequestMapping() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() + .uri("/actuator/example/three") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) + .expectBody(String.class) + .isEqualTo("Three"))); + } + + @Test + void getToRequestMappingWithReadOnlyAccess() { + this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") + .run(withWebTestClient((webTestClient) -> webTestClient.get() + .uri("/actuator/example/three") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) + .expectBody(String.class) + .isEqualTo("Three"))); + } + + @Test + void postToRequestMapping() { + this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.post() + .uri("/actuator/example/three") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) + .expectBody(String.class) + .isEqualTo("Three"))); + } + + @Test + void postToRequestMappingWithReadOnlyAccessRespondsWith405() { + this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") + .run(withWebTestClient((webTestClient) -> webTestClient.post() + .uri("/actuator/example/three") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isEqualTo(HttpStatus.METHOD_NOT_ALLOWED))); + } + + private ContextConsumer withWebTestClient(Consumer webClient) { + return (context) -> { + int port = ((AnnotationConfigServletWebServerApplicationContext) context.getSourceApplicationContext()) + .getWebServer() + .getPort(); + WebTestClient webTestClient = createWebTestClient(port); + webClient.accept(webTestClient); + }; + } + + private WebTestClient createWebTestClient(int port) { + DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://localhost:" + port); + uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE); + return WebTestClient.bindToServer() + .uriBuilderFactory(uriBuilderFactory) + .responseTimeout(Duration.ofMinutes(5)) + .build(); + } + + @Configuration(proxyBeanMethods = false) + @EnableWebMvc + @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) + static class EndpointConfiguration { + + @Bean + TomcatServletWebServerFactory tomcat() { + return new TomcatServletWebServerFactory(0); + } + + @Bean + ControllerEndpointDiscoverer webEndpointDiscoverer(ApplicationContext applicationContext) { + return new ControllerEndpointDiscoverer(applicationContext, null, Collections.emptyList()); + } + + @Bean + ControllerEndpointHandlerMapping webEndpointHandlerMapping(ControllerEndpointsSupplier endpointsSupplier, + EndpointAccessResolver endpointAccessResolver) { + return new ControllerEndpointHandlerMapping(new EndpointMapping("actuator"), + endpointsSupplier.getEndpoints(), null, endpointAccessResolver); + } + + @Bean + EndpointAccessResolver endpointAccessResolver(Environment environment) { + return (id, defaultAccess) -> environment.getProperty("endpoint-access", Access.class, Access.UNRESTRICTED); + } + + @Bean + DispatcherServlet dispatcherServlet() { + return new DispatcherServlet(); + } + + } + + @RestControllerEndpoint(id = "example") + static class ExampleMvcEndpoint { + + @GetMapping(path = "one", produces = MediaType.TEXT_PLAIN_VALUE) + String one() { + return "One"; + } + + @PostMapping("/two") + ResponseEntity two(@RequestBody Map content) { + return ResponseEntity.created(URI.create("/example/" + content.get("id"))).build(); + } + + @RequestMapping(path = "/three", produces = MediaType.TEXT_PLAIN_VALUE) + String three() { + return "Three"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java index 86e25863b434..fb63b7a200f6 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/MvcWebEndpointIntegrationTests.java @@ -32,14 +32,15 @@ import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.error.ErrorMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -132,7 +133,7 @@ protected int getPort(AnnotationConfigServletWebServerApplicationContext context @Configuration(proxyBeanMethods = false) @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, WebMvcAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class, ErrorMvcAutoConfiguration.class }) static class WebMvcConfiguration { @@ -157,7 +158,7 @@ WebMvcEndpointHandlerMapping webEndpointHandlerMapping(Environment environment, @Configuration(proxyBeanMethods = false) @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, WebMvcAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class, ErrorMvcAutoConfiguration.class }) static class PathMatcherWebMvcConfiguration { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebIntegrationTests.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebIntegrationTests.java index 1c4dd2d1c754..5497eb0ba72f 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebIntegrationTests.java @@ -27,6 +27,18 @@ import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorNameGenerator; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.CompositeReactiveHealthContributor; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; +import org.springframework.boot.health.registry.DefaultHealthContributorRegistry; +import org.springframework.boot.health.registry.DefaultReactiveHealthContributorRegistry; +import org.springframework.boot.health.registry.HealthContributorRegistry; +import org.springframework.boot.health.registry.ReactiveHealthContributorRegistry; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -199,8 +211,7 @@ private void withHealthContributor(ApplicationContext context, String name, Heal } } - private > R getContributorRegistry(ApplicationContext context, - Class registryType) { + private R getContributorRegistry(ApplicationContext context, Class registryType) { return context.getBeanProvider(registryType).getIfAvailable(); } @@ -242,7 +253,9 @@ static class TestConfiguration { @Bean HealthContributorRegistry healthContributorRegistry(Map healthContributorBeans) { - return new DefaultHealthContributorRegistry(healthContributorBeans); + return new DefaultHealthContributorRegistry( + HealthContributorNameGenerator.withoutStandardSuffixes().apply(healthContributorBeans), + Collections.emptyList()); } @Bean @@ -250,10 +263,14 @@ HealthContributorRegistry healthContributorRegistry(Map healthContributorBeans, Map reactiveHealthContributorBeans) { - Map allIndicators = new LinkedHashMap<>(reactiveHealthContributorBeans); - healthContributorBeans.forEach((name, contributor) -> allIndicators.computeIfAbsent(name, - (key) -> ReactiveHealthContributor.adapt(contributor))); - return new DefaultReactiveHealthContributorRegistry(allIndicators); + HealthContributorNameGenerator nameGenerator = HealthContributorNameGenerator.withoutStandardSuffixes(); + Map contributors = new LinkedHashMap<>(); + contributors.putAll(nameGenerator.apply(reactiveHealthContributorBeans)); + healthContributorBeans.forEach((beanName, bean) -> { + String contributorName = nameGenerator.generateContributorName(beanName); + contributors.computeIfAbsent(contributorName, (key) -> ReactiveHealthContributor.adapt(bean)); + }); + return new DefaultReactiveHealthContributorRegistry(contributors, Collections.emptyList()); } @Bean diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/health/TestHealthEndpointGroup.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/health/TestHealthEndpointGroup.java new file mode 100644 index 000000000000..ab6fb421eeef --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/health/TestHealthEndpointGroup.java @@ -0,0 +1,92 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.health; + +import java.util.function.Predicate; + +import org.springframework.boot.actuate.endpoint.SecurityContext; + +/** + * Test implementation of {@link HealthEndpointGroups}. + * + * @author Phillip Webb + */ +class TestHealthEndpointGroup implements HealthEndpointGroup { + + private final StatusAggregator statusAggregator = new SimpleStatusAggregator(); + + private final HttpCodeStatusMapper httpCodeStatusMapper = new SimpleHttpCodeStatusMapper(); + + private final Predicate memberPredicate; + + private Boolean showComponents; + + private boolean showDetails = true; + + private AdditionalHealthEndpointPath additionalPath; + + TestHealthEndpointGroup() { + this((name) -> true); + } + + TestHealthEndpointGroup(Predicate memberPredicate) { + this.memberPredicate = memberPredicate; + } + + @Override + public boolean isMember(String name) { + return this.memberPredicate.test(name); + } + + @Override + public boolean showComponents(SecurityContext securityContext) { + return (this.showComponents != null) ? this.showComponents : this.showDetails; + } + + void setShowComponents(Boolean showComponents) { + this.showComponents = showComponents; + } + + @Override + public boolean showDetails(SecurityContext securityContext) { + return this.showDetails; + } + + void setShowDetails(boolean includeDetails) { + this.showDetails = includeDetails; + } + + @Override + public StatusAggregator getStatusAggregator() { + return this.statusAggregator; + } + + @Override + public HttpCodeStatusMapper getHttpCodeStatusMapper() { + return this.httpCodeStatusMapper; + } + + @Override + public AdditionalHealthEndpointPath getAdditionalPath() { + return this.additionalPath; + } + + void setAdditionalPath(AdditionalHealthEndpointPath additionalPath) { + this.additionalPath = additionalPath; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/InfoEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/info/InfoEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/InfoEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/info/InfoEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/logging/LogFileWebEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LoggersEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/logging/LoggersEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LoggersEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/logging/LoggersEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/HeapDumpWebEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/management/HeapDumpWebEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/HeapDumpWebEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/management/HeapDumpWebEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java index c313c6cd6dee..1cfce12dddf1 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java @@ -28,6 +28,7 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest; +import org.springframework.boot.metrics.actuate.endpoint.MetricsEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpointIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpointIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/metrics/export/prometheus/PrometheusScrapeEndpointIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointCycloneDxWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointCycloneDxWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointCycloneDxWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointCycloneDxWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointSpdxWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointSpdxWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointSpdxWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointSpdxWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointSyftWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointSyftWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointSyftWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointSyftWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointWebIntegrationTests.java similarity index 100% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/sbom/SbomEndpointWebIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointIntegrationTests.java new file mode 100644 index 000000000000..f470600a95f0 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointIntegrationTests.java @@ -0,0 +1,333 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.web.mappings; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +import jakarta.servlet.FilterRegistration; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.web.mappings.MappingsEndpoint.ApplicationMappingsDescriptor; +import org.springframework.boot.actuate.web.mappings.MappingsEndpoint.ContextMappingsDescriptor; +import org.springframework.boot.servlet.actuate.mappings.FilterRegistrationMappingDescription; +import org.springframework.boot.servlet.actuate.mappings.FiltersMappingDescriptionProvider; +import org.springframework.boot.servlet.actuate.mappings.ServletRegistrationMappingDescription; +import org.springframework.boot.servlet.actuate.mappings.ServletsMappingDescriptionProvider; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.boot.webflux.actuate.mappings.DispatcherHandlerMappingDescription; +import org.springframework.boot.webflux.actuate.mappings.DispatcherHandlersMappingDescriptionProvider; +import org.springframework.boot.webmvc.actuate.mappings.DispatcherServletMappingDescription; +import org.springframework.boot.webmvc.actuate.mappings.DispatcherServletsMappingDescriptionProvider; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mock.web.MockServletConfig; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.ConfigurableWebApplicationContext; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.function.RequestPredicates; +import org.springframework.web.servlet.function.RouterFunctions; +import org.springframework.web.util.pattern.PathPatternParser; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.springframework.web.reactive.function.server.RequestPredicates.GET; +import static org.springframework.web.reactive.function.server.RequestPredicates.POST; +import static org.springframework.web.reactive.function.server.RouterFunctions.route; + +/** + * Integration tests for {@link MappingsEndpoint}. + * + * @author Andy Wilkinson + * @author Stephane Nicoll + * @author Xiong Tang + */ +class MappingsEndpointIntegrationTests { + + @Test + void servletWebMappings() { + Supplier contextSupplier = prepareContextSupplier(); + new WebApplicationContextRunner(contextSupplier) + .withUserConfiguration(EndpointConfiguration.class, ServletWebConfiguration.class) + .run((context) -> { + ContextMappingsDescriptor contextMappings = contextMappings(context); + assertThat(contextMappings.getParentId()).isNull(); + assertThat(contextMappings.getMappings()).containsOnlyKeys("dispatcherServlets", "servletFilters", + "servlets"); + Map> dispatcherServlets = mappings(contextMappings, + "dispatcherServlets"); + assertThat(dispatcherServlets).containsOnlyKeys("dispatcherServlet"); + List handlerMappings = dispatcherServlets.get("dispatcherServlet"); + assertThat(handlerMappings).hasSize(4); + List servlets = mappings(contextMappings, "servlets"); + assertThat(servlets).hasSize(1); + List filters = mappings(contextMappings, "servletFilters"); + assertThat(filters).hasSize(1); + }); + } + + @Test + void servletWebMappingsWithPathPatternParser() { + Supplier contextSupplier = prepareContextSupplier(); + new WebApplicationContextRunner(contextSupplier) + .withUserConfiguration(EndpointConfiguration.class, ServletWebConfiguration.class, + PathPatternParserConfiguration.class) + .run((context) -> { + ContextMappingsDescriptor contextMappings = contextMappings(context); + assertThat(contextMappings.getParentId()).isNull(); + assertThat(contextMappings.getMappings()).containsOnlyKeys("dispatcherServlets", "servletFilters", + "servlets"); + Map> dispatcherServlets = mappings(contextMappings, + "dispatcherServlets"); + assertThat(dispatcherServlets).containsOnlyKeys("dispatcherServlet"); + List handlerMappings = dispatcherServlets.get("dispatcherServlet"); + assertThat(handlerMappings).hasSize(4); + List servlets = mappings(contextMappings, "servlets"); + assertThat(servlets).hasSize(1); + List filters = mappings(contextMappings, "servletFilters"); + assertThat(filters).hasSize(1); + }); + } + + @Test + void servletWebMappingsWithAdditionalDispatcherServlets() { + Supplier contextSupplier = prepareContextSupplier(); + new WebApplicationContextRunner(contextSupplier) + .withUserConfiguration(EndpointConfiguration.class, ServletWebConfiguration.class, + CustomDispatcherServletConfiguration.class) + .run((context) -> { + ContextMappingsDescriptor contextMappings = contextMappings(context); + Map> dispatcherServlets = mappings(contextMappings, + "dispatcherServlets"); + assertThat(dispatcherServlets).containsOnlyKeys("dispatcherServlet", + "customDispatcherServletRegistration", "anotherDispatcherServletRegistration"); + assertThat(dispatcherServlets.get("dispatcherServlet")).hasSize(4); + assertThat(dispatcherServlets.get("customDispatcherServletRegistration")).hasSize(4); + assertThat(dispatcherServlets.get("anotherDispatcherServletRegistration")).hasSize(4); + }); + } + + @SuppressWarnings("unchecked") + private Supplier prepareContextSupplier() { + ServletContext servletContext = mock(ServletContext.class); + given(servletContext.getInitParameterNames()).willReturn(Collections.emptyEnumeration()); + given(servletContext.getAttributeNames()).willReturn(Collections.emptyEnumeration()); + FilterRegistration filterRegistration = mock(FilterRegistration.class); + given((Map) servletContext.getFilterRegistrations()) + .willReturn(Collections.singletonMap("testFilter", filterRegistration)); + ServletRegistration servletRegistration = mock(ServletRegistration.class); + given((Map) servletContext.getServletRegistrations()) + .willReturn(Collections.singletonMap("testServlet", servletRegistration)); + return () -> { + AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext(); + context.setServletContext(servletContext); + return context; + }; + } + + @Test + void reactiveWebMappings() { + new ReactiveWebApplicationContextRunner() + .withUserConfiguration(EndpointConfiguration.class, ReactiveWebConfiguration.class) + .run((context) -> { + ContextMappingsDescriptor contextMappings = contextMappings(context); + assertThat(contextMappings.getParentId()).isNull(); + assertThat(contextMappings.getMappings()).containsOnlyKeys("dispatcherHandlers"); + Map> dispatcherHandlers = mappings(contextMappings, + "dispatcherHandlers"); + assertThat(dispatcherHandlers).containsOnlyKeys("webHandler"); + List handlerMappings = dispatcherHandlers.get("webHandler"); + assertThat(handlerMappings).hasSize(4); + }); + } + + private ContextMappingsDescriptor contextMappings(ApplicationContext context) { + ApplicationMappingsDescriptor applicationMappings = context.getBean(MappingsEndpoint.class).mappings(); + assertThat(applicationMappings.getContexts()).containsOnlyKeys(context.getId()); + return applicationMappings.getContexts().get(context.getId()); + } + + @SuppressWarnings("unchecked") + private T mappings(ContextMappingsDescriptor contextMappings, String key) { + return (T) contextMappings.getMappings().get(key); + } + + @Configuration(proxyBeanMethods = false) + static class EndpointConfiguration { + + @Bean + MappingsEndpoint mappingsEndpoint(Collection descriptionProviders, + ApplicationContext context) { + return new MappingsEndpoint(descriptionProviders, context); + } + + } + + @Configuration(proxyBeanMethods = false) + @EnableWebFlux + @Controller + static class ReactiveWebConfiguration { + + @Bean + DispatcherHandlersMappingDescriptionProvider dispatcherHandlersMappingDescriptionProvider() { + return new DispatcherHandlersMappingDescriptionProvider(); + } + + @Bean + RouterFunction routerFunction() { + return route(GET("/one"), (request) -> ServerResponse.ok().build()).andRoute(POST("/two"), + (request) -> ServerResponse.ok().build()); + } + + @RequestMapping("/three") + void three() { + + } + + @Bean + RouterFunction routerFunctionWithAttributes() { + return route(GET("/four"), (request) -> ServerResponse.ok().build()).withAttribute("test", "test"); + } + + } + + @Configuration(proxyBeanMethods = false) + @EnableWebMvc + @Controller + static class ServletWebConfiguration { + + @Bean + DispatcherServletsMappingDescriptionProvider dispatcherServletsMappingDescriptionProvider() { + return new DispatcherServletsMappingDescriptionProvider(); + } + + @Bean + ServletsMappingDescriptionProvider servletsMappingDescriptionProvider() { + return new ServletsMappingDescriptionProvider(); + } + + @Bean + FiltersMappingDescriptionProvider filtersMappingDescriptionProvider() { + return new FiltersMappingDescriptionProvider(); + } + + @Bean + DispatcherServlet dispatcherServlet(WebApplicationContext context) throws ServletException { + DispatcherServlet dispatcherServlet = new DispatcherServlet(context); + dispatcherServlet.init(new MockServletConfig()); + return dispatcherServlet; + } + + @Bean + org.springframework.web.servlet.function.RouterFunction routerFunction() { + return RouterFunctions + .route(RequestPredicates.GET("/one"), + (request) -> org.springframework.web.servlet.function.ServerResponse.ok().build()) + .andRoute(RequestPredicates.POST("/two"), + (request) -> org.springframework.web.servlet.function.ServerResponse.ok().build()); + } + + @RequestMapping("/three") + void three() { + + } + + @Bean + org.springframework.web.servlet.function.RouterFunction routerFunctionWithAttributes() { + return RouterFunctions + .route(RequestPredicates.GET("/four"), + (request) -> org.springframework.web.servlet.function.ServerResponse.ok().build()) + .withAttribute("test", "test"); + } + + } + + @Configuration + static class CustomDispatcherServletConfiguration { + + @Bean + ServletRegistrationBean customDispatcherServletRegistration(WebApplicationContext context) { + ServletRegistrationBean registration = new ServletRegistrationBean<>( + createTestDispatcherServlet(context)); + registration.setName("customDispatcherServletRegistration"); + return registration; + } + + @Bean + DispatcherServlet anotherDispatcherServlet(WebApplicationContext context) { + return createTestDispatcherServlet(context); + } + + @Bean + ServletRegistrationBean anotherDispatcherServletRegistration( + DispatcherServlet dispatcherServlet, WebApplicationContext context) { + ServletRegistrationBean registrationBean = new ServletRegistrationBean<>( + anotherDispatcherServlet(context)); + registrationBean.setName("anotherDispatcherServletRegistration"); + return registrationBean; + } + + private DispatcherServlet createTestDispatcherServlet(WebApplicationContext context) { + try { + DispatcherServlet dispatcherServlet = new DispatcherServlet(context); + dispatcherServlet.init(new MockServletConfig()); + return dispatcherServlet; + } + catch (ServletException ex) { + throw new IllegalStateException(ex); + } + } + + } + + @Configuration + static class PathPatternParserConfiguration { + + @Bean + WebMvcConfigurer pathPatternParserConfigurer() { + return new WebMvcConfigurer() { + + @Override + public void configurePathMatch(PathMatchConfigurer configurer) { + configurer.setPatternParser(new PathPatternParser()); + } + + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/cyclonedx.json b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/cyclonedx.json new file mode 100644 index 000000000000..d5c78df8ea6f --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/cyclonedx.json @@ -0,0 +1,4615 @@ +{ + "bomFormat" : "CycloneDX", + "specVersion" : "1.5", + "serialNumber" : "urn:uuid:13862013-3360-43e5-8055-3645aa43c548", + "version" : 1, + "metadata" : { + "timestamp" : "2024-01-12T11:10:49Z", + "tools" : [ + { + "vendor" : "CycloneDX", + "name" : "cyclonedx-gradle-plugin", + "version" : "1.8.1" + } + ], + "component" : { + "group" : "org.example", + "name" : "cyclonedx", + "version" : "0.0.1-SNAPSHOT", + "purl" : "pkg:maven/org.example/cyclonedx@0.0.1-SNAPSHOT?type=jar", + "type" : "library", + "bom-ref" : "pkg:maven/org.example/cyclonedx@0.0.1-SNAPSHOT?type=jar" + } + }, + "components" : [ + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-aop", + "version" : "6.1.2", + "description" : "Spring AOP", + "hashes" : [ + { + "alg" : "MD5", + "content" : "c9b8757051ed6c1cc9fda0e379283348" + }, + { + "alg" : "SHA-1", + "content" : "a247bd81df8fa9c6a002b95969692bfd146a70b2" + }, + { + "alg" : "SHA-256", + "content" : "e47b66833ebec281374d55b4e36352b80fe3fa64c94252481a8a7e8d31d9d601" + }, + { + "alg" : "SHA-512", + "content" : "b1cb69feb2931bd4af48b2329614f8e2a0d1afe77267af5f5ea9717ab24c83fd524c8bc7aa8d357a6ccbc497535c4fd282ddfb6d78364a349895a14825af8b9c" + }, + { + "alg" : "SHA-384", + "content" : "09c3c2711a054993922d28b76357c376649a942bf0d7410915e540339c3fa42d5a498211b02e0b09493e68fac7a0d833" + }, + { + "alg" : "SHA3-384", + "content" : "b30a6ea50e454373bd74779d983fc941bb1775368ea67ff0464edbdf0dd3d1c137760bee64a620bd51daf5b65281f15e" + }, + { + "alg" : "SHA3-256", + "content" : "291404410acd2cfbcc804bd91a9777276f622fb3b82788298254c0bf1856b49f" + }, + { + "alg" : "SHA3-512", + "content" : "8101ef2cc88af43b2bfc6126547de4e4a4cc29bf49bffd83aa9d299cab9e9cdb6a5246d46c00119dd88ca02dbf7959c3076dbd32d23e8e1366144ccbbda13316" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar" + }, + { + "group" : "com.fasterxml.jackson.datatype", + "name" : "jackson-datatype-jdk8", + "version" : "2.15.3", + "description" : "Add-on module for Jackson (http://jackson.codehaus.org) to support JDK 8 data types.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "3b6579ff944e128c4eccb34e76ff67e0" + }, + { + "alg" : "SHA-1", + "content" : "80158cb020c7bd4e4ba94d8d752a65729dc943b2" + }, + { + "alg" : "SHA-256", + "content" : "29995d3677f72dde74bf32bbf268b96beb952492b742d93f4c70af6c44b2156e" + }, + { + "alg" : "SHA-512", + "content" : "1b13d4f0a955af18a2c68ca45deca79c38d7f9f065d7053bddf2a3dc2fafe729b3355676f7442012451e363aa0da0cd8a0b7a44ded7057cf513df98a475cbbf6" + }, + { + "alg" : "SHA-384", + "content" : "9a29961097a15d3aeabc1ab870699dce827511df9902fc66fe9f836d294c8cea68617498d52fe7dbe920bb5c745f2789" + }, + { + "alg" : "SHA3-384", + "content" : "55570097f9979197eafda91156db909f25dd1b37387656893564060a673dcbc6d85c1f5dc6fd5c8b379b48a4974e6757" + }, + { + "alg" : "SHA3-256", + "content" : "362c3a494e16016f7adc3f512ebe8c8f8da4dbdfc1ca285d05ac085a9198258f" + }, + { + "alg" : "SHA3-512", + "content" : "1aebbe19a11236b7dbf85fd4c457e1a9b5a60fad9c818cc9fd462d7eb489dd5d3a378b4c7c42c6e3777e0b70263968c964cf1aaf8247fc97ec445481af2418a8" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.15.3?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.15.3?type=jar" + }, + { + "group" : "org.apiguardian", + "name" : "apiguardian-api", + "version" : "1.1.2", + "description" : "@API Guardian", + "hashes" : [ + { + "alg" : "MD5", + "content" : "8c7de3f82037fa4a2e8be2a2f13092af" + }, + { + "alg" : "SHA-1", + "content" : "a231e0d844d2721b0fa1b238006d15c6ded6842a" + }, + { + "alg" : "SHA-256", + "content" : "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38" + }, + { + "alg" : "SHA-512", + "content" : "d7ccd0e7019f1a997de39d66dc0ad4efe150428fdd7f4c743c93884f1602a3e90135ad34baea96d5b6d925ad6c0c8487c8e78304f0a089a12383d4a62e2c9a61" + }, + { + "alg" : "SHA-384", + "content" : "5ae11cfedcee7da43a506a67946ddc8a7a2622284a924ba78f74541e9a22db6868a15f5d84edb91a541e38afded734ea" + }, + { + "alg" : "SHA3-384", + "content" : "c146116b3dfd969200b2ce52d96b92dd02d6f5a45a86e7e85edf35600ddbc2f3c6e8a1ad7e2db4dcd2c398c09fad0927" + }, + { + "alg" : "SHA3-256", + "content" : "b4b436d7f615fc0b820204e69f83c517d1c1ccc5f6b99e459209ede4482268de" + }, + { + "alg" : "SHA3-512", + "content" : "7b95b7ac68a6891b8901b5507acd2c24a0c1e20effa63cd513764f513eab4eb55f8de5178edbe0a400c11f3a18d3f56243569d6d663100f06dd98288504c09c5" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/apiguardian-team/apiguardian" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar" + }, + { + "group" : "jakarta.annotation", + "name" : "jakarta.annotation-api", + "version" : "2.1.1", + "description" : "Jakarta Annotations API", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5dac2f68e8288d0add4dc92cb161711d" + }, + { + "alg" : "SHA-1", + "content" : "48b9bda22b091b1f48b13af03fe36db3be6e1ae3" + }, + { + "alg" : "SHA-256", + "content" : "5f65fdaf424eee2b55e1d882ba9bb376be93fb09b37b808be6e22e8851c909fe" + }, + { + "alg" : "SHA-512", + "content" : "eabe8b855b735663684052ec4cc357cc737936fa57cebf144eb09f70b3b6c600db7fa6f1c93a4f36c5994b1b37dad2dfcec87a41448872e69552accfd7f52af6" + }, + { + "alg" : "SHA-384", + "content" : "798597a6b80b423844d70609c54b00d725a357031888da7e5c3efd3914d1770be69aa7135de13ddb89a4420a5550e35b" + }, + { + "alg" : "SHA3-384", + "content" : "9629b8ca82f61674f5573723bbb3c137060e1442062eb52fa9c90fc8f57ea7d836eb2fb765d160ec8bf300bcb6b820be" + }, + { + "alg" : "SHA3-256", + "content" : "f71ffc2a2c2bd1a00dfc00c4be67dbe5f374078bd50d5b24c0b29fbcc6634ecb" + }, + { + "alg" : "SHA3-512", + "content" : "aa4e29025a55878db6edb0d984bd3a0633f3af03fa69e1d26c97c87c6d29339714003c96e29ff0a977132ce9c2729d0e27e36e9e245a7488266138239bdba15e" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + }, + { + "license" : { + "id" : "GPL-2.0-with-classpath-exception" + } + } + ], + "purl" : "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://github.com/eclipse-ee4j/common-annotations-api/issues" + }, + { + "type" : "mailing-list", + "url" : "https://dev.eclipse.org/mhonarc/lists/ca-dev" + }, + { + "type" : "vcs", + "url" : "https://github.com/eclipse-ee4j/common-annotations-api" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar" + }, + { + "group" : "com.fasterxml.jackson.core", + "name" : "jackson-annotations", + "version" : "2.15.3", + "description" : "Core annotations used for value types, used by Jackson data binding package.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "f478f693731e4a2f0f0d3c7bba119b32" + }, + { + "alg" : "SHA-1", + "content" : "79baf4e605eb3bbb60b1c475d44a7aecceea1d60" + }, + { + "alg" : "SHA-256", + "content" : "aae865c3d88256d61b11523cb1e88bd48d5b9ad5855fa1fc859504fd2204708a" + }, + { + "alg" : "SHA-512", + "content" : "c496afd736fa8acbf8126887e2ff375f162212f451326451fbb4b9194231d814e25bccacbaead9db98beec454f6b8d9ed706c5c88e2145bf7e1a37e13fd81af0" + }, + { + "alg" : "SHA-384", + "content" : "13b4d153cc113a69008147974d8887f868f2f3f0a551ef0bacaccf0add17a3168465a94a471e075913f9c6649980a3cb" + }, + { + "alg" : "SHA3-384", + "content" : "dcf8ed73f748eb32e1ab25eba3c294344cc0ddb2cc7bb4376814f1866df42c3093f1336291ce9ed9e1c8730663e0017c" + }, + { + "alg" : "SHA3-256", + "content" : "59f42bc85ee3a8a5b422085b0462aed2a770cf52d7a3660f2cd6dd257ec6e694" + }, + { + "alg" : "SHA3-512", + "content" : "1d1a6fd0e6851d419e79f82170f4060981c233ec8dc61656b84ce7988e9b71bbeecd7364cdadac066ddaf0b3de4dc8aa5acc411ebd1641f549a3af5ba214667b" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/FasterXML/jackson-annotations" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-jcl", + "version" : "6.1.2", + "description" : "Spring Commons Logging Bridge", + "hashes" : [ + { + "alg" : "MD5", + "content" : "1638acc7030a001c37f803185dbd6eaf" + }, + { + "alg" : "SHA-1", + "content" : "285eb725861c9eacf2a3e4965d4e897932e335ea" + }, + { + "alg" : "SHA-256", + "content" : "eb9ebadb1581f0fe598216f7cf032a3b44a84c96de06ffa8d6f41bcc47305134" + }, + { + "alg" : "SHA-512", + "content" : "2e80d7485b7ad4de6cc372d86ed73db9808be6a5a33e3c9fabccc7915fe57b73011bed75b4567c44456fedad5ae2186658a7f5cc331b4aad64e2a7cc78acdcfa" + }, + { + "alg" : "SHA-384", + "content" : "a6a6422a6c2654eff951af0d6dfb6e93501bdcb4e38ec353d515ca8de919a34b9e1fe37c562106f3f33f844cf071e010" + }, + { + "alg" : "SHA3-384", + "content" : "71098eb263af3ab42d93b8e7a96ceb90fb2069f2ecca85754e702b82f9876255abf5e3f9b48beb4a200f2d9e13599794" + }, + { + "alg" : "SHA3-256", + "content" : "7f49ddd5db9841bb2d7ca8cb5ce52fa1e8982c7c37bc0c6e987eca8f5fc70d38" + }, + { + "alg" : "SHA3-512", + "content" : "4a417d058ecd3619a9716c5d47ecc506f4cb9c3684ee589c443c7b7996b630949932295186135cb3ce5fb0154c29436de4b6c1dbf7f135563449050973510200" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-jcl@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-jcl@6.1.2?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-webmvc", + "version" : "6.1.2", + "description" : "Spring Web MVC", + "hashes" : [ + { + "alg" : "MD5", + "content" : "0fcf00ac160e0d42ad9cd242c796e47a" + }, + { + "alg" : "SHA-1", + "content" : "906ee995372076e22ef9666d8628845c75bf5c42" + }, + { + "alg" : "SHA-256", + "content" : "de42748c3c94c06131c3fe97d81f5c685e4492b9e986baa88af768bb12ea7738" + }, + { + "alg" : "SHA-512", + "content" : "8e7ad7afa2a605d8dbb6cb36c11caf0e626a5ca5849c06f0b35524e5ad6a13eec1ddff8625e1cc278b3082555a940ec3865657828458ab8d60d1c99d513aba0f" + }, + { + "alg" : "SHA-384", + "content" : "5ec328ff12f857baf85ce6f44c849f8818658aaabb4e4d0940ea6b5ad2b009ce3c7717b6b02843f641f8125d0cec4291" + }, + { + "alg" : "SHA3-384", + "content" : "75605b286d839df688bbfb9594dbb83d1eb22f2cae52a6f4b35d485e91ab94a55e94158086684ef3b059f1346af6dc85" + }, + { + "alg" : "SHA3-256", + "content" : "2e67bcc31eede462f5105a09dbf5b40a3e0ccc52d637c6e2720b43412da01525" + }, + { + "alg" : "SHA3-512", + "content" : "d7c5330069c3c0f5eda1417a52384a4b5adc4451c405315a992ed147f26466a19487ffc5e39b90a1ec4cb0df3f804a4d26203f9aaf4e74cf906d1e811abfbf3b" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-webmvc@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-webmvc@6.1.2?type=jar" + }, + { + "group" : "org.apache.tomcat.embed", + "name" : "tomcat-embed-websocket", + "version" : "10.1.17", + "description" : "Core Tomcat implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "cfc1778713fba9b5bc33d3db64071dff" + }, + { + "alg" : "SHA-1", + "content" : "9ee2f34b51144b75878c9b42768e17de8fbdc74b" + }, + { + "alg" : "SHA-256", + "content" : "00b16e507bea58c6e8a7cb64f129cd2ffd62da092a67a693a8a6af1efdc7dd6d" + }, + { + "alg" : "SHA-512", + "content" : "72da073d4ec4f7473c9a91b4d11607d02a3d18ca8af10348f9130a280f898814625a5865cb44244e6be6d6ab915099805bf06a60f80fd9b8ff2c47840d5266e9" + }, + { + "alg" : "SHA-384", + "content" : "3f4c1d108ca60a7a658839b8ac45eba94354ad20e641d36d2ecf777bac252d371df1e8806a5460ccaf9da222f72a4a9c" + }, + { + "alg" : "SHA3-384", + "content" : "2d0703de58338d38fbae7f4a38390a766d66e3875e3a6a7f2620ae478c838c8f306a39cdac8652890e1116a3859e56e1" + }, + { + "alg" : "SHA3-256", + "content" : "e594abbc4cb6dc0896c08a89cb3fa376980587d5995bace2b3c0798d99c1e454" + }, + { + "alg" : "SHA3-512", + "content" : "3a35964398627fc8bcd323dd9fb6d4e51ea183b704074320822906c074aeb50a0f8732e42b98bdad9c5f0aa4eb421da96dde7e97f094ccdbcb70f668c6d4ff6e" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.17?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.17?type=jar" + }, + { + "group" : "net.bytebuddy", + "name" : "byte-buddy", + "version" : "1.14.10", + "description" : "Byte Buddy is a Java library for creating Java classes at run time. This artifact is a build of Byte Buddy with all ASM dependencies repackaged into its own name space.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "4e5bd83559bf8533b51f92dcd911d16c" + }, + { + "alg" : "SHA-1", + "content" : "8117daf4a612122eb4f517f66adff778cb8b4737" + }, + { + "alg" : "SHA-256", + "content" : "30e6e0446437a67db37e2b7f7d33f50787ddfd970359319dfd05469daa2dcbce" + }, + { + "alg" : "SHA-512", + "content" : "583512f3c47513cf17735aad4e600be44c97e9978c9f6a45227de8a160a879960b1fe01672751e7583176935e0db5477aba581bf68ef5c94f52436a0683a306e" + }, + { + "alg" : "SHA-384", + "content" : "efcce5a139f498de410e182a52e5b2465823a2ebf845001c9a733d87418118342c3854d00a0fae7945ae8dcb1916ba90" + }, + { + "alg" : "SHA3-384", + "content" : "cace3217b1c2c77a4bc194ecc602a28886d9e448efa26b1985e9fd09d90c92bc2e1b50ed70475106ddf266f8c2d14160" + }, + { + "alg" : "SHA3-256", + "content" : "71647273afb1561b70d2cfa519f707a98711f9ae5b891249ae5803c00c25a788" + }, + { + "alg" : "SHA3-512", + "content" : "4aba6f5dcac177c8f8aed902307c62916c32be61841adcf12b9c9885de2de9795a965c0b939729ed67ee7d49b0fbfaf0dfd922be1bf1cdbfbe7b1f09e083831b" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-test-autoconfigure", + "version" : "3.2.1", + "description" : "Spring Boot Test AutoConfigure", + "hashes" : [ + { + "alg" : "MD5", + "content" : "d6f93aa42df4cb27a58835750597d835" + }, + { + "alg" : "SHA-1", + "content" : "bfc34c523b3ab295fb01f46373e903f9729cdd43" + }, + { + "alg" : "SHA-256", + "content" : "86c51c743babfc591be09af7fedcd778410706e567e9ed27218448ccd2297ef4" + }, + { + "alg" : "SHA-512", + "content" : "701b6ee27c87081e4a65ba76fe721f74e917a655575b19b9205b314f4a561889564e09ceadaa880aaf30f70cd8b48dc70fc5e32f511204b1ea031a12349fd9be" + }, + { + "alg" : "SHA-384", + "content" : "74d4cf202399e946789a5572007aa4fbf1daf26cfac27f83a3d8550711f99700083029b1f900037b8f263543ac9824a1" + }, + { + "alg" : "SHA3-384", + "content" : "ac0b64ec94b558b4f806c09f68247eff80bcc8e33b97f5d09f5517a2339187e4b11c8e2287400a173cb128e3fdb4ab06" + }, + { + "alg" : "SHA3-256", + "content" : "5ca85cd0c052076d625c262cf445e4e8fb255b13323ba4ab08cbfcf32ec236b3" + }, + { + "alg" : "SHA3-512", + "content" : "04ce88c724852938057c723a7ec637af2f8e601879a592a6fe135eaa26940f8fd9d9ac8f6917e761cb0ff31547bb849ff88a66e1f6e93c1032a4009fe1fdef1d" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.2.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-json", + "version" : "3.2.1", + "description" : "Starter for reading and writing json", + "hashes" : [ + { + "alg" : "MD5", + "content" : "bea54cf408b022894c0b1b013c58c0a9" + }, + { + "alg" : "SHA-1", + "content" : "ecda50de20ab6d3c49ea30df4c1982048f5d31ac" + }, + { + "alg" : "SHA-256", + "content" : "572f1a4171dff33b5a9260bbd704473442adf24f890386abe33ecc18c047836a" + }, + { + "alg" : "SHA-512", + "content" : "c611e0d07093d99dbcded7a00e7c00355a7c13c24a69d33105ca88ec63cc68ba76339b5a96b84f2b666bb883849980776e1e24ee2df9c7dd07b2dde0992289b5" + }, + { + "alg" : "SHA-384", + "content" : "ed40ffb527cf8442dbe3eb7b542970317e4827ed00196387d78f123490a77b08b3bc2fd5f53b83f6bee1d4eed29215bf" + }, + { + "alg" : "SHA3-384", + "content" : "26d5852f479f1c72f501569a8ea0c0e4c93f9049676921dca94b467e68f221214e4485c41647e6a92005e5090a6a7c80" + }, + { + "alg" : "SHA3-256", + "content" : "dc69eefb2f1441bbec58c219ccedd895b863b1e1d25cc3805936f0c9b072f2e6" + }, + { + "alg" : "SHA3-512", + "content" : "bf6fce60937e78550fb3d411c19aad2200d8129138fade809e9d0abc307c7f06b54732f1e94fa86ebb82d4da0293f7bce43345416b3fdae1b3c2edbac6706310" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-json@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-json@3.2.1?type=jar" + }, + { + "group" : "com.fasterxml.jackson.datatype", + "name" : "jackson-datatype-jsr310", + "version" : "2.15.3", + "description" : "Add-on module to support JSR-310 (Java 8 Date & Time API) data types.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "acd8ae6da000eb831a69b4acdc182b7f" + }, + { + "alg" : "SHA-1", + "content" : "4a20a0e104931bfa72f24ef358c2eb63f1ef2aaf" + }, + { + "alg" : "SHA-256", + "content" : "bea1d78009ebc4e5d54918a3f7aec5da9fbd09f662c191a217ffcf37e8527c5e" + }, + { + "alg" : "SHA-512", + "content" : "1c5bde6c91a2a89f3c1f231f4e17c435063d9012babbfcba509a3b25363b1fd99f0dcd4234f1e00559e43d3dc8e6c71834282c72f2ebf15484ae900754c5d757" + }, + { + "alg" : "SHA-384", + "content" : "cc72f54d89bc0f7ffae9af36dfba38e5a61ac83db2f0d8de3c74e405a0bfd77b6d463217ece19c64eeb16291d80a69f5" + }, + { + "alg" : "SHA3-384", + "content" : "096944bac7583e5c97e8afcfbc928ca4a87a7d3e5eb74cc77394a19ca8bc6f26185da7fdf5d6bd2179582bf51940edc5" + }, + { + "alg" : "SHA3-256", + "content" : "0301cf719fd327643b3228b91c36688aaea3fccf3487c3e09bae3de636340dc7" + }, + { + "alg" : "SHA3-512", + "content" : "b9a4a8c9785e8ec2786690bfede18c76e08d81fc9c77bb2dad88e1a034f97f7d20020531ac1cb9b0b6e61645b08ea441aba35fc0732edc2fc1dc4b36d6f1695c" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar" + }, + { + "group" : "org.hdrhistogram", + "name" : "HdrHistogram", + "version" : "2.1.12", + "description" : "HdrHistogram supports the recording and analyzing sampled data value counts across a configurable integer value range with configurable value precision within the range. Value precision is expressed as the number of significant digits in the value recording, and provides control over value quantization behavior across the value range and the subsequent value resolution at any given level.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "4b1acf3448b750cb485da7e37384fcd8" + }, + { + "alg" : "SHA-1", + "content" : "6eb7552156e0d517ae80cc2247be1427c8d90452" + }, + { + "alg" : "SHA-256", + "content" : "9b47fbae444feaac4b7e04f0ea294569e4bc282bc69d8c2ce2ac3f23577281e2" + }, + { + "alg" : "SHA-512", + "content" : "b03b7270eb7962c88324858f94313adb3a53876f1e11568a78a5b7e00a9419e4d7ab8774747427bff6974b971b6dfc47a127fca11cb30eaf7d83b716e09b1a0d" + }, + { + "alg" : "SHA-384", + "content" : "06977d680dafd803d32441994474e598384a584411a67c95ab4a64698c9e4cbd613e0119b54685cea275b507a0a6f362" + }, + { + "alg" : "SHA3-384", + "content" : "b5ccb4d39bf7cc8ccc33f0f8fcbab0a63c99a94feda840b5d80fc3ae061127f1475cfb869b060933783a1f2eafb103a1" + }, + { + "alg" : "SHA3-256", + "content" : "ef2113f27862af1d24d90c2028fc566902720248468d3c0f2f1807cc86918882" + }, + { + "alg" : "SHA3-512", + "content" : "4fca2f75bdfd3f2ac40dc227ae2ef0272142802b1546d4f5edf9155eaeed84eff07b0c3a978291a1df096ec94724b0defb045365e6a51acfdd5da68d72c5a8eb" + } + ], + "licenses" : [ + { + "license" : { + "id" : "CC0-1.0" + } + }, + { + "license" : { + "id" : "BSD-2-Clause", + "url" : "https://opensource.org/licenses/BSD-2-Clause" + } + } + ], + "purl" : "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://github.com/HdrHistogram/HdrHistogram/issues" + }, + { + "type" : "vcs", + "url" : "scm:git:git://github.com/HdrHistogram/HdrHistogram.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12?type=jar" + }, + { + "group" : "io.micrometer", + "name" : "micrometer-commons", + "version" : "1.12.1", + "description" : "Module containing common code", + "hashes" : [ + { + "alg" : "MD5", + "content" : "2518ae277e56aea5e37e3fc2f578dfa4" + }, + { + "alg" : "SHA-1", + "content" : "abcc6b294e60582afdfae6c559c94ad1d412ce2d" + }, + { + "alg" : "SHA-256", + "content" : "295785b04cd4de7711bb16730da5e9829bac55a8879d52120625dac6c89904ed" + }, + { + "alg" : "SHA-512", + "content" : "25d65699a25fe3b90de17a0539233fdad37df864f6d493475976e9a513bd7767520a882cbf6bbd98714a1fe94acdb77a160cd68f549475d2b93624ffe8672a00" + }, + { + "alg" : "SHA-384", + "content" : "8523ae45ce6dd4a068cce108cd31da24629839d3d293fca92353cf45db9eae88107744c9e66b82ed14abb96782c562da" + }, + { + "alg" : "SHA3-384", + "content" : "9af1fc3aad2d0131c337b843c38b05510d31e7931a48841a4bdb618257f185286ed393f8a4418ae4c5f91da7f9c76cbf" + }, + { + "alg" : "SHA3-256", + "content" : "d5dbeadc5f629430202c81a6736dff2efbfbf3ea2c09844b1194f316772a93f7" + }, + { + "alg" : "SHA3-512", + "content" : "c7b1dd1727000936bf51c02f9bf9b262a412e2b815531df4a9f7aad675ef0f728d4492327a404b37b1ef36d41a240b83dbfeea3367b3b4faa22cdc2decc5bac9" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar" + }, + { + "group" : "org.mockito", + "name" : "mockito-core", + "version" : "5.7.0", + "description" : "Mockito mock objects library core API and implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "4df8dd230071bc192161d0e54a76f6b5" + }, + { + "alg" : "SHA-1", + "content" : "a1c258331ab91d66863c983aff7136357e9de056" + }, + { + "alg" : "SHA-256", + "content" : "dbad5e746654910a11a59ecb4d01e38461f3e5d16161689dc2588d5554432521" + }, + { + "alg" : "SHA-512", + "content" : "5a2f00df2b1b2dbca06686f88806b86990f1eea6f7c25281c0e7ec7cf7904a0a9227477279b11630d80f8e88d6b6e9dbdb40ad094a4077cc6a44cd2072d12662" + }, + { + "alg" : "SHA-384", + "content" : "3f2caa05fe4a5d5b385654ce60d0655724200fdd333652459b86848c3b895a9ad0b0daca8a014851d6b5c744cd0e9372" + }, + { + "alg" : "SHA3-384", + "content" : "06ba4583220a4aaa47d79ccab11783d48900d8850a346e4a1efc61c057630fcf0bb9c95cec74833ab5e6ee08e55625ec" + }, + { + "alg" : "SHA3-256", + "content" : "f1f9899edf629fffaf8b4483ac04430945996393f4fdcedc38eba22a9a5c715d" + }, + { + "alg" : "SHA3-512", + "content" : "d6f479d52534b382088012e3d1a83fa267dfb046322a72e84438d21973165617d1d710bb42f1cb2d2d3d7f891969320232031be33f4abb2ea1526217e16e8c63" + } + ], + "licenses" : [ + { + "license" : { + "id" : "MIT", + "url" : "https://opensource.org/licenses/MIT" + } + } + ], + "purl" : "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "build-system", + "url" : "https://github.com/mockito/mockito/actions" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/mockito/mockito/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/mockito/mockito.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-actuator-autoconfigure", + "version" : "3.2.1", + "description" : "Spring Boot Actuator AutoConfigure", + "hashes" : [ + { + "alg" : "MD5", + "content" : "3afea56b25f872cee2c929c761b0790d" + }, + { + "alg" : "SHA-1", + "content" : "0fe81034352a15731322fba326447ba70bfa3962" + }, + { + "alg" : "SHA-256", + "content" : "3850d85c0f6074fe9286dece9b44f8bded5e194e9b816860735e0fc728173d65" + }, + { + "alg" : "SHA-512", + "content" : "7197158ef14a580edc836ab7af10a9f5f567ba60e21267b624fc4143debd2638c7b8bd8e2e5973fdd5c5d512be73df96500fb0a4273f20a21b42161e9f7add75" + }, + { + "alg" : "SHA-384", + "content" : "4a35eb1f124d8d7812d32f87b16a24dd56d4cb43278ce66f216f4a4af34db357e7481fc1b26de9bde7c2dd6847687721" + }, + { + "alg" : "SHA3-384", + "content" : "8369a8b49cae80b92abbfcc0218d55b9cecd86778735c66b9b0cc6fbc7251784725249392e716c314e3ec08c995557bb" + }, + { + "alg" : "SHA3-256", + "content" : "ee742160e4951e1f6145d575f6c6ebb908a46f38a8b3b81b7d61aac7c111a87f" + }, + { + "alg" : "SHA3-512", + "content" : "dcb1b214577203c9b3e2e5dcb3aaef8e46aec5f75a40a606f42e230c6e1af39c37250d58de6bf694c5a62d70fb1a6dcba436d696f71d7aa1a52b9f4dea5aa9a9" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.2.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-tomcat", + "version" : "3.2.1", + "description" : "Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web", + "hashes" : [ + { + "alg" : "MD5", + "content" : "db4df0f653e84bfd545894c4567b19ff" + }, + { + "alg" : "SHA-1", + "content" : "d8efc48034015522958cb3fea5831b4cbcd4fcfb" + }, + { + "alg" : "SHA-256", + "content" : "bf93da73a8fb4caf9fa68e4f3b97adcc9dbb8c79220a828b3d70ecf12d410117" + }, + { + "alg" : "SHA-512", + "content" : "d2bce5bb0271525766283e17160513de530c20e0452cecc3c9d5be3890986cc071c1423a3c11c54a36d2f83bd3a238b0fcbcc6218976a5633f0753a313418f6f" + }, + { + "alg" : "SHA-384", + "content" : "1f9ae7504b1345595377a4d35163315824dcf25f29ac9d522385e6e1672b813719655989708eb03b419e808f1f102be9" + }, + { + "alg" : "SHA3-384", + "content" : "9d890c3314b5ec30f39de30bf70471aef5f19e64d6d2f60b6fe66b3c57978bbda0a981cf92e42f18f27b72ed2ddb3574" + }, + { + "alg" : "SHA3-256", + "content" : "43d38219fbe556c2bac8670fa0aa4f89e2ac273fda77d8bceac8d9d34d7b27c2" + }, + { + "alg" : "SHA3-512", + "content" : "6a4e9a2ff89293c60c8a05cb79a65695dbe9823978be93f1b309d702338f87f108aabeaeafe8ff0ebf08bcd5483efbbb4a85c566e1357acd1d2fab565c910a80" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-tomcat@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-tomcat@3.2.1?type=jar" + }, + { + "group" : "org.apache.logging.log4j", + "name" : "log4j-to-slf4j", + "version" : "2.21.1", + "description" : "The Apache Log4j binding between Log4j 2 API and SLF4J.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "00b957af4a40bea6a7bf61400b6ccf63" + }, + { + "alg" : "SHA-1", + "content" : "d77b2ba81711ed596cd797cc2b5b5bd7409d841c" + }, + { + "alg" : "SHA-256", + "content" : "de143c565ba78b0f2c0be58f132c7aec75e6e1a10845ebda5a4f17c2a35d9990" + }, + { + "alg" : "SHA-512", + "content" : "8a7a682dc5ae6a123c8de6002f1470ad2682795c65b47b06397d9ad9a31729e588c406013bfa989f9c2a51750c353cd7a147bc036f2d66b0f8f0b3f13798a637" + }, + { + "alg" : "SHA-384", + "content" : "8f3e4f1eea069f47b2c6111f1233448ea9ccc723b7c8a8bd308b7317a6ec1f47008d2952c1cb274152a38d3e21da750b" + }, + { + "alg" : "SHA3-384", + "content" : "822f93c3bba450b89a7f64b4d81aab48a7f5c2f693b53a4dcc83eba3a8300ff90c9e7727223f3491c782c80bee9dc707" + }, + { + "alg" : "SHA3-256", + "content" : "1f3f3aace32b45e9a6271c7b4ac76ddf86eb4f32e28e147a3e054dc8c836def1" + }, + { + "alg" : "SHA3-512", + "content" : "bb61c16d22aeed2d6b18972f68a6c4670fb8a07eeb79407748a7d499bc64e8ad8eb9774d372d9286227665686fe90878f2ef7e7f8595b74cd448d0f847aec02e" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0", + "url" : "https://www.apache.org/licenses/LICENSE-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.21.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.21.1?type=jar" + }, + { + "group" : "jakarta.xml.bind", + "name" : "jakarta.xml.bind-api", + "version" : "4.0.1", + "hashes" : [ + { + "alg" : "MD5", + "content" : "e62084f1afb23eccde6645bf3a9eb06f" + }, + { + "alg" : "SHA-1", + "content" : "ca2330866cbc624c7e5ce982e121db1125d23e15" + }, + { + "alg" : "SHA-256", + "content" : "287f3b6d0600082e0b60265d7de32be403ee7d7269369c9718d9424305b89d95" + }, + { + "alg" : "SHA-512", + "content" : "dcc70e8301a7f274bbb6d6b3fe84ad8c9e5beda318699c05aeac0c42b9e1e210fc6953911be2cb1a2ef49ac5159c331608365b1b83a14a8e86f89f630830dd28" + }, + { + "alg" : "SHA-384", + "content" : "16ff377d0cfd7d8f23f45417e1e0df72de7f77780832ae78a1d2c51d77c4b2f8d270bd9ce4b73d07b70b060a9c39c56e" + }, + { + "alg" : "SHA3-384", + "content" : "773fd2d1e1a647bea7a5365490483fd56e7a49d9b731298d3202b4f93602c9a1a7add0eee868bc5a7ac961da7dda8c8e" + }, + { + "alg" : "SHA3-256", + "content" : "26214bba5cee45014859be8018dc631c14146e0a5959bb88e05d98472c88de8b" + }, + { + "alg" : "SHA3-512", + "content" : "32bdc043b7d616d73bbc26e0b36308126b15658cd032a354770760c5b5656429a4240dd3ddcea835556e813b6ae8618307ebeb96e2e46ba8ab16f6a485fa4d32" + } + ], + "licenses" : [ + { + "license" : { + "id" : "BSD-3-Clause" + } + } + ], + "purl" : "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.1?type=jar" + }, + { + "group" : "org.yaml", + "name" : "snakeyaml", + "version" : "2.2", + "description" : "YAML 1.1 parser and emitter for Java", + "hashes" : [ + { + "alg" : "MD5", + "content" : "d78aacf5f2de5b52f1a327470efd1ad7" + }, + { + "alg" : "SHA-1", + "content" : "3af797a25458550a16bf89acc8e4ab2b7f2bfce0" + }, + { + "alg" : "SHA-256", + "content" : "1467931448a0817696ae2805b7b8b20bfb082652bf9c4efaed528930dc49389b" + }, + { + "alg" : "SHA-512", + "content" : "11547e75cc80bee26f532e2598bc6e4ffa802941496dc0d8ce017f1b15e01ebbb80e91ed17d1047916e32bf2fc58da532bc71a1dfe93afccc277a296d86634ba" + }, + { + "alg" : "SHA-384", + "content" : "dae0cb1a7ab9ccc75413f46f18ae160e12e91dfef0c17a07ea547a365e9fb422c071aa01579f2a320f15ce6ee4c29038" + }, + { + "alg" : "SHA3-384", + "content" : "654b418f330fa02f1111a20c27395ec5c7f463907ae44f60057c94da04f81e815cf1c3959f005026381ef79030049694" + }, + { + "alg" : "SHA3-256", + "content" : "2c4deb8d79876b80b210ef72dc5de2b19607e50fbe3abf09a4324576ca0881fc" + }, + { + "alg" : "SHA3-512", + "content" : "0d9be5610b2bcb6bb7562ee8bcc0d68f81d3771958ce9299c5e57e8ec952c96906d711587b7f72936328c72fb41687b4f908c4de3070b78cc1f3e257cf4b715e" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.yaml/snakeyaml@2.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://bitbucket.org/snakeyaml/snakeyaml/issues" + }, + { + "type" : "vcs", + "url" : "https://bitbucket.org/snakeyaml/snakeyaml/src" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.yaml/snakeyaml@2.2?type=jar" + }, + { + "group" : "org.junit.platform", + "name" : "junit-platform-commons", + "version" : "1.10.1", + "description" : "Module \"junit-platform-commons\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "cd430f3f7345c0888f8408ce8795c751" + }, + { + "alg" : "SHA-1", + "content" : "2bfcd4a4e38b10c671b6916d7e543c20afe25579" + }, + { + "alg" : "SHA-256", + "content" : "7d9855ee3f3f71f015eb1479559bf923783243c24fbfbd8b29bed8e8099b5672" + }, + { + "alg" : "SHA-512", + "content" : "4aa83350e7a6df21feb9ba8756bb4a68986f33f8c6e384720d1daa448444016c0def1781729788e3e884664abd6703b1e3c0ec6b79893a9d5645c3a4809c0ad2" + }, + { + "alg" : "SHA-384", + "content" : "d264f2c8ceaff384b0f22ee77890195ed3d918b01f338e35fc2ee12f82df15e59533918509f535883b4f4befed28595e" + }, + { + "alg" : "SHA3-384", + "content" : "d1fa76d6b2567e831b37ff7843df6d7d65028d4e53c570c6f580cbbf13269d2aa2afedfedfe5a3f2cf92d7de6d3c89b2" + }, + { + "alg" : "SHA3-256", + "content" : "eef0f968f2d2fc31f8b4a4ed43bafeb46977de1ac3d59477ab6e2b014f97e070" + }, + { + "alg" : "SHA3-512", + "content" : "93340cc2c378c830c755b25006bc4f73ec77ad10661f05625b23efa0854d456da8e62bdbe7e7edf3418dda864e6e0d7a6b9d34cea23d525b8991258f3d75fc9c" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.platform/junit-platform-commons@1.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.platform/junit-platform-commons@1.10.1?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-web", + "version" : "6.1.2", + "description" : "Spring Web", + "hashes" : [ + { + "alg" : "MD5", + "content" : "a39761bc7a706c70f6ca3ab805a97b34" + }, + { + "alg" : "SHA-1", + "content" : "0f26b98778376cc39afb04fbb6fdd7543bef89f2" + }, + { + "alg" : "SHA-256", + "content" : "3f2012a24c6213f155b6bc69aa3ecafe2a373c1e92a26dbecc62ff575c3a1fb3" + }, + { + "alg" : "SHA-512", + "content" : "f07f054feaf53c2a97b82150882281035824cf0b815f317a22ba1954afa721bc5d57cb07faa19bad99fc235373b62edd7013f7ac2cd0a3d0db91faf49f216741" + }, + { + "alg" : "SHA-384", + "content" : "57418cf2a9b3256201c0874e7721966b09929030c64f5e5a85007bd645294dfbf1a14d4632a5aa5fcf70af5bf733d542" + }, + { + "alg" : "SHA3-384", + "content" : "83daa608abc0124ec237f65231d5f1dd1a5d751e459d3ea255a3d12a56e92ac83037fb72c5793f497fbecb9e389eb299" + }, + { + "alg" : "SHA3-256", + "content" : "1a17acdfa8920b1849a16e4260bb4b960f60da07732148a5281cfcba21d1e4a8" + }, + { + "alg" : "SHA3-512", + "content" : "3e5e020cb1068250eb0e58e9bc0368c44db96d59022047ecffe286a51b0896e4320d9696f2f9136b4c0aed547d8dd1af1bbc2b4b053aa994246bb43bd7397f05" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-web@6.1.2?type=jar" + }, + { + "group" : "org.objenesis", + "name" : "objenesis", + "version" : "3.3", + "description" : "A library for instantiating Java objects", + "hashes" : [ + { + "alg" : "MD5", + "content" : "ab0e0b2ab81affdd7f38bcc60fd85571" + }, + { + "alg" : "SHA-1", + "content" : "1049c09f1de4331e8193e579448d0916d75b7631" + }, + { + "alg" : "SHA-256", + "content" : "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb" + }, + { + "alg" : "SHA-512", + "content" : "1fa990d15bd179f07ffbc460d580a6fd0562e45dee8bd4a9405917536b78f45c0d6f644b67f85d781c758aa56eff90aef23eedcc9bd7f5ff887a67b716083e61" + }, + { + "alg" : "SHA-384", + "content" : "2f6878f91a12db32c244afcee619d57c3ad6ff0297f4e41c2247e737c1ccc5fcc1ce03256b479b0f9b87900410bc4502" + }, + { + "alg" : "SHA3-384", + "content" : "a3dd9f6908fe732900d50eb209988183ffcf511afb4e401ef95b75c51777709d2d10e1dc9ee386b7357c5c2cbcf8c00e" + }, + { + "alg" : "SHA3-256", + "content" : "fd2b66d174ed68cbfcda41d5cbd29db766c5676866d6b2324b446a87afab3a9f" + }, + { + "alg" : "SHA3-512", + "content" : "ef509e8bcea73bc282287205ffc7625508080be44c16948137274f189459624891dcf109118c9feff109e1aa99becf176f8db837ac4fd586201510c3ae2ea30a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.objenesis/objenesis@3.3?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.objenesis/objenesis@3.3?type=jar" + }, + { + "group" : "com.vaadin.external.google", + "name" : "android-json", + "version" : "0.0.20131108.vaadin1", + "description" : "  JSON (JavaScript Object Notation) is a lightweight data-interchange format. This is the org.json compatible Android implementation extracted from the Android SDK  ", + "hashes" : [ + { + "alg" : "MD5", + "content" : "10612241a9cc269501a7a2b8a984b949" + }, + { + "alg" : "SHA-1", + "content" : "fa26d351fe62a6a17f5cda1287c1c6110dec413f" + }, + { + "alg" : "SHA-256", + "content" : "dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79" + }, + { + "alg" : "SHA-512", + "content" : "c4a06a0a3ce7bdbee702c06944265c050a4c8d2fbd21c248936e2edfdab63acea30f2cf3568d3c21a559940d939985a8b10d30aff972a3e8cbeb392c0b02da3a" + }, + { + "alg" : "SHA-384", + "content" : "60d1044b5439cdf5eb621118cb0581365ab4f023a30998b238b87854236f03d8395d45b0262fb812335ff904cb77f25f" + }, + { + "alg" : "SHA3-384", + "content" : "b80ebdbec2127279ca402ca52e50374d3ca773376258f6aa588b442822ee7362de8cca206db71b79862bde84018cf450" + }, + { + "alg" : "SHA3-256", + "content" : "6285b1ac8ec5fd339c7232affd9c08e6daf91dfa18ef8ae7855f52281d76627e" + }, + { + "alg" : "SHA3-512", + "content" : "de7ed83f73670213b4eeacfd7b3ceb7fec7d88ac877f41aeaacf43351d04b34572f2edc9a8f623af5b3fccab3dac2cc048f5c8803c1d4dcd1ff975cd6005124d" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0", + "url" : "https://www.apache.org/licenses/LICENSE-2.0" + } + } + ], + "purl" : "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "distribution", + "url" : "http://oss.sonatype.org/content/repositories/vaadin-releases/" + }, + { + "type" : "vcs", + "url" : "http://developer.android.com/sdk/" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-logging", + "version" : "3.2.1", + "description" : "Starter for logging using Logback. Default logging starter", + "hashes" : [ + { + "alg" : "MD5", + "content" : "7ac01b9dee045285c365cf6a3d8d8451" + }, + { + "alg" : "SHA-1", + "content" : "0df8ec78dc87885298998ca3c9bd603ee7bfe5b8" + }, + { + "alg" : "SHA-256", + "content" : "0b7e411cfc44a15fc63a36cd05a73b34c3558f1b06e4f297b1919361b8a351a7" + }, + { + "alg" : "SHA-512", + "content" : "23baf0a59d56809db43101fbddb712b515012c64530362665cebe84c53bbd716218d3602024315f3250dea923138845c09d5c56dd9c7fb26a53d5e21a325e52e" + }, + { + "alg" : "SHA-384", + "content" : "f5ff55d346828eaec7b535bdd1d6096acc3819e81f6fa0a3d2396d523616e2e356d58115de8b8c49adf035216fa6ea83" + }, + { + "alg" : "SHA3-384", + "content" : "6e5bd5c09d127a2984a55bbfc296cc515e399f35ee2ca949b10639c5ef583bee58dc9eeb60f6bec1f05904f8b91b4a26" + }, + { + "alg" : "SHA3-256", + "content" : "99b21628e6efb820b4955e0e17bb54345a6974dc785b79abb7af8186a261159e" + }, + { + "alg" : "SHA3-512", + "content" : "91625907d0200fb80f025aa6ed098372955053bfb277db124d95ce2dd5049c20e9e7f2b97cffd6f247d9ae8da1bc26c004b688687056a87ccb3033d57a7c20f3" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.2.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-actuator", + "version" : "3.2.1", + "description" : "Spring Boot Actuator", + "hashes" : [ + { + "alg" : "MD5", + "content" : "d5ede97972b567fe75db1d2bbfc035d8" + }, + { + "alg" : "SHA-1", + "content" : "9089b9fff0c17eae54aabc466b78e010eac3a04f" + }, + { + "alg" : "SHA-256", + "content" : "b870c0a601dc0d6d98b33a6b59d41799285848de267f7cfb466a6f167f30c4d2" + }, + { + "alg" : "SHA-512", + "content" : "9577f4ba268b688ad100d4038f6dba97139a29b82127f6a581b948f0ee08fc8159f51fa5f7deb200e5a61559fd321559d2255af75c3e28cf293e815b8b1bb8ac" + }, + { + "alg" : "SHA-384", + "content" : "96adde3cd5a4f729a6d382566800e62e89c93d1c3b9120ffefcd9a666d755fc5d6dc3dd12577f927bcaf03b7f1b0922b" + }, + { + "alg" : "SHA3-384", + "content" : "c3f71bfae2d560ec46f76e833aee6964b5ad57639cb4ded937cd6d1e39b213a4c255d9b83ba59882d22dd31a4ef7b5f5" + }, + { + "alg" : "SHA3-256", + "content" : "d7a251040e99b14a5d926f86bdcb1fcf505518d31cb421e6aaf32d59d8f7f2eb" + }, + { + "alg" : "SHA3-512", + "content" : "3b642b5433989ba548cffebd7c155d5ada680b96996eac432895de56a27d7529c795d7263e8419854c9d118cddc0492d142d260a2e5434058134c9bc17ab8253" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-actuator@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-actuator@3.2.1?type=jar" + }, + { + "group" : "ch.qos.logback", + "name" : "logback-core", + "version" : "1.4.14", + "description" : "logback-core module", + "hashes" : [ + { + "alg" : "MD5", + "content" : "7367629d307fa3d0b82d76b9d3f1d09a" + }, + { + "alg" : "SHA-1", + "content" : "4d3c2248219ac0effeb380ed4c5280a80bf395e8" + }, + { + "alg" : "SHA-256", + "content" : "f8c2f05f42530b1852739507c1792f0080167850ed8f396444c6913d6617a293" + }, + { + "alg" : "SHA-512", + "content" : "d18159d4b378973e49182c4711b3d5b1f3600674ddd7bde26793247854bbd3a7233df7f74c356ecc86e4160ac6f866e0b32c109df6e1b428a10cddd4bc7f44e8" + }, + { + "alg" : "SHA-384", + "content" : "afe21cf21e8804d069514a1f0d57c92b4caf56f8b010bd681d19fff67f237fcf0bbe1e1c9bfc4cedcfe602a3ea859b57" + }, + { + "alg" : "SHA3-384", + "content" : "38cc28c8a578f4053412440d88b41938fa029a8ee3d350fe7474b34afa0f17889298d00f3c2cec4510d72d3342d29a77" + }, + { + "alg" : "SHA3-256", + "content" : "6c7d3be575969be97a49e90a97a8dc1bb25380b1b302073e00d2e21cb266e6a6" + }, + { + "alg" : "SHA3-512", + "content" : "8e9ce45d599bffac71e35a0d59c4dcff067f628157a75e9e28c1930f31537fb1dd058ddd9906322c1154f29436252a36bc50595578bfee9bcad4a9705c85726a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-1.0" + } + }, + { + "license" : { + "name" : "GNU Lesser General Public License", + "url" : "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" + } + } + ], + "purl" : "pkg:maven/ch.qos.logback/logback-core@1.4.14?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/ch.qos.logback/logback-core@1.4.14?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-test", + "version" : "3.2.1", + "description" : "Spring Boot Test", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5c793b3b61ba2637840a6c865aa2901e" + }, + { + "alg" : "SHA-1", + "content" : "142fbe3cfe3370c57d0ed55cca0d8d96e1d6f26e" + }, + { + "alg" : "SHA-256", + "content" : "0fb27aeb59ab757e60c48f9810d0ab54dc858a4c1cd9cc75b4ad07456c9c3e7c" + }, + { + "alg" : "SHA-512", + "content" : "975428c3f753ec1375f9c0ca2c47756a22896cc510193b53f7a8501255634a2e0d2165e699055667f4127cbaa8e79c9c128aef6de0854fccd4e158dce4422939" + }, + { + "alg" : "SHA-384", + "content" : "c3abb4c4a9961cab0fde6119d5b86755ea0c43fdd266b51d369a8544818463ce1876df2b13b0a2478f36b1e5282a305d" + }, + { + "alg" : "SHA3-384", + "content" : "641f9090f373f299d61bf54dd06e7ea15217c5b06424e970ddaed1f64e2a25aae74bdc10e04c9c4e934f2a3a5ab95c4b" + }, + { + "alg" : "SHA3-256", + "content" : "45d05dd704757c997b11f13961762e371309bec11292b32af3f244ca3b49642c" + }, + { + "alg" : "SHA3-512", + "content" : "53001dd1610347d6cf92f737067271fe3c638828a0b1e0b6aca62429e97a85018daf6ab3e10f065acd79ed7c93dc3a4c57f89eda3e2feb48ab548ca7e906b414" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar" + }, + { + "group" : "io.micrometer", + "name" : "micrometer-jakarta9", + "version" : "1.12.1", + "description" : "Module for Jakarta 9+ based instrumentations", + "hashes" : [ + { + "alg" : "MD5", + "content" : "0e247019d91d3c357b440436e1af2fba" + }, + { + "alg" : "SHA-1", + "content" : "2dc7257970669fa45e342b0b36902d868af2dbed" + }, + { + "alg" : "SHA-256", + "content" : "e8c66d7aee8fbc8a9d2e15c6c53df92bd7ecbf94f1ca8562d62d9a2693aa4633" + }, + { + "alg" : "SHA-512", + "content" : "3a481de081b216d42bd9b741b3a830c93d917c5ae8a11f670785b53b55cff601e1cdfd037b12d8b95cd8557c4493d6e04e51980860e421f444f2b4a953070969" + }, + { + "alg" : "SHA-384", + "content" : "cdbca1958c2502bcdad18446401f7f21ec2bc2c4055fd2fafa8fdad30cb8c8fd9aa9863de5ddd9cb852cafda487d29b0" + }, + { + "alg" : "SHA3-384", + "content" : "13f29eca056350277ee80d786945386abdd1c8b7c04dc35a94c7ac8146e7b6cafa617652fca15e79b8376341ae5576d0" + }, + { + "alg" : "SHA3-256", + "content" : "f095b2247aa3ada3c824121b4720dcceb3b65f7a2b9e880acdedc613a62d9be6" + }, + { + "alg" : "SHA3-512", + "content" : "773cd6f711b68a27d958ecb01f85d8480835014d23d3484e69e1c63bc736f50697bd6cf7d5e7776a13ae946ed10621334cb84ba8357b26d45cb6c9990826f993" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/io.micrometer/micrometer-jakarta9@1.12.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/io.micrometer/micrometer-jakarta9@1.12.1?type=jar" + }, + { + "group" : "com.fasterxml.jackson.module", + "name" : "jackson-module-parameter-names", + "version" : "2.15.3", + "description" : "Add-on module for Jackson (http://jackson.codehaus.org) to support introspection of method/constructor parameter names, without having to add explicit property name annotation.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "495868f770056602bfe13ea781656f03" + }, + { + "alg" : "SHA-1", + "content" : "8d251b90c5358677e7d8161e0c2488e6f84f49da" + }, + { + "alg" : "SHA-256", + "content" : "baf1a3156a23cb407e05374161a07ed8560f78a7ae249955de04a9a2fa2d0f2b" + }, + { + "alg" : "SHA-512", + "content" : "497b08f55f601b7ff6294e0b8307e015e60ad45c7949bd80ed3f5ee19daa93fad7f0b5a93abb8082ec46480667ab8539337633213d0fd5992e4a10c710f0a7aa" + }, + { + "alg" : "SHA-384", + "content" : "1a50ca6c0e0b4e3ecf83e3f327670a3b36f2b847b46ab5e193e9bccc36fee3bd41c1aa937dda88c4936339eafc73fc93" + }, + { + "alg" : "SHA3-384", + "content" : "30d05f1dd78a796ba4abb79be93dae2d7e4e5269de18d85a9d89b1c92f6ff8fe09ac1953a48a0b2b51906bbaadb56fca" + }, + { + "alg" : "SHA3-256", + "content" : "9e50d137efbe3de957a64fa4b90532cbb67efc2b09ba11824362315d1f57b812" + }, + { + "alg" : "SHA3-512", + "content" : "9418c5c18e429e201d7f6a4d5f05a52a433dbe4bf72a82e3ea69010c1d4b9ec99fc651804f2f8339a53841f88416318e3ab7fb1a07391cde5ea745ebbfcf98bc" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.15.3?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.15.3?type=jar" + }, + { + "group" : "org.junit.platform", + "name" : "junit-platform-engine", + "version" : "1.10.1", + "description" : "Module \"junit-platform-engine\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "4d571057589cd109f3f4bedf7bbf5e7a" + }, + { + "alg" : "SHA-1", + "content" : "f32ae4af74fde68414b8a3d2b7cf1fb43824a83a" + }, + { + "alg" : "SHA-256", + "content" : "baa48e470d6dee7369a0a8820c51da89c1463279eda6e13a304d11f45922c760" + }, + { + "alg" : "SHA-512", + "content" : "52ea2f11ec2ef0457384335d1b09263f4efecf63d9df99c5f8396f74d972722c51f8f766370e85e030f4476e805dac72603296942593c5bbe56993454b9d8e30" + }, + { + "alg" : "SHA-384", + "content" : "7c520e04c995a47c19c94fdcbbcba9bb117696191e6a989a82d9f960e0e315e5cf87d28022ac5cb2701c85d5f38eefde" + }, + { + "alg" : "SHA3-384", + "content" : "79d4f2fb987d6a44174dda99b1bd827e8dfd0399495c3e994371d4f69631212768dee8b891313aac89045388a1bed9db" + }, + { + "alg" : "SHA3-256", + "content" : "5c3fcec688368188688cb6949c1230c2822211e53f3a65b7b3abf4a38051798b" + }, + { + "alg" : "SHA3-512", + "content" : "30a0834e88bbc62287e5f49302c4a07b6da1bf4d9774faddbe7e606fb296c0dcd71c7e90ef8fff3e18dd050e5a19f7b903c91674ff4806cdb97111e4f0cfc199" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.platform/junit-platform-engine@1.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.platform/junit-platform-engine@1.10.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-autoconfigure", + "version" : "3.2.1", + "description" : "Spring Boot AutoConfigure", + "hashes" : [ + { + "alg" : "MD5", + "content" : "29fb14fe1d383588e87a73da4508604d" + }, + { + "alg" : "SHA-1", + "content" : "b100d2d21d45dddd740d496357ca6f3813d777d0" + }, + { + "alg" : "SHA-256", + "content" : "371f0f36d226a8db972c37c73f0a0896ee4d3e77c29b54dbce8a64af731a6e53" + }, + { + "alg" : "SHA-512", + "content" : "42bc3a99f9c9ffc9fd08447303a946fce1c81e3a869a5788c7d3b669536455eedc8009428ae4660d66b0d74ab170968b6aad905455b53342d7c521e7ec4c262f" + }, + { + "alg" : "SHA-384", + "content" : "f47603c4009bb767f9d5cb0bf3fcba69167daab53cbfafd217450977464073e8b814c76aa545b1eccee587201fe93eef" + }, + { + "alg" : "SHA3-384", + "content" : "bbd77376c9a46de290522662f327a8e6b0221a6c0105632e73b527799bec8a162d98948d0d05b32509650b4f47a6465e" + }, + { + "alg" : "SHA3-256", + "content" : "9e9549dda419ad6f482e3b376c595c69ccb93cebf365c1b18a59bf226c3264db" + }, + { + "alg" : "SHA3-512", + "content" : "1473f0de013447eb40d0b6d2a30013d2a7d262ce1e0259d4a27f88e421e5538234a46704f88b27c227aab7ae2261995a73f4075a6a43124e39c7234c6d164fe2" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar" + }, + { + "group" : "org.junit.jupiter", + "name" : "junit-jupiter-engine", + "version" : "5.10.1", + "description" : "Module \"junit-jupiter-engine\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "71d86cd027062c4da0796c2493ae94fe" + }, + { + "alg" : "SHA-1", + "content" : "6c9ff773f9aa842b91d1f2fe4658973252ce2428" + }, + { + "alg" : "SHA-256", + "content" : "02930dfe495f93fe70b26550ace3a28f7e1b900c84426c2e4626ce020c7282d6" + }, + { + "alg" : "SHA-512", + "content" : "1fcc9406d1e0301e27538757c9649545d784e83743a8800932971881cfd78a14a264ad13c0b92fad9ae1be50963c540427a19cb2d1fee06888ef48105aad4c8b" + }, + { + "alg" : "SHA-384", + "content" : "6657ac1bb11d7a40bbcb020add01e57edbbc521645116908d857074d9ea319eab3e7b7f2e9fa1ff8df08b5db3774f4dc" + }, + { + "alg" : "SHA3-384", + "content" : "607313914c11274c577b0aaaae6c68aa6ecf25d8302f55d4e334aa6b58df2e543d2399785e2019a56b85aac7716c9623" + }, + { + "alg" : "SHA3-256", + "content" : "be3560971111d3f548bef24aa6660ec2a126fd17b3bd68b7deeb1ab48735a9d1" + }, + { + "alg" : "SHA3-512", + "content" : "4ba6cb70f8fc1918dcedc874340488909c48e0f976d1834ec433f4b5c6cff55b16a996a0443a1b68a0d0ad84a37bf51386633905628728bde08b5820ee67dfaa" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.jupiter/junit-jupiter-engine@5.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-engine@5.10.1?type=jar" + }, + { + "group" : "io.micrometer", + "name" : "micrometer-observation", + "version" : "1.12.1", + "description" : "Module containing Observation related code", + "hashes" : [ + { + "alg" : "MD5", + "content" : "b55c9caac5c8f778996937c3f6cf4101" + }, + { + "alg" : "SHA-1", + "content" : "fbd0e0e9b6a36effd53e0eee35b050ed1f548ae5" + }, + { + "alg" : "SHA-256", + "content" : "48f6607b248e8b77ee9f7b3934f70124471daf947b30480c1b9c0e9d9f996c83" + }, + { + "alg" : "SHA-512", + "content" : "3e12e101b161715e5c30eb166578de7ae76749a2c4d22435bc57395be14d1313073d5fa76dcc883ed807d4982d343addfa24540e283cd0432f1428ff00962d98" + }, + { + "alg" : "SHA-384", + "content" : "791f99b503d7fa16733a74d92ebd02e72dfce4d648245f149f5363019beabe7e317e7ef0df0bcb67832dbab03943ff53" + }, + { + "alg" : "SHA3-384", + "content" : "ccb83eb15cd8004295bdb40b948cb9d3efaa4281b0d02a97b49970a2699822d7cd15b83206c236c3a41e49063caa5ded" + }, + { + "alg" : "SHA3-256", + "content" : "773e3647329d707d79efcb92c88cbe0719b4dcd820f06983e6e283e666875acc" + }, + { + "alg" : "SHA3-512", + "content" : "922f6c81c3a7b8e8c1296eb3359723161e91bac646d4bef954904c70a40ccfd9dc95c783715fcedc788f67ef06ea5514a918c7cc6811f2bdd39eb011a36698e7" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar" + }, + { + "group" : "org.awaitility", + "name" : "awaitility", + "version" : "4.2.0", + "description" : "A Java DSL for synchronizing asynchronous operations", + "hashes" : [ + { + "alg" : "MD5", + "content" : "8f3644827b9e3037de42068c57006260" + }, + { + "alg" : "SHA-1", + "content" : "2c39784846001a9cffd6c6b89c78de62c0d80fb8" + }, + { + "alg" : "SHA-256", + "content" : "2d23b79211fdd19036f6940cc783543779320aaf86f38d6e385a2ff26da41272" + }, + { + "alg" : "SHA-512", + "content" : "4c422b4aef3dfceb040898f45cd1b2efb7bbf213ef9487334a0d0e674e494e120fef61348f8a81ce726f2f66dc426e133917de20c52b5d39d792e2dca7bc82d8" + }, + { + "alg" : "SHA-384", + "content" : "11d15d6efb32707cae528eefb8fa4ab7820649ed528c3447660efd984518ee2906421af5ee76ea8181c904d594e8e719" + }, + { + "alg" : "SHA3-384", + "content" : "71eff4441379fb1d13bec42264d48dd1ed4817c7a226a4ef1e5255e5afcc8e5e61aa92677ae98fdce2bf4824b4dbe4fc" + }, + { + "alg" : "SHA3-256", + "content" : "4fc8b38b34625336be520d2be1edcab4c8dd8e0667fecb2aa6aea83b9bad7f28" + }, + { + "alg" : "SHA3-512", + "content" : "074f8629ab499c28155e505513e0a25c83ce722747d196966eac6327de604853503ca5f54b84effe8e2e3ab78d9ce285bdba82bf738ff8bff0f1009549230521" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.awaitility/awaitility@4.2.0?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.awaitility/awaitility@4.2.0?type=jar" + }, + { + "group" : "org.hamcrest", + "name" : "hamcrest", + "version" : "2.2", + "description" : "Core API and libraries of hamcrest matcher framework.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "10b47e837f271d0662f28780e60388e8" + }, + { + "alg" : "SHA-1", + "content" : "1820c0968dba3a11a1b30669bb1f01978a91dedc" + }, + { + "alg" : "SHA-256", + "content" : "5e62846a89f05cd78cd9c1a553f340d002458380c320455dd1f8fc5497a8a1c1" + }, + { + "alg" : "SHA-512", + "content" : "6b1141329b83224f69f074cb913dbff6921d6b8693ede8d2599acb626481255dae63de42eb123cbd5f59a261ac32faae012be64e8e90406ae9215543fbca5546" + }, + { + "alg" : "SHA-384", + "content" : "89bdcfdb28da13eaa09a40f5e3fd5667c3cf789cf43e237b8581d1cd814fee392ada66a79cbe77295950e996f485f887" + }, + { + "alg" : "SHA3-384", + "content" : "0d011b75ed22fe456ff683b420875636c4c05b3b837d8819f3f38fd33ec52b3ce2f854acfb7bebffc6659046af8fa204" + }, + { + "alg" : "SHA3-256", + "content" : "92d05019d2aec2c45f0464df5bf29a2e41c1af1ee3de05ec9d8ca82e0ee4f0b0" + }, + { + "alg" : "SHA3-512", + "content" : "4c5cbbe0dcaa9878e1dc6d3caa523c795a96280cb53843577164e5af458572cde0e82310cf5b52c1ea370c434d5631f02e06980d63126843d9b16e357a5f7483" + } + ], + "licenses" : [ + { + "license" : { + "id" : "BSD-3-Clause", + "url" : "https://opensource.org/licenses/BSD-3-Clause" + } + } + ], + "purl" : "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/hamcrest/JavaHamcrest" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar" + }, + { + "group" : "org.junit.jupiter", + "name" : "junit-jupiter-api", + "version" : "5.10.1", + "description" : "Module \"junit-jupiter-api\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "c6b8b04f2910f6cef6ac10846f43a92d" + }, + { + "alg" : "SHA-1", + "content" : "eb90c7d8bfaae8fdc97b225733fcb595ddd72843" + }, + { + "alg" : "SHA-256", + "content" : "60d5c398c32dc7039b99282514ad6064061d8417cf959a1f6bd2038cc907c913" + }, + { + "alg" : "SHA-512", + "content" : "b1fef44d4aa781bb119ab723c3c2a6f0d27efc4493a1fa26b603c7c7a8884c4d6274bccec6536f120d55f876f8d052aaf6cc003074c27cc704deb2c4bc08b6f0" + }, + { + "alg" : "SHA-384", + "content" : "0fd81f893be859a50766bfbf3bd74bd7d359c6d481b7fe3099e220402f585d3d46b6ad42a36b1d88eefbb6fd27a3cefa" + }, + { + "alg" : "SHA3-384", + "content" : "5e13ba92f757499ca52d719869d318cade9bde9c948ee9c68d753a21ec273f7b56ad68ff8cb281614efeef1d4c479db0" + }, + { + "alg" : "SHA3-256", + "content" : "997c9e0cc57d61a85a8eec568d0f014d47af5bf655602a2c3518b6530b089905" + }, + { + "alg" : "SHA3-512", + "content" : "e97c3e2c1faa1f77b174ef6ce7b24a2339e547f5976a4e40348653e84498e0c3bb96068447facef6df6b54d4af34b807f19b4d2bb1d31e26f97d6dae07843bf6" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar" + }, + { + "group" : "org.skyscreamer", + "name" : "jsonassert", + "version" : "1.5.1", + "description" : "A library to develop RESTful but flexible APIs", + "hashes" : [ + { + "alg" : "MD5", + "content" : "60a7d3d352b233487d735f4b86802717" + }, + { + "alg" : "SHA-1", + "content" : "6d842d0faf4cf6725c509a5e5347d319ee0431c3" + }, + { + "alg" : "SHA-256", + "content" : "1e9a7c443d0dd579906646d767f3701918a78cb88a93112f528305fc9095d261" + }, + { + "alg" : "SHA-512", + "content" : "51221bbeb30ed47840494d31128e605e29a96249f3e4b9c00985a865f8ed58b73e045772e3b0af74a35018a9dd004b5cc2182344b9154d9a50604ad1a073f2dd" + }, + { + "alg" : "SHA-384", + "content" : "941cec8d4ce1fab19f32b36f0afd2c7de27325659c5f85ab90948182098de4afe327b49cea57b946f18671af8037aefd" + }, + { + "alg" : "SHA3-384", + "content" : "3fb46460472c82901ec6fa5deab84eea18369e74aad920e3ee9e0fb8a859e8397a287428d0bf1c2b137368b6579c5c4b" + }, + { + "alg" : "SHA3-256", + "content" : "24b6c0f73ee51c19d5fdae62588dff9d0bf172da7e6ad1595e275920c8de829c" + }, + { + "alg" : "SHA3-512", + "content" : "686fb7b0ee0849bc78b6eeb74a941795252cec9a62ea153e6bd1e77d51fb6ee14f64970cb52cc13f581d21b166c6f1b28b8fbc4c7ae0c3b225df385a92635f0c" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.skyscreamer/jsonassert@1.5.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.skyscreamer/jsonassert@1.5.1?type=jar" + }, + { + "group" : "org.mockito", + "name" : "mockito-junit-jupiter", + "version" : "5.7.0", + "description" : "Mockito JUnit 5 support", + "hashes" : [ + { + "alg" : "MD5", + "content" : "ab44b412aa650651eedf323e945fe367" + }, + { + "alg" : "SHA-1", + "content" : "ac2d6a3431747a7986b8f4abef465f72bf3a21ae" + }, + { + "alg" : "SHA-256", + "content" : "e2416a260c3a45ba77d674cfe27d49428e57efe21a7b2ddeae733ebb5c5d85bf" + }, + { + "alg" : "SHA-512", + "content" : "39cccb119c0767f4e443567873af78d882c4a1e99c553ad39d4efae2698933de602d9c0046a70a05be552793569d4b43e75c2a798fd1f7f0a8c5ab34db8b9c94" + }, + { + "alg" : "SHA-384", + "content" : "f02eeae7fe867ff8580164b4d20d269efbad2a18ba2ffc8ba9744c603c589fb5155399361b14ab2a6549d605d26a4694" + }, + { + "alg" : "SHA3-384", + "content" : "6b95b5f5efcc97a2531c9c108e53fe5465ae0249d46988fe7fd47df7ad4d154de40a66471a996ae7abd75bd0c1f6c9b4" + }, + { + "alg" : "SHA3-256", + "content" : "30978340a8749b094a5b0f42dffbb91e72f7d7eaea6924efce13f47a44048fdf" + }, + { + "alg" : "SHA3-512", + "content" : "80601cb4de8850a0255b7c28cb7993be667a238d961fd281c7152b7ba40eec399240a2ab9d686cd1463872652876e88ef221d699acb61a2acf041c9f187053ab" + } + ], + "licenses" : [ + { + "license" : { + "id" : "MIT", + "url" : "https://opensource.org/licenses/MIT" + } + } + ], + "purl" : "pkg:maven/org.mockito/mockito-junit-jupiter@5.7.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "build-system", + "url" : "https://github.com/mockito/mockito/actions" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/mockito/mockito/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/mockito/mockito.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.mockito/mockito-junit-jupiter@5.7.0?type=jar" + }, + { + "group" : "org.apache.logging.log4j", + "name" : "log4j-api", + "version" : "2.21.1", + "description" : "The Apache Log4j API", + "hashes" : [ + { + "alg" : "MD5", + "content" : "b5e9bf76dd128b37666ecd9a252b50ec" + }, + { + "alg" : "SHA-1", + "content" : "74c65e87b9ce1694a01524e192d7be989ba70486" + }, + { + "alg" : "SHA-256", + "content" : "1db48e180881bef1deb502022006a025a248d8f6a26186789b0c7ce487c602d6" + }, + { + "alg" : "SHA-512", + "content" : "4cbf72fbea7009ec2fc363aae2ccfe11ea2023967d65be39335eedd1d8917b7402eeb2219efd5a1f11d03833dd1f57eecab428616b03124ef2266c6cca06ac56" + }, + { + "alg" : "SHA-384", + "content" : "edd8429f2f88476afbfa63314f7846d1341a4cfc58d3abe55b3cda236613feb6859f711e0ae60bd7821b74e488fb0666" + }, + { + "alg" : "SHA3-384", + "content" : "b67292ff0c7ca988a4b40b6ec14582ef579990d275a37944ac9572ecdfd4bf6e9fff2ab982b21d159a1135c21a32495f" + }, + { + "alg" : "SHA3-256", + "content" : "b2641c2db75d3c676e451a53b5f60dfaf030a84e0230747bd50d00414f8a27b3" + }, + { + "alg" : "SHA3-512", + "content" : "f1f4d9c48a9d088460e1ad3d71126b243069e522588cdc5534ac8f201ec0574287e8f1fba182f8925ee75b78726269487cc0160f7f8bd1aa21cc8e587fdb5c4a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0", + "url" : "https://www.apache.org/licenses/LICENSE-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.logging.log4j/log4j-api@2.21.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.logging.log4j/log4j-api@2.21.1?type=jar" + }, + { + "group" : "org.assertj", + "name" : "assertj-core", + "version" : "3.24.2", + "description" : "Rich and fluent assertions for testing in Java", + "hashes" : [ + { + "alg" : "MD5", + "content" : "b596a91049e6ce526bc5595c1bebea2c" + }, + { + "alg" : "SHA-1", + "content" : "ebbf338e33f893139459ce5df023115971c2786f" + }, + { + "alg" : "SHA-256", + "content" : "df3d0b348f1fe806bdddcb10fa4ae63c6679e9888d4bc7055f09848517976aa3" + }, + { + "alg" : "SHA-512", + "content" : "d8e3159effc7954258f2398e26c34eab6c243675408c7b5fcd7ed04a7b7dc06006514510ad15be9e7725f724cbf6e5c534cb22cbfb7c0aed71b81d4ed5755220" + }, + { + "alg" : "SHA-384", + "content" : "4f06196b5329e215282476d8e3aa5065092924bccb91da4eb0aa2e8fcd2509f249369654f0c17b59c38f11b878a305e3" + }, + { + "alg" : "SHA3-384", + "content" : "3029ae58aef975843e9205f130dcdd8f8e7da5ff1bfad62b7d918ffe52b74a3c34a859af13393abe122124a9132f3feb" + }, + { + "alg" : "SHA3-256", + "content" : "2db6965251a03be26f5baa83792a002444b4de34aaaefb0e6cf3cccf0a20939e" + }, + { + "alg" : "SHA3-512", + "content" : "fa3ffb87bc40c3f881fb477d41c8565cbc1ce46ead2030442674bb86a425c722b75fce5bb3c22425b21cc3122ac46e0f28b2eaba2bcf5d5ddcb31f47d967b890" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.assertj/assertj-core@3.24.2?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.assertj/assertj-core@3.24.2?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-web", + "version" : "3.2.1", + "description" : "Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container", + "hashes" : [ + { + "alg" : "MD5", + "content" : "8a6aea9e1fbdbabbd00e35038739200f" + }, + { + "alg" : "SHA-1", + "content" : "e27e36d4222fd4d589e634e1c7f5f09f0316147c" + }, + { + "alg" : "SHA-256", + "content" : "2f14d3a4a0ae3ad634bcfa07117542001c1789c0bdce3504baee8f2bc45ef006" + }, + { + "alg" : "SHA-512", + "content" : "2fcfc8d9abfcd0518b6755737c6e520544600b3c26b42b60d1ab3fcfceb31582d5dbcd5d86a98ec312442d335e49f0db0ecf21d8e99089ef41d962ece42d97ae" + }, + { + "alg" : "SHA-384", + "content" : "e3c8cb02b18ea5b7aa2a7c9c97c62385fcaa8fc53f41d7bf0b98d262a10473e9674924ad287964f6e58fb9c5915da8d1" + }, + { + "alg" : "SHA3-384", + "content" : "713c9200480f14fd4bcd073d43ac7900771c9d36b4e72b50ddf80733670948ad57700ea37336de5078d16557e426de79" + }, + { + "alg" : "SHA3-256", + "content" : "3346906c7b4b455c00226fd9804a237d3a667523800e0c2083413fde4592b7c3" + }, + { + "alg" : "SHA3-512", + "content" : "99ba750d8e1c97636eb47122ce259b1bc9b91c51fecc50d13604f7ae7096a20f1fa38562d83786c1d4c3ba07ff94b286d869d671a5f0d00fd6c378f032332f63" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-web@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-web@3.2.1?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-test", + "version" : "3.2.1", + "description" : "Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito", + "hashes" : [ + { + "alg" : "MD5", + "content" : "f808bed72032367a1170477e74e57f7e" + }, + { + "alg" : "SHA-1", + "content" : "e6a20062864e3a9a0bba0ac3b0c5a819453045b9" + }, + { + "alg" : "SHA-256", + "content" : "2e0a11d69fed912dd6f5a6b0f492ce1530e2ac932de9588d4b7df0ab548eea0a" + }, + { + "alg" : "SHA-512", + "content" : "83c1f7e7b404be7b9f603a386ca2d0c84c7e0b73190ffb19ef2b0dff5cbc1ebd57ce73be663ee01ed28f1c4f41d91db7f070d7b37a3f2ae6b9b6814dd930a089" + }, + { + "alg" : "SHA-384", + "content" : "3a5159cad10587b250f0a1f7cf6ebea9f2cbda539c008094fec1dff47eeced5b2119be3ad007eab0598445b9282164f4" + }, + { + "alg" : "SHA3-384", + "content" : "9303b808eed6e0425d5c7e968601960d9ff2e0c2fd840ffd041b01f0499b1f86ae05c50e968e925374a54b26e9298410" + }, + { + "alg" : "SHA3-256", + "content" : "a18f18bd0a077a38ea0b3aeae85730b9f104d65d4d48f88210f2954c45739eae" + }, + { + "alg" : "SHA3-512", + "content" : "e021bfc51b8d6b8cdc1b44cf5042778c208db09b349250e33630b28ace2ed97d52bd89750ab70e14b650578f379a7e6172838c83bbb2c974394132cb80381f27" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.2.1?type=jar" + }, + { + "group" : "jakarta.activation", + "name" : "jakarta.activation-api", + "version" : "2.1.2", + "description" : "${project.name} ${spec.version} Specification", + "hashes" : [ + { + "alg" : "MD5", + "content" : "1af11450fafc7ee26c633d940286bc16" + }, + { + "alg" : "SHA-1", + "content" : "640c0d5aff45dbff1e1a1bc09673ff3a02b1ba12" + }, + { + "alg" : "SHA-256", + "content" : "f53f578dd0eb4170c195a4e215c59a38abfb4123dcb95dd902fef92876499fbb" + }, + { + "alg" : "SHA-512", + "content" : "383283f469aba01a274591e29f1aa398fefa273bca180162d9d11c87509ffb55cb2dde51783bd6cae6f2c4347e0ac7358cf11f4c85787d5d2857354b9e29d877" + }, + { + "alg" : "SHA-384", + "content" : "e34ac294c104cb67ac06f7fc60752e54a881c04f68271b758899739a5df5be2d2d0e707face2705b95fa5a26cedf9313" + }, + { + "alg" : "SHA3-384", + "content" : "ffd74b0335a4bfdd9a0c733c77ecdfa967d5280500c7d2f01e2be8499d39a9f0cd29c9063ae634223347bb00f4e60c33" + }, + { + "alg" : "SHA3-256", + "content" : "c97236eaebb15b8aefa034b23834eaeed848dacf119746c6d87832c47581e74d" + }, + { + "alg" : "SHA3-512", + "content" : "147dfa2bf46bb47c81462c36ac6612f9f807169ffb785e2bbd45538205c5713f33af4373f3324a2063350c2367baff37e9c2cf085c38c96870ad88c60a7fbea4" + } + ], + "licenses" : [ + { + "license" : { + "id" : "BSD-3-Clause" + } + } + ], + "purl" : "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://github.com/jakartaee/jaf-api/issues/" + }, + { + "type" : "vcs", + "url" : "https://github.com/jakartaee/jaf-api" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2?type=jar" + }, + { + "group" : "io.micrometer", + "name" : "micrometer-core", + "version" : "1.12.1", + "description" : "Core module of Micrometer containing instrumentation API and implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "30dcc7ea6a0e99663e5908bce7371206" + }, + { + "alg" : "SHA-1", + "content" : "b72e9a2f26355ecb8ababa0148a5c3c4ac648f14" + }, + { + "alg" : "SHA-256", + "content" : "97d0a5309e9c584f4dec6f549a383ae25d8727abff43cff8e0b90580ee797b67" + }, + { + "alg" : "SHA-512", + "content" : "2acd080a1b40cb5a1ca0b7266af829392e318291dab57e6239ca97d15112cc206992b78316f4c02400454124519a084341e4de55dd729c96805b3fb196707a64" + }, + { + "alg" : "SHA-384", + "content" : "9a3998a9a219fc049ace5731fde94944948332eccbe589dbc34456057a2df173ef17e3b0642233e513d3118bcfba565f" + }, + { + "alg" : "SHA3-384", + "content" : "22c97b3fb49d299ebc36674a6e32d9fd05726d88109ede3323e3e97e82100d1ed6d7010e86749a2b07ffe994fb3b7833" + }, + { + "alg" : "SHA3-256", + "content" : "3b272686c89e274b5944715db002871e072f0f8c7099228f6d6909656b6ba3f4" + }, + { + "alg" : "SHA3-512", + "content" : "b1d82086950a2e61ed3e016fa962af2e9c3b2d543c4c311d40d9f7fc402b9beb3e5d09261d336cb1634b186f723bf584874f3fb8a29c38198d5ddd2b386c4413" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/io.micrometer/micrometer-core@1.12.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/io.micrometer/micrometer-core@1.12.1?type=jar" + }, + { + "group" : "org.junit.jupiter", + "name" : "junit-jupiter-params", + "version" : "5.10.1", + "description" : "Module \"junit-jupiter-params\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5e8e17f6f2a5dedb42d9846a3352dd31" + }, + { + "alg" : "SHA-1", + "content" : "c8f15d4e99940c4564098af78c10809c00fdca06" + }, + { + "alg" : "SHA-256", + "content" : "c8cf62debcbb354deefe1ffd0671eff785514907567d22a615ff8a8de4522b21" + }, + { + "alg" : "SHA-512", + "content" : "dbd8a3bca0a03b6eef54de2b489685c8125e0c6f23cbdb633174b21e07cc7b97a24b55dcb5b60ec1a496683a918bfdf1ea0459950689e3755aa965ea9e106ee9" + }, + { + "alg" : "SHA-384", + "content" : "882b3106163d7c195867e08db9948a0997e1469a23c847bff523efa30a9b274c0588f8228fca98c78abf9b61709a7ff2" + }, + { + "alg" : "SHA3-384", + "content" : "6e4e9a7dbb32cc3f16f21a14fe036aa13488c5b94e3cb6cc53b417c4588b90b5ae118caa3eb9f4bc9c513d06e2c1f408" + }, + { + "alg" : "SHA3-256", + "content" : "171a08027b527e3be1ad66082405eacf4a55746dd983c46d9ff7ee5552276615" + }, + { + "alg" : "SHA3-512", + "content" : "c435b4a17208b67f6fa35ebe74872c3d2c3557b290437bb682ac86701402bbe17d0e53446c674bb94c7feaae4bbfa99d888c7bf7181707e27fe08ff7934c00f6" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.10.1?type=jar" + }, + { + "group" : "com.fasterxml.jackson.core", + "name" : "jackson-databind", + "version" : "2.15.3", + "description" : "General data-binding functionality for Jackson: works on core streaming API", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5f453c55f127690fa8491ce347aa055c" + }, + { + "alg" : "SHA-1", + "content" : "a734bc2c47a9453c4efa772461a3aeb273c010d9" + }, + { + "alg" : "SHA-256", + "content" : "c3c53333a2172a80678bda1803e39cff45bec6ae3e9c7d4f44a81ec4e2ab18dc" + }, + { + "alg" : "SHA-512", + "content" : "490ccc99a9c28238fe28455bae08196b83df034cae8a1947d27ff89e500a5d812cf4be36c61942e647c62ad540d8eb4428f49855f0cc8db0ee9e7a5b12ba2454" + }, + { + "alg" : "SHA-384", + "content" : "b53f4a6fddbf677a8d02c65e9f0a96372140c68286d68740987fb462f946de878abaeea421d3e4716751f04d88c16ad1" + }, + { + "alg" : "SHA3-384", + "content" : "5a407605544e303abf8a212651bf5e5594fa313804a399bf03401f449c0baf26ef965def518b05c275b2f38f18457739" + }, + { + "alg" : "SHA3-256", + "content" : "d0880002ac261d181e663499627fcce5763f3a9120bb76e758adfb9939d17c98" + }, + { + "alg" : "SHA3-512", + "content" : "e97bfe0e9117dad82e0799cb2c105c4553c6aa5ce9abdefee4fd5b584876555309aafa9a19ca586e928e292e32f23452849a10da7364966e11e4f7afcc6aec78" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/FasterXML/jackson-databind" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + }, + { + "group" : "org.slf4j", + "name" : "jul-to-slf4j", + "version" : "2.0.9", + "description" : "JUL to SLF4J bridge", + "hashes" : [ + { + "alg" : "MD5", + "content" : "24f86e89ee3f71ea91f644150c507740" + }, + { + "alg" : "SHA-1", + "content" : "09ef7c70b248185845f013f49a33ff9ca65b7975" + }, + { + "alg" : "SHA-256", + "content" : "69b4e5f8d3bd3f6f54367d19f2c1ee95dd5877802f12d868282e218dd76b00bf" + }, + { + "alg" : "SHA-512", + "content" : "c1cdfbc0c867917d65ab58e039b01c5b119368aef82abcb406d91646da208a4bfad91831a5a425eacfa8253ccd5713a9d4325d45665288483929cce7a6a56eb7" + }, + { + "alg" : "SHA-384", + "content" : "a8d45375ec27c0833a441f28055ba2c07b601fb7a9bc54945672fc2f7b957d8ada5d574ab607ef3f9a279c32c0a7b0a5" + }, + { + "alg" : "SHA3-384", + "content" : "d65edaa8f6ad8bbea84617e414ede438ec4aafffa3734f2d38e6dd0a01c1f42f9397acaf6291a73489fb252d7369c71e" + }, + { + "alg" : "SHA3-256", + "content" : "69416188261a8af7cb686a6d68a809f4e7cab668f6b12d4456ce8fd9df7a1c25" + }, + { + "alg" : "SHA3-512", + "content" : "52d54c80e3934913a184efc091978201934b0ee47a6b4f9c8555a4d549becd26957e17592aff46dfdcfcbcb2313bfad09699ee84cfd7112ed2a00422c87399e8" + } + ], + "licenses" : [ + { + "license" : { + "id" : "MIT", + "url" : "https://opensource.org/licenses/MIT" + } + } + ], + "purl" : "pkg:maven/org.slf4j/jul-to-slf4j@2.0.9?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.slf4j/jul-to-slf4j@2.0.9?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot", + "version" : "3.2.1", + "description" : "Spring Boot", + "hashes" : [ + { + "alg" : "MD5", + "content" : "6f7384977eae04c804b1062df9217959" + }, + { + "alg" : "SHA-1", + "content" : "faa2ce019bee68a8d17529d0a08ebc427f927e13" + }, + { + "alg" : "SHA-256", + "content" : "6fde604399114e77b12519b3d117117c607cb73b89a88800856fb0e0cc82ea7a" + }, + { + "alg" : "SHA-512", + "content" : "8619959d143ef38f5c846591b8b10b0c50906a3301a5e9ed3e3df44124bdfbe3197cd4ecfb214c3250f40a0c1b11138b7a3f6865755445879f0685d2e88a6846" + }, + { + "alg" : "SHA-384", + "content" : "e237fdf6fdb8d21f2fc19fc15a370901c368266ae8d2b157f41b5eeed50b211a871fabc352dda10bb3aec60975d233f5" + }, + { + "alg" : "SHA3-384", + "content" : "cd6240fc102daf1efcd9fdd6532ce21297d5477e9bde3f5651cc9ec9505d526f63ea2284e484c2aee2a8e63841137839" + }, + { + "alg" : "SHA3-256", + "content" : "3959b52aebe7405a95f82d8990b8122cf21b89967f691dad851b85191973f9cb" + }, + { + "alg" : "SHA3-512", + "content" : "1b4ef33997158ddb97ccbcec7011cd55f0e019428d25410b01a83ca58c9420f2f8805be955cf704605145abe582522db0c8afb9698ae4efac141a3807a457ae5" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + }, + { + "group" : "org.latencyutils", + "name" : "LatencyUtils", + "version" : "2.0.3", + "description" : "LatencyUtils is a package that provides latency recording and reporting utilities.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "2ad12e1ef7614cecfb0483fa9ac6da73" + }, + { + "alg" : "SHA-1", + "content" : "769c0b82cb2421c8256300e907298a9410a2a3d3" + }, + { + "alg" : "SHA-256", + "content" : "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec" + }, + { + "alg" : "SHA-512", + "content" : "bb81a42498c65389366205f4e07cee336920e2f05cc0daae213f2784b1d0ce9a908b038daec20478f23eb00b2bf704f96c5b00f63c99615193ab2a3cc4a9f890" + }, + { + "alg" : "SHA-384", + "content" : "16ca4640dc9d848e6c6d15441897e1b5a9f27f34207b0bb456dd54d8f267b73b348092e548e78634144de44ba3515205" + }, + { + "alg" : "SHA3-384", + "content" : "406c2b5c6f64b0c090568e479b5e6136a04a4e77f8eea65d32b4e2b01deebcdf6a0a851240cdb740c25b5a5e61e6c179" + }, + { + "alg" : "SHA3-256", + "content" : "50ae828358301033542fd7c412e86ee318d5451f89a182e2a679aaf18099d26d" + }, + { + "alg" : "SHA3-512", + "content" : "456c337b9fb385579aae707409ed6a04d08e5fc87b1a46733dca617c22c625bf253dc4747e0cdbf5e7d8b48102d2938cb482b6b688a79aab645a7459c592258f" + } + ], + "licenses" : [ + { + "license" : { + "id" : "CC0-1.0" + } + } + ], + "purl" : "pkg:maven/org.latencyutils/LatencyUtils@2.0.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "issue-tracker", + "url" : "https://github.com/LatencyUtils/LatencyUtils/issues" + }, + { + "type" : "vcs", + "url" : "scm:git:git://github.com/LatencyUtils/LatencyUtils.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.latencyutils/LatencyUtils@2.0.3?type=jar" + }, + { + "group" : "org.apache.tomcat.embed", + "name" : "tomcat-embed-el", + "version" : "10.1.17", + "description" : "Core Tomcat implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "f9171a84574782d1d68acd8b07177172" + }, + { + "alg" : "SHA-1", + "content" : "9ad7312421535d7d3aabe0f541e852baccb59726" + }, + { + "alg" : "SHA-256", + "content" : "bac12b9c993a9181ffc88ea8ba085491a482729e64ae105750a7475a7b85e549" + }, + { + "alg" : "SHA-512", + "content" : "77cf7be4536d7f1f4761fec33562134150c0ebc74d582160ff913c8be37b1502ed63e90bce81bc8617cfcd76c774903c2dca4209a972146f4c976f786456c596" + }, + { + "alg" : "SHA-384", + "content" : "62b14b49de8ee6efb41831ff172114af56a18379a797de732915ac356bce3e5582764253852c9831a3c3b6c1e52dea65" + }, + { + "alg" : "SHA3-384", + "content" : "05cb21cbf8b221332d7ad588cc6aa2087c60e8ce92c5ff2bddcd16465ef2a0198f74d4595dc3313d1acc68ea945c8672" + }, + { + "alg" : "SHA3-256", + "content" : "c18e9b240138c21a23b0bf2f502d1d667084c5a50d7b3340a4a08799a3175de9" + }, + { + "alg" : "SHA3-512", + "content" : "663d02ece35a989d8da1cdbdea002974f0115ae8c727dd71f0505f299c63f04c0e83b718e4c3e65412bea1c79d872e9ca7d9431c7deb63a312d3191d419620ab" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.17?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.17?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-context", + "version" : "6.1.2", + "description" : "Spring Context", + "hashes" : [ + { + "alg" : "MD5", + "content" : "ca23d3013c2afc6d3b30b993f3c5cd69" + }, + { + "alg" : "SHA-1", + "content" : "15df19852991220556b4462a366269b8e15278eb" + }, + { + "alg" : "SHA-256", + "content" : "af22a435469956415bbee873de6c05995ef12f2d29622abf510a94581ea52de2" + }, + { + "alg" : "SHA-512", + "content" : "eca3cb14e8c0fb65d27bc21a8041aab3baea14f278fb546356fcec9874d0dcd10353fe697e94ebc35a78abb3387d5a41b67c1cbc9341eb05359c1b535147a9c9" + }, + { + "alg" : "SHA-384", + "content" : "374207d989f7f27ded5468f35867d0aace78927cdaf98c31b2b6345210fbbe960ae5e5143bb0308347b7ef386159fa04" + }, + { + "alg" : "SHA3-384", + "content" : "236c1d366734b231ef4a334da4220b311dd58b1707ae854b2a50ff89b6b348913458fecdab14d196128b695de6dc9832" + }, + { + "alg" : "SHA3-256", + "content" : "e1e1e87df37dbc064315d7afaa59480c830a0f445ed0df2ff5968931f96e9e86" + }, + { + "alg" : "SHA3-512", + "content" : "a600b2720ed8e5c6ecbb2a68b6a5fb5320811818e2128016b9888df705901a8d0f38dfa99b8d458724a85e769b4da2ce14d461133e085f8aab23f59e9e520c11" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-context@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-context@6.1.2?type=jar" + }, + { + "group" : "org.opentest4j", + "name" : "opentest4j", + "version" : "1.3.0", + "description" : "Open Test Alliance for the JVM", + "hashes" : [ + { + "alg" : "MD5", + "content" : "03c404f727531f3fd3b4c73997899327" + }, + { + "alg" : "SHA-1", + "content" : "152ea56b3a72f655d4fd677fc0ef2596c3dd5e6e" + }, + { + "alg" : "SHA-256", + "content" : "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b" + }, + { + "alg" : "SHA-512", + "content" : "78fc698a7871bb50305e3657893c10500595f043348d875f57bc39ca4a6a51eda3967b7c8c8a7ec3e8f85f2171bca4aa98823e912e416e87e81c6ba5b70a37c3" + }, + { + "alg" : "SHA-384", + "content" : "10398b6998c9202a0731e2e19ae1c3f9d8a83582c2663fe7bdda15794ee6fa816727dbd8f7c7164bd5395ee1cfe7c97e" + }, + { + "alg" : "SHA3-384", + "content" : "3abe706fd78509c25a402c7bbf6f9ddf71ffb5b35054864ba0fdf7902207115f888a0ba728fd71d2e87a9360d2498121" + }, + { + "alg" : "SHA3-256", + "content" : "d961907a1bfa1dcda329dca494ffbc251b31fabcaca5ab7095661a8ce3c1d654" + }, + { + "alg" : "SHA3-512", + "content" : "0ad661617bcac51bcd26f7ad4611c69b1fd9811b50dbf734e041a3243ab1f845e7796620e8a7c40c4a2df3946864598b1251396c7d9bd813203d82710788cce0" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.opentest4j/opentest4j@1.3.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/ota4j-team/opentest4j" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.opentest4j/opentest4j@1.3.0?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-core", + "version" : "6.1.2", + "description" : "Spring Core", + "hashes" : [ + { + "alg" : "MD5", + "content" : "98bedebd5de314d344ed3a7dcad01c66" + }, + { + "alg" : "SHA-1", + "content" : "e43c71a9eaca454654621f7d272f15b53c68d583" + }, + { + "alg" : "SHA-256", + "content" : "8e3f7378e98c26500bdb5ecd6865778f57a22787eb2f11b9bd5fb8e438a0c631" + }, + { + "alg" : "SHA-512", + "content" : "9654f2d77899116d66dbf5808815c866da0bc7a965532da059c7819bde3928e8d3692f0dc97e06f94c44e5452b785b50eb364a1cb7e46385653ba0e2c7195306" + }, + { + "alg" : "SHA-384", + "content" : "3b63b4a26c5706ef2e379ff7bce89df983e7ae449a927905ce23ecf26e22bbcf8e91dc53cc75f4f7cd72bc09d7e7bb20" + }, + { + "alg" : "SHA3-384", + "content" : "ca29e88f0764a6a9279fc93d5cb9284a04c6ccca6a8a5beaa404079b90674286fc6458d14b0b0a727d31e00b8009e4f9" + }, + { + "alg" : "SHA3-256", + "content" : "861fc1147deae5a55165bd32c3fd4e18687afcc37876205c10bf1feede582ff9" + }, + { + "alg" : "SHA3-512", + "content" : "659a0d2e5ba153be219e1ebbafb28f9b48c44a2acd78d695e7479551a1c1641b7893d7df071a3cc7436de03735b0c8024b2f758bd0286711eae64ab005f6e929" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-core@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + }, + { + "group" : "com.jayway.jsonpath", + "name" : "json-path", + "version" : "2.8.0", + "description" : "A library to query and verify JSON", + "hashes" : [ + { + "alg" : "MD5", + "content" : "501b9f34e6a05c20dd74e6b40e066617" + }, + { + "alg" : "SHA-1", + "content" : "b4ab3b7a9e425655a0ca65487bbbd6d7ddb75160" + }, + { + "alg" : "SHA-256", + "content" : "9601707e95cd79fb98570a01ea8cfb857b5cde948744d6e0edf733c11002c95b" + }, + { + "alg" : "SHA-512", + "content" : "8d1521092a2acb13a2667774b8b81debc1f2a0e937007e27e5bd28bb222910774b64d6e269f33473f765c810c03a34e715d16065dc9a4be8d8d081436282ba7e" + }, + { + "alg" : "SHA-384", + "content" : "aeea493be7c23574a77df50a0652776b768d52e4238efd504b8ef3b142bbe6caf0dae8955b30c2173a54f70243d36a36" + }, + { + "alg" : "SHA3-384", + "content" : "c11c80614c007f350fa2fe758c0f4505e7ed7d25590622f133abc59ccffeb4e0b2abfd393b83e58dff4668307f28704f" + }, + { + "alg" : "SHA3-256", + "content" : "d7a7d1d7845dde343617ec009dd0d76e6bf012f182324e3b9d0f23c52bb7f67f" + }, + { + "alg" : "SHA3-512", + "content" : "da023255dfa2271a0b6b35b7d35980c3c502f3f63b3d515714f7dea54046f527bd6cbd903fec9492aad88ad03a1b85dc2b05fca4b34ded3c3b427c4cbfab02fe" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.jayway.jsonpath/json-path@2.8.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "scm:git:git://github.com/jayway/JsonPath.git" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.jayway.jsonpath/json-path@2.8.0?type=jar" + }, + { + "group" : "org.slf4j", + "name" : "slf4j-api", + "version" : "2.0.9", + "description" : "The slf4j API", + "hashes" : [ + { + "alg" : "MD5", + "content" : "45630e54b0f0ac2b3c80462515ad8fda" + }, + { + "alg" : "SHA-1", + "content" : "7cf2726fdcfbc8610f9a71fb3ed639871f315340" + }, + { + "alg" : "SHA-256", + "content" : "0818930dc8d7debb403204611691da58e49d42c50b6ffcfdce02dadb7c3c2b6c" + }, + { + "alg" : "SHA-512", + "content" : "069e6ddce79617e37d61758120c7e68348ee62f255781948937f7bec3058e46244026d7f6a11e90fbc15cd4288c4bb1acee4f242af521c721a9e68a05e64d526" + }, + { + "alg" : "SHA-384", + "content" : "fd6f7ad85d02ac63cd1a586c8bb158c1fc000495f512f097731ea9f749b5da2637615b821294962805ba312c738f40aa" + }, + { + "alg" : "SHA3-384", + "content" : "17cd61f59a162250b52a89c7c56eb60da253b776210500313c7b82744483ff84717946f969251fb4d76f9bb12a2458fe" + }, + { + "alg" : "SHA3-256", + "content" : "9dcb04582c64c79e788f9191195834ec75bb3457133d22a176a0ccb069b97103" + }, + { + "alg" : "SHA3-512", + "content" : "990faffa454598a3fa82affe30f1323db769d2e1fff20d9c7163ef6fd95ac7a0874c06a634207a2eaed9e5afbdee68b225138fc75018717ba97efe3ffe92c88a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "MIT", + "url" : "https://opensource.org/licenses/MIT" + } + } + ], + "purl" : "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar" + }, + { + "group" : "ch.qos.logback", + "name" : "logback-classic", + "version" : "1.4.14", + "description" : "logback-classic module", + "hashes" : [ + { + "alg" : "MD5", + "content" : "204b49a7fa041b2b2c455193079dc1d2" + }, + { + "alg" : "SHA-1", + "content" : "d98bc162275134cdf1518774da4a2a17ef6fb94d" + }, + { + "alg" : "SHA-256", + "content" : "8e832f7263ca606ae36dabb2d8b24c2f43d82cf634e81dad9d1640fa6ee3c596" + }, + { + "alg" : "SHA-512", + "content" : "77b535f2cf5a2fdb807017cb6fe456c40dcb11491e743ff86f99df2714a1b12bb9182ac193d37c8a6dd7eb2bf4c7d24390a6d551d02a280083673516eecdabc4" + }, + { + "alg" : "SHA-384", + "content" : "606400251082b8193a57bb20f1774ee2d6e439fab2ddb0207643fe9cee66cf61edba5e5c80d4b3bc9785a7bab910f8df" + }, + { + "alg" : "SHA3-384", + "content" : "d9d9b1412d2fea3eeb5d110a0e7d44c9bc13459fd2b2f5cbb30b95174081f0184758abe43b5e6b6197a716c3ba7b310f" + }, + { + "alg" : "SHA3-256", + "content" : "e1b0d59a9a91fd7878c92b3680cde8c34896823612a2f04715c05e977c09db82" + }, + { + "alg" : "SHA3-512", + "content" : "e0a39dacbb91b7d9f00bdf78829918079f6f2e749c28f31a359064bac9ac7eb65c87e581795946814460f787e33b8829a9cf0e933a0f87dd7d48f288d45f5064" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-1.0" + } + }, + { + "license" : { + "name" : "GNU Lesser General Public License", + "url" : "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" + } + } + ], + "purl" : "pkg:maven/ch.qos.logback/logback-classic@1.4.14?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/ch.qos.logback/logback-classic@1.4.14?type=jar" + }, + { + "publisher" : "Chemouni Uriel", + "group" : "net.minidev", + "name" : "accessors-smart", + "version" : "2.5.0", + "description" : "Java reflect give poor performance on getter setter an constructor calls, accessors-smart use ASM to speed up those calls.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "fc814b28882dd9f2552eda21add0698f" + }, + { + "alg" : "SHA-1", + "content" : "aca011492dfe9c26f4e0659028a4fe0970829dd8" + }, + { + "alg" : "SHA-256", + "content" : "12314fc6881d66a413fd66370787adba16e504fbf7e138690b0f3952e3fbd321" + }, + { + "alg" : "SHA-512", + "content" : "77b21fdd3401a0557d2d04a14c27563897afe9e001fc520398e22083bc18afee5e48dd9f5fc6561d0f327a30a9303bf5cc20f0a2ce741d80b3792e258276faac" + }, + { + "alg" : "SHA-384", + "content" : "7464bf3917d11712b235c7e1af339766d01cb4b41ec98941c3c69bc4ab9a4d0e6c832cbf01482425100dc8f1611ce3a0" + }, + { + "alg" : "SHA3-384", + "content" : "be26dc2bfc5fdc1a45e14f1c2fcfe224994e66d39049e235ea83c714fb90bb685d3f2209c0d550528e2cd9b2d9d95a6e" + }, + { + "alg" : "SHA3-256", + "content" : "6a914eb757ec313842f13c837eeb628e606323cc63dc24127e7a9804e2746d12" + }, + { + "alg" : "SHA3-512", + "content" : "edbddef0538aac87bf6af714e12c4078fd6ada069b6fd0e1e5c1038b060999764e06c28b3ca38b8d540d0f60c72f7321ddc22d2537156999bad5098c89b6975a" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/net.minidev/accessors-smart@2.5.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://urielch.github.io/" + }, + { + "type" : "distribution", + "url" : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + }, + { + "type" : "vcs", + "url" : "https://github.com/netplex/json-smart-v2" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/net.minidev/accessors-smart@2.5.0?type=jar" + }, + { + "group" : "com.fasterxml.jackson.core", + "name" : "jackson-core", + "version" : "2.15.3", + "description" : "Core Jackson processing abstractions (aka Streaming API), implementation for JSON", + "hashes" : [ + { + "alg" : "MD5", + "content" : "c86c75392bf138d54d2a219bb1d0cbcd" + }, + { + "alg" : "SHA-1", + "content" : "60d600567c1862840397bf9ff5a92398edc5797b" + }, + { + "alg" : "SHA-256", + "content" : "51fab7aad51ed588482edc507fd542747936c5094d1ab76ed21ddb63b96b610d" + }, + { + "alg" : "SHA-512", + "content" : "112de40a31dc7d011f256f1d2fe0d9e2afc301a1f31974318f8d070c3e362b2ba96005167384244f630b915451db6694bd3cf6a9b793872351bc18f21c9de5e4" + }, + { + "alg" : "SHA-384", + "content" : "9daaf08467525e462234c53ddbf7287bcef15d8df7fbc64bcd558a91d11e8335b3a79368d194b126d3c8fb846800025b" + }, + { + "alg" : "SHA3-384", + "content" : "0b4fdc8d11fc060461e74e773fce2e64d1a98bed7db6edf51784bb1b801da4bae744a2958e81c2e24cb992fec892fb6c" + }, + { + "alg" : "SHA3-256", + "content" : "751ad4f10a78cb36fccbbe1dfe208816f17619edd5adeabc86b7509201e03c3d" + }, + { + "alg" : "SHA3-512", + "content" : "aa5807b7d92d150fada6a4ecdbfce998bbea825a09af8381127ba3736de029ae9923f54d770b2e5c3f5c85d9b4bcf21e6893a5a3089db2d02f1432b85dfa0fe7" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/FasterXML/jackson-core" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar" + }, + { + "group" : "org.xmlunit", + "name" : "xmlunit-core", + "version" : "2.9.1", + "description" : "XMLUnit for Java", + "hashes" : [ + { + "alg" : "MD5", + "content" : "011288450a3905a7d97e3957b69e713e" + }, + { + "alg" : "SHA-1", + "content" : "e5833662d9a1279a37da3ef6f62a1da29fcd68c4" + }, + { + "alg" : "SHA-256", + "content" : "7e70f23d4f75e05f0ee79f0f6b9e13b6cf51d34f36c5fc3a6b839429dde1efef" + }, + { + "alg" : "SHA-512", + "content" : "1d07dc1582a1930664ab3cffd1443e85c83fec138c663f3070a9d3b283f818157b2cdd1589595867281a96d3b444b18c22c1ee3249a75c857c6ee9682785e8a3" + }, + { + "alg" : "SHA-384", + "content" : "f54a506a08b66776d92d4379712ae9f7658cc89bd7b780eb629bd37143ff68e28cb2314539dc3c1ff13dc9cccba394f2" + }, + { + "alg" : "SHA3-384", + "content" : "7fd679371624f72417612491bac721a49f229744df3fc7455e5fd3983bd2de452a4eaabb707be7bac328f3beeea88d99" + }, + { + "alg" : "SHA3-256", + "content" : "c517aa9c543a4a3df361c30ba6609082a1dd5dc2abc351643ad5b733a1282773" + }, + { + "alg" : "SHA3-512", + "content" : "3797bade2087f791697f6736296381f8b158a2a93f50faeabcd96b4c9f48ad26fd78af56cc1036c449c35e624181961d54acdd7623b84c23c81c72d5d0fa57f1" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.xmlunit/xmlunit-core@2.9.1?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.xmlunit/xmlunit-core@2.9.1?type=jar" + }, + { + "publisher" : "OW2", + "group" : "org.ow2.asm", + "name" : "asm", + "version" : "9.3", + "description" : "ASM, a very small and fast Java bytecode manipulation framework", + "hashes" : [ + { + "alg" : "MD5", + "content" : "e1c3b96035117ab516ffe0de9bd696e0" + }, + { + "alg" : "SHA-1", + "content" : "8e6300ef51c1d801a7ed62d07cd221aca3a90640" + }, + { + "alg" : "SHA-256", + "content" : "1263369b59e29c943918de11d6d6152e2ec6085ce63e5710516f8c67d368e4bc" + }, + { + "alg" : "SHA-512", + "content" : "04362f50a2b66934c2635196bf8e6bd2adbe4435f312d1d97f4733c911e070f5693941a70f586928437043d01d58994325e63744e71886ae53a62c824927a4d4" + }, + { + "alg" : "SHA-384", + "content" : "304aa6673d587a68a06dd8601c6db0dc4d387f89a058b7600459522d94780e9e8d87a2778604fc41b81c43a57bf49ad6" + }, + { + "alg" : "SHA3-384", + "content" : "9744884ed03ced46ed36c68c7bb1f523678bcbb4f32ebeaa220157b8631e862d6573066dfc2092ed77dc7826ad17aef2" + }, + { + "alg" : "SHA3-256", + "content" : "2be2d22fdbafe87b7cdda0498fc4f45db8d77a720b63ec1f7ffe8351e173b77b" + }, + { + "alg" : "SHA3-512", + "content" : "a3ff403dd3eefbb7511d2360ab1ca3d1bf33b2f9d1c5738284be9d132eb6ad869f2d97e790ed0969132af30271e544d3725c02252267fe55e0339f89f3669ce1" + } + ], + "licenses" : [ + { + "license" : { + "id" : "BSD-3-Clause", + "url" : "https://opensource.org/licenses/BSD-3-Clause" + } + } + ], + "purl" : "pkg:maven/org.ow2.asm/asm@9.3?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "http://www.ow2.org/" + }, + { + "type" : "issue-tracker", + "url" : "https://gitlab.ow2.org/asm/asm/issues" + }, + { + "type" : "mailing-list", + "url" : "https://mail.ow2.org/wws/arc/asm/" + }, + { + "type" : "vcs", + "url" : "https://gitlab.ow2.org/asm/asm/" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.ow2.asm/asm@9.3?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter", + "version" : "3.2.1", + "description" : "Core starter, including auto-configuration support, logging and YAML", + "hashes" : [ + { + "alg" : "MD5", + "content" : "d9eb815815944bcdaeed5e63f32e5d7f" + }, + { + "alg" : "SHA-1", + "content" : "bc03d7075fb9d9d4877218db48d5dae3dd72a65d" + }, + { + "alg" : "SHA-256", + "content" : "a25f2f4172c34f46b73fff03293370c3daf231a1db2883ef8032aa471779fb8b" + }, + { + "alg" : "SHA-512", + "content" : "35cc80f9b10e81624324083a024c97e247e12f54762cfaadf40504903b0ebdc76d0226af1e4646bca445211b039913709ff48289dd57e27ecab18fd6e427d306" + }, + { + "alg" : "SHA-384", + "content" : "9acae9f3f77733a83d37641d3bd32d762225a08dcb20d61ff33a9038e8a4fe2dd39026bb08026cdb618437f68fc11382" + }, + { + "alg" : "SHA3-384", + "content" : "1e605937a46c8371423b7876d5dae4363f718f70200a1276056bd6466d03096aa580708c7abc76618a141a542df29b24" + }, + { + "alg" : "SHA3-256", + "content" : "331b3c120493fb5d9dd628beb8aa10382772a08d0a687103a2e87a4516fffde6" + }, + { + "alg" : "SHA3-512", + "content" : "9f2612fbecec4664979896868e4766b1f66aaebc914e46a07a7ef7e5ff76786e5a73ae9ca5f364d23ae41f8bea2fb44e5034014950423fdc3a438ae1dc275820" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar" + }, + { + "group" : "org.apache.tomcat.embed", + "name" : "tomcat-embed-core", + "version" : "10.1.17", + "description" : "Core Tomcat implementation", + "hashes" : [ + { + "alg" : "MD5", + "content" : "81d2d784780b1fe54275ab4f3d0c3830" + }, + { + "alg" : "SHA-1", + "content" : "5b9185ee002f9e194d2cb21ddcf8bc5f3d4a69da" + }, + { + "alg" : "SHA-256", + "content" : "5d70fa6ae0548f89fb4c070423ecc2db050cebf248b0d5f3f2294375a6762382" + }, + { + "alg" : "SHA-512", + "content" : "9fb1726f3a10f5e0bdd1cafcdc9532536679d04e5cdde9e54bdf18819ea2651bcaac0efddd6a8b5dbf3cfb8dfcd7ab0453f2ff3fa4e21a0f3796d4dd6d630433" + }, + { + "alg" : "SHA-384", + "content" : "e644a094c17574fc9334772913aeabd6de0be8eacb0718981dbd97ee197a21f43ff3efe2c073f8863a4ff111f4ccb303" + }, + { + "alg" : "SHA3-384", + "content" : "2e8d5d4b1e202e19529270adc7992e9d187ad34bdd62ab7633359f3394059cdade69c88dddd3879dea40487cb17702da" + }, + { + "alg" : "SHA3-256", + "content" : "25826af7f0a6fd192e83cd14481055b0c5477c325e51d17355d9ff97963380a0" + }, + { + "alg" : "SHA3-512", + "content" : "0b2513e578a484562ad47a8a1a4d1fe8253a9a276fac49ea9732877d976a2d1827037caa5a6401d5659c765317acb94127e62f99373a4efea63b44ab4a1824be" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar" + }, + { + "group" : "net.bytebuddy", + "name" : "byte-buddy-agent", + "version" : "1.14.10", + "description" : "The Byte Buddy agent offers convenience for attaching an agent to the local or a remote VM.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "389b6aca1ee862684592f6f041f81724" + }, + { + "alg" : "SHA-1", + "content" : "90ed94ac044ea8953b224304c762316e91fd6b31" + }, + { + "alg" : "SHA-256", + "content" : "67993a89d47ca58ff868802a4448ddd150e5fe4e5a5645ded990d7b4d557a6b9" + }, + { + "alg" : "SHA-512", + "content" : "7f1a1310b1a0f60d6ff07dee8d9b7e404e8fb9a25a5c0c186e00cafc834e5a026a7694fb65279367dabfa1789c1f16192d0ea794b7f511f0bb3414b8d519e9a5" + }, + { + "alg" : "SHA-384", + "content" : "ed1e1d594a7c2837311accf3f718cbc7c6e2034afcab13c63d72313ee1ffd18a53863f1ccd194b85b7e0ffed78bafc9c" + }, + { + "alg" : "SHA3-384", + "content" : "b3baeae67826ec4e4f71b2870220c362f153d2a126b04557302b5b8e24a58b9741bef7afa9c4e4f0fa1ea9371cbcb1df" + }, + { + "alg" : "SHA3-256", + "content" : "01ccb9e430868deef5b51124073643eaf6dd2c8c7e4d6e70b59042c9d28e3361" + }, + { + "alg" : "SHA3-512", + "content" : "b621fa443ade355b10cc45329a5e0f700942dd39e633a8f2343ece00446cd42f5c1217b041a67b3143df86397c363f8dcad226f1e70b8755126512a74f878262" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.10?type=jar", + "modified" : false, + "type" : "library", + "bom-ref" : "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.10?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-test", + "version" : "6.1.2", + "description" : "Spring TestContext Framework", + "hashes" : [ + { + "alg" : "MD5", + "content" : "fadfe62dd198a4acce4416acb28e2869" + }, + { + "alg" : "SHA-1", + "content" : "c393079051398e02c20d8b24e02822f365123719" + }, + { + "alg" : "SHA-256", + "content" : "2155779c3e461df55f3b093f0e6e4bda398664e3452efe599690bc9a3f1932f0" + }, + { + "alg" : "SHA-512", + "content" : "5e6e4f76edbf17a321302bf6257c09ed7893e32c50fb3cace37b2271f3c488d397c67b5315ef3019ee6d28544f52cf593e0475bf00927cd67f0c668d6b3909a3" + }, + { + "alg" : "SHA-384", + "content" : "151df7daac9a3e3e74732405bd4feb17ad9ff3e4de196e767f39da675d4480994ed8da13e3b1b27c7b4ee9ebc17feef8" + }, + { + "alg" : "SHA3-384", + "content" : "9069193468f2ae4c65c94d3950541efe37498a4e19245ddc67909181e83e14019f956baba54da0b9d2e8a262db13abd0" + }, + { + "alg" : "SHA3-256", + "content" : "8ccf71564f5ee7e6a578031c7c8530a5ddf136cc1dce483818ebd30d53c851df" + }, + { + "alg" : "SHA3-512", + "content" : "31049da217d1115b589780ffaa3ddfbf676cc58e70bd4cbc1f24c0cb2aea6b155539f8f9b3f6757f19719fed0a6102110f195b34cdd464b5e375132c25e7bb51" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-test@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-test@6.1.2?type=jar" + }, + { + "group" : "org.junit.jupiter", + "name" : "junit-jupiter", + "version" : "5.10.1", + "description" : "Module \"junit-jupiter\" of JUnit 5.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "32fd55a03f648868767c1bebedd198df" + }, + { + "alg" : "SHA-1", + "content" : "6e5c7dd668d6349cb99e52ab8321e73479a309bc" + }, + { + "alg" : "SHA-256", + "content" : "c1a386e901fae28e493185a47c8cea988fb1a37422b353a0f8b4df2e6c5d6037" + }, + { + "alg" : "SHA-512", + "content" : "c97a2f9eefa6f34441fc0c97744873040bbe49d335954edab43bab25876a33f4b3f11347459420569ef660449728aa093bbae5d42c0fa733a0b624706b57a65d" + }, + { + "alg" : "SHA-384", + "content" : "873dfccaf8366ce5b14dc0b5498205debecd90ecba20b1f1c924721764d546b5b9629dd57c486e5a5a2bc38954bf3824" + }, + { + "alg" : "SHA3-384", + "content" : "67f09e3174ae3fac6ddea13b56dcf078165e715cb18afd73d86bb980357e365cef6e62083231f09ae2accddfe62f5bcb" + }, + { + "alg" : "SHA3-256", + "content" : "1c2a60003b13025c959e7728b3f4469b67bad8649d2080c0871418fb52b1c078" + }, + { + "alg" : "SHA3-512", + "content" : "7c03cfaeabed9c57b26e083bcb0ca9a114c491216fc7e9652a39a5468579175e575ace315493610fdc7711c6557eff11933fbd28f5433c237d2277bee102c5a6" + } + ], + "licenses" : [ + { + "license" : { + "id" : "EPL-2.0" + } + } + ], + "purl" : "pkg:maven/org.junit.jupiter/junit-jupiter@5.10.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "vcs", + "url" : "https://github.com/junit-team/junit5" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.junit.jupiter/junit-jupiter@5.10.1?type=jar" + }, + { + "publisher" : "Chemouni Uriel", + "group" : "net.minidev", + "name" : "json-smart", + "version" : "2.5.0", + "description" : "JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.", + "hashes" : [ + { + "alg" : "MD5", + "content" : "af9b7eda9c435acaf22e840991c7b10f" + }, + { + "alg" : "SHA-1", + "content" : "57a64f421b472849c40e77d2e7cce3a141b41e99" + }, + { + "alg" : "SHA-256", + "content" : "432b9e545848c4141b80717b26e367f83bf33f19250a228ce75da6e967da2bc7" + }, + { + "alg" : "SHA-512", + "content" : "56284bb3cee2bcc3684cdcc610115c7eacafdbd70aa852cb0209616b0503dfd448c5110b50e11a71b1c61a6e7ea27594ff63cc968230374555cc6f652d69d372" + }, + { + "alg" : "SHA-384", + "content" : "0fbbd6899d344c3158007f2f033165284323f1ecdfa49e17730d9d2bed8b3d77bbdc209a72a388e9e15a5bed9d9c8eef" + }, + { + "alg" : "SHA3-384", + "content" : "0f18f178117f8c640e7e1ac2ed4c2b28e331f658f40eac2f5974e891f7130b760e4f057859a537caaa046ba9c086a24a" + }, + { + "alg" : "SHA3-256", + "content" : "4c91eaa12f7c0ee08264ad95d016cfa41af08c963055b7f9076771da402e93e0" + }, + { + "alg" : "SHA3-512", + "content" : "0c5fad6395cf3fd25c04fd1e2c915351da4849475b463e017b760ef97800addb170d11f89791dd29ab867e343c35fd1f3ea7935622ba728d789c9f2e7fd1da51" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/net.minidev/json-smart@2.5.0?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://urielch.github.io/" + }, + { + "type" : "distribution", + "url" : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + }, + { + "type" : "vcs", + "url" : "https://github.com/netplex/json-smart-v2" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/net.minidev/json-smart@2.5.0?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-expression", + "version" : "6.1.2", + "description" : "Spring Expression Language (SpEL)", + "hashes" : [ + { + "alg" : "MD5", + "content" : "2f56216dc7ee08cbeafa54ccf18cad35" + }, + { + "alg" : "SHA-1", + "content" : "98786397734b27b7c8843a6b01a7fa34d40d6806" + }, + { + "alg" : "SHA-256", + "content" : "0fef5fb19f375a8632d2a117f4b3aed059b959e9693e90c3b7f57b7cad2f9e0b" + }, + { + "alg" : "SHA-512", + "content" : "a28e984d9ff1d4078d57f139ff28065ffba7f325c891c74c0774cd3ccfe50a9462cd93483c28c8ca4674b581ab723687c37c5c88e7cb080823d5629fa684e7f8" + }, + { + "alg" : "SHA-384", + "content" : "a84fb64144a67b56ce322fc9f4948a9491f6f5876d198eb57c99f38540971a0779a2949b93cc5f32662f97a83823ea87" + }, + { + "alg" : "SHA3-384", + "content" : "b099ce06de6a5543e52a2d43c97c4ed6567e82263db29849ff09cf37bf48e3e9974308698c2f272187508e242f756576" + }, + { + "alg" : "SHA3-256", + "content" : "efa3768de47e3b1ff9257f8367a528e38b3eec9c972eb7ba3dd8f60da626fb17" + }, + { + "alg" : "SHA3-512", + "content" : "95d7011482520e797a25f9d9b8db1b1bf6c24b3ddb3ca4b70fe5a1a58ed04ea870f86f8393f884dad8b893a6fc53ad8da1b21fdc01d9169564c3dc0229824b27" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar" + }, + { + "publisher" : "VMware, Inc.", + "group" : "org.springframework.boot", + "name" : "spring-boot-starter-actuator", + "version" : "3.2.1", + "description" : "Starter for using Spring Boot's Actuator which provides production ready features to help you monitor and manage your application", + "hashes" : [ + { + "alg" : "MD5", + "content" : "59713236dc4fc4b1562a3ea9788bde1e" + }, + { + "alg" : "SHA-1", + "content" : "ca17ff67e80a230f04d40d73321d623b769e361d" + }, + { + "alg" : "SHA-256", + "content" : "31c28021755feab49cc9310a8353382b3ca35d0adf02926b83e4c44ea4942898" + }, + { + "alg" : "SHA-512", + "content" : "ed618c7f1e3337c90919551ad4f14996bb2a78f773ba00c1e02d5a991d1c578e940d9b73f5e01045115c7b5d3f096f8de6720ba0d28992a586ef834948f17766" + }, + { + "alg" : "SHA-384", + "content" : "45956cbd019f099f96f36391c98fd23ea32698035f90f6e4e4df0d9a43dc03ef6db2954c2871da76a038511280591b43" + }, + { + "alg" : "SHA3-384", + "content" : "3a08b673deb39ab5db9561281245b76e9f57410601e5ce4040cefedb02e2a19abb45a98d2de170fbbac7b7f0b93eceb3" + }, + { + "alg" : "SHA3-256", + "content" : "12151432b32e26bab903572023ea022757a31177e4a6315d8fcd15bbbf34731c" + }, + { + "alg" : "SHA3-512", + "content" : "911f109b63d07f20de51f8a2de8799e32fdff05a52def36d408cb1da72a3bb63ff0878f850a7ad1cc9e85393f24ac58c6b8dd4068f11d9e70bc1e130974db00f" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework.boot/spring-boot-starter-actuator@3.2.1?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-boot/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-boot" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-actuator@3.2.1?type=jar" + }, + { + "publisher" : "Spring IO", + "group" : "org.springframework", + "name" : "spring-beans", + "version" : "6.1.2", + "description" : "Spring Beans", + "hashes" : [ + { + "alg" : "MD5", + "content" : "5ee147f2234968eeab4b469af4d3b5f1" + }, + { + "alg" : "SHA-1", + "content" : "abf52f2254975a3b1e95b2b63fb8b01d891cdc51" + }, + { + "alg" : "SHA-256", + "content" : "742baa41c1b0282ef01b3d542dc1b1de71db2578bd9ddd9a7d57fb191234b194" + }, + { + "alg" : "SHA-512", + "content" : "efd0eb5a073c899515ae144a4fcb4fc97cc53cbd4236d0e6a30df8fa8873fcd9bc509bc3fa88d1bff86a94dc3dbc5106374d0117f64ec8df9e6affe8f98aaa07" + }, + { + "alg" : "SHA-384", + "content" : "6214558d1024fa3b5545079268b0b2fbeda93768a0665d617612ddf4e42e11b770c38c05cb86e3ae558025afa67beea5" + }, + { + "alg" : "SHA3-384", + "content" : "8170ccea30165f25c533e27c0de38b590ca72f285cfc365c60e97745e78532213d6c93bdbea56f561dd180297a8c5ab4" + }, + { + "alg" : "SHA3-256", + "content" : "2761e0814e167de13ed08ce748880006407eda2fa744a347f57684c2bc9bb6fe" + }, + { + "alg" : "SHA3-512", + "content" : "ecdeb4cd558af513ed381942f35bd2d8dfa9b0db446dbc8c5326656ade960682283c71fcaae5578ca431f705f1a86041b0764bd453f30e738be65c4f0bbf37d1" + } + ], + "licenses" : [ + { + "license" : { + "id" : "Apache-2.0" + } + } + ], + "purl" : "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "modified" : false, + "externalReferences" : [ + { + "type" : "website", + "url" : "https://spring.io/projects/spring-framework" + }, + { + "type" : "issue-tracker", + "url" : "https://github.com/spring-projects/spring-framework/issues" + }, + { + "type" : "vcs", + "url" : "https://github.com/spring-projects/spring-framework" + } + ], + "type" : "library", + "bom-ref" : "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar" + } + ], + "dependencies" : [ + { + "ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/ch.qos.logback/logback-classic@1.4.14?type=jar", + "dependsOn" : [ + "pkg:maven/ch.qos.logback/logback-core@1.4.14?type=jar", + "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/io.micrometer/micrometer-jakarta9@1.12.1?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-core@1.12.1?type=jar", + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.15.3?type=jar", + "dependsOn" : [ + "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar", + "pkg:maven/com.jayway.jsonpath/json-path@2.8.0?type=jar", + "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.1?type=jar", + "pkg:maven/net.minidev/json-smart@2.5.0?type=jar", + "pkg:maven/org.assertj/assertj-core@3.24.2?type=jar", + "pkg:maven/org.awaitility/awaitility@4.2.0?type=jar", + "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar", + "pkg:maven/org.junit.jupiter/junit-jupiter@5.10.1?type=jar", + "pkg:maven/org.mockito/mockito-junit-jupiter@5.7.0?type=jar", + "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar", + "pkg:maven/org.skyscreamer/jsonassert@1.5.1?type=jar", + "pkg:maven/org.springframework/spring-test@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar", + "pkg:maven/org.xmlunit/xmlunit-core@2.9.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar", + "dependsOn" : [ + "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar", + "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.10?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-actuator@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar", + "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.yaml/snakeyaml@2.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-web@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter-json@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "pkg:maven/org.springframework/spring-webmvc@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter-tomcat@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-test@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/net.minidev/accessors-smart@2.5.0?type=jar", + "dependsOn" : [ + "pkg:maven/org.ow2.asm/asm@9.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.xmlunit/xmlunit-core@2.9.1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/io.micrometer/micrometer-core@1.12.1?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar", + "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12?type=jar", + "pkg:maven/org.latencyutils/LatencyUtils@2.0.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.opentest4j/opentest4j@1.3.0?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/net.minidev/json-smart@2.5.0?type=jar", + "dependsOn" : [ + "pkg:maven/net.minidev/accessors-smart@2.5.0?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.junit.platform/junit-platform-commons@1.10.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.17?type=jar", + "dependsOn" : [ + "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.21.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar", + "pkg:maven/org.apache.logging.log4j/log4j-api@2.21.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/ch.qos.logback/logback-classic@1.4.14?type=jar", + "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.21.1?type=jar", + "pkg:maven/org.slf4j/jul-to-slf4j@2.0.9?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.skyscreamer/jsonassert@1.5.1?type=jar", + "dependsOn" : [ + "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1?type=jar" + ] + }, + { + "ref" : "pkg:maven/ch.qos.logback/logback-core@1.4.14?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.15.3?type=jar", + "dependsOn" : [ + "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-webmvc@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-context@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.assertj/assertj-core@3.24.2?type=jar", + "dependsOn" : [ + "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.jayway.jsonpath/json-path@2.8.0?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.17?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-core@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-jcl@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.10.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar", + "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-context@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-expression@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.slf4j/jul-to-slf4j@2.0.9?type=jar", + "dependsOn" : [ + "pkg:maven/org.slf4j/slf4j-api@2.0.9?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.apache.logging.log4j/log4j-api@2.21.1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.10?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.junit.jupiter/junit-jupiter@5.10.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.10.1?type=jar", + "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-tomcat@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar", + "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.17?type=jar", + "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.17?type=jar", + "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.17?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.awaitility/awaitility@4.2.0?type=jar", + "dependsOn" : [ + "pkg:maven/org.hamcrest/hamcrest@2.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-actuator@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-context@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar", + "dependsOn" : [ + "pkg:maven/io.micrometer/micrometer-commons@1.12.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-jcl@6.1.2?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-json@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "pkg:maven/org.springframework/spring-web@6.1.2?type=jar", + "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.mockito/mockito-junit-jupiter@5.7.0?type=jar", + "dependsOn" : [ + "pkg:maven/org.mockito/mockito-core@5.7.0?type=jar" + ] + }, + { + "ref" : "pkg:maven/net.bytebuddy/byte-buddy@1.14.10?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.10.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.junit.platform/junit-platform-commons@1.10.1?type=jar", + "pkg:maven/org.opentest4j/opentest4j@1.3.0?type=jar", + "pkg:maven/org.apiguardian/apiguardian-api@1.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.15.3?type=jar", + "dependsOn" : [ + "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.1?type=jar", + "dependsOn" : [ + "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.2.1?type=jar", + "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar", + "pkg:maven/org.yaml/snakeyaml@2.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.latencyutils/LatencyUtils@2.0.3?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-test@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.springframework/spring-aop@6.1.2?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework/spring-beans@6.1.2?type=jar", + "pkg:maven/org.springframework/spring-core@6.1.2?type=jar" + ] + }, + { + "ref" : "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1?type=jar", + "dependsOn" : [ ] + }, + { + "ref" : "pkg:maven/org.springframework.boot/spring-boot-starter-actuator@3.2.1?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.2.1?type=jar", + "pkg:maven/io.micrometer/micrometer-jakarta9@1.12.1?type=jar", + "pkg:maven/io.micrometer/micrometer-observation@1.12.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.15.3?type=jar", + "dependsOn" : [ + "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.15.3?type=jar", + "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.3?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.example/cyclonedx@0.0.1-SNAPSHOT?type=jar", + "dependsOn" : [ + "pkg:maven/org.springframework.boot/spring-boot-starter-actuator@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter-web@3.2.1?type=jar", + "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.2.1?type=jar" + ] + }, + { + "ref" : "pkg:maven/org.ow2.asm/asm@9.3?type=jar", + "dependsOn" : [ ] + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/spdx.json b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/spdx.json new file mode 100644 index 000000000000..37e278638766 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/spdx.json @@ -0,0 +1,3909 @@ +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "documentNamespace": "https://anchore.com/syft/file/sbom-test-gradle-0.0.1-SNAPSHOT.jar-d1583014-0f58-4476-8f5f-dbbcd2df5102", + "creationInfo": { + "licenseListVersion": "3.23", + "creators": [ + "Organization: Anchore, Inc", + "Tool: syft-0.105.0" + ], + "created": "2024-02-15T12:39:33Z" + }, + "packages": [ + { + "name": "HdrHistogram", + "SPDXID": "SPDXRef-Package-java-archive-HdrHistogram-2c7953c2c68ec3bc", + "versionInfo": "2.1.12", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "6eb7552156e0d517ae80cc2247be1427c8d90452" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-d509473237fa971bc0a8ad7708f3cd561fcf86ef2e611701ed8eec621fd6575e", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:HdrHistogram:HdrHistogram:2.1.12:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:hdrhistogram:HdrHistogram:2.1.12:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12" + } + ] + }, + { + "name": "LatencyUtils", + "SPDXID": "SPDXRef-Package-java-archive-LatencyUtils-f9418986cc24a153", + "versionInfo": "2.0.3", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "769c0b82cb2421c8256300e907298a9410a2a3d3" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-Public-Domain--per-Creative-Commons-CC0", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:LatencyUtils:LatencyUtils:2.0.3:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:latencyutils:LatencyUtils:2.0.3:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.latencyutils/LatencyUtils@2.0.3" + } + ] + }, + { + "name": "jackson-annotations", + "SPDXID": "SPDXRef-Package-java-archive-jackson-annotations-c1e7975b6f55f7e8", + "versionInfo": "2.16.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "fd441d574a71e7d10a4f73de6609f881d8cdfeec" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-https---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-annotations:jackson-annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-annotations:jackson_annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_annotations:jackson-annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_annotations:jackson_annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson-annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson_annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-annotations:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson-annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson_annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_annotations:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson-annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson_annotations:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.16.1" + } + ] + }, + { + "name": "jackson-core", + "SPDXID": "SPDXRef-Package-java-archive-jackson-core-0408f25059f495c5", + "versionInfo": "2.16.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "9456bb3cdd0f79f91a5f730a1b1bb041a380c91f" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-https---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-core:jackson-core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-core:jackson_core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_core:jackson-core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_core:jackson_core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson-core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson_core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-core:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson-core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson_core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_core:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson-core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson_core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-core:core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_core:core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:core:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.16.1" + } + ] + }, + { + "name": "jackson-databind", + "SPDXID": "SPDXRef-Package-java-archive-jackson-databind-9ad3756f611d1ed2", + "versionInfo": "2.16.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "02a16efeb840c45af1e2f31753dfe76795278b73" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-https---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-databind:jackson-databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-databind:jackson_databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_databind:jackson-databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_databind:jackson_databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson-databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson_databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-databind:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson-databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson_databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_databind:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson-databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson_databind:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:core:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.16.1" + } + ] + }, + { + "name": "jackson-datatype-jdk8", + "SPDXID": "SPDXRef-Package-java-archive-jackson-datatype-jdk8-846731ed2e85561c", + "versionInfo": "2.16.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "695d9b8639cfc7a42a0507708cef2366fe492a44" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-http---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype-jdk8:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype-jdk8:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype_jdk8:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype_jdk8:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:datatype:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:datatype:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype-jdk8:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype_jdk8:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:datatype:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.16.1" + } + ] + }, + { + "name": "jackson-datatype-jsr310", + "SPDXID": "SPDXRef-Package-java-archive-jackson-datatype-jsr310-1347581c05f302c0", + "versionInfo": "2.16.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "36a418325c618e440e5ccb80b75c705d894f50bd" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-http---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype-jsr310:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype-jsr310:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype_jsr310:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype_jsr310:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:datatype:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:datatype:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype-jsr310:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype_jsr310:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-datatype:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_datatype:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:datatype:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.16.1" + } + ] + }, + { + "name": "jackson-module-parameter-names", + "SPDXID": "SPDXRef-Package-java-archive-jackson-module-parameter-names-f5bca9d628ab321f", + "versionInfo": "2.16.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "9e167afd1596e6a6aa6fe4e1af17f4ce8be0676f" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-http---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module-parameter-names:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module-parameter-names:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module_parameter_names:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module_parameter_names:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module-parameter:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module-parameter:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module_parameter:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module_parameter:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module-parameter-names:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module_parameter_names:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:module:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:module:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module-parameter:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module_parameter:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson-module:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson_module:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:module:jackson:2.16.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.16.1" + } + ] + }, + { + "name": "jakarta.annotation-api", + "SPDXID": "SPDXRef-Package-java-archive-jakarta.annotation-api-77a5bf527533d628", + "versionInfo": "2.1.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "48b9bda22b091b1f48b13af03fe36db3be6e1ae3" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-85a9a90b97292e5203565dd71a1a086ca3fe4d8ccea74453294fee37d5b0c7ae", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jakarta.annotation-api:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jakarta.annotation-api:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jakarta.annotation_api:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jakarta.annotation_api:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:eclipse-foundation:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:eclipse-foundation:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:eclipse_foundation:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:eclipse_foundation:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jakarta.annotation:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jakarta.annotation:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:glassfish:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:glassfish:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1" + } + ] + }, + { + "name": "jul-to-slf4j", + "SPDXID": "SPDXRef-Package-java-archive-jul-to-slf4j-598311f4a5b2a501", + "versionInfo": "2.0.11", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "279356f8e873b1a26badd8bbb3284b5c3b22c770" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-http---www.opensource.org-licenses-mit-license.php", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul-to-slf4j:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul-to-slf4j:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul_to_slf4j:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul_to_slf4j:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul-to:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul-to:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul_to:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul_to:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:slf4j:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:slf4j:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:jul:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.slf4j/jul-to-slf4j@2.0.11" + } + ] + }, + { + "name": "log4j-api", + "SPDXID": "SPDXRef-Package-java-archive-log4j-api-c404b33d3a8ce0d8", + "versionInfo": "2.22.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "bea6fede6328fabafd7e68363161a7ea6605abd1" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-bc2074dd7e94ae9ffbcea3c53de6625b1b651c330895f46cf72d207c3025b98b", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:log4j-api:2.22.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:log4j_api:2.22.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:log4j:2.22.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:api:2.22.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.apache.logging.log4j/log4j-api@2.22.1" + } + ] + }, + { + "name": "log4j-to-slf4j", + "SPDXID": "SPDXRef-Package-java-archive-log4j-to-slf4j-860f45be6a175d16", + "versionInfo": "2.22.1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b5e67b6acac768bfec1d1d6991504f45453abcad" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-bc2074dd7e94ae9ffbcea3c53de6625b1b651c330895f46cf72d207c3025b98b", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:log4j-to-slf4j:2.22.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:log4j_to_slf4j:2.22.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:log4j:2.22.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:slf4j:2.22.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.22.1" + } + ] + }, + { + "name": "logback-classic", + "SPDXID": "SPDXRef-Package-java-archive-logback-classic-d91fe3ae6bb15cad", + "versionInfo": "1.4.14", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d98bc162275134cdf1518774da4a2a17ef6fb94d" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-b997c307e688e15a53c7603c100d346cb7dc9726146cb5644d66bddc7ed1c8ca", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback-classic:logback-classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback-classic:logback_classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback_classic:logback-classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback_classic:logback_classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback:logback-classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback:logback_classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:qos-ch:logback-classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:qos-ch:logback_classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:qos_ch:logback-classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:qos_ch:logback_classic:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/ch.qos.logback/logback-classic@1.4.14" + } + ] + }, + { + "name": "logback-core", + "SPDXID": "SPDXRef-Package-java-archive-logback-core-3748310e1aac44ea", + "versionInfo": "1.4.14", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "4d3c2248219ac0effeb380ed4c5280a80bf395e8" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-b997c307e688e15a53c7603c100d346cb7dc9726146cb5644d66bddc7ed1c8ca", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback-core:logback-core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback-core:logback_core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback_core:logback-core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback_core:logback_core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback:logback-core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:logback:logback_core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:qos-ch:logback-core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:qos-ch:logback_core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:qos_ch:logback-core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:qos_ch:logback_core:1.4.14:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/ch.qos.logback/logback-core@1.4.14" + } + ] + }, + { + "name": "micrometer-commons", + "SPDXID": "SPDXRef-Package-java-archive-micrometer-commons-c46f369578c77c43", + "versionInfo": "1.13.0-M1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "e738daf6678eedf8e0c40a782bdb0df064a391e5" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer-commons:micrometer-commons:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer-commons:micrometer_commons:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer_commons:micrometer-commons:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer_commons:micrometer_commons:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer:micrometer-commons:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer:micrometer_commons:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/io.micrometer/micrometer-commons@1.13.0-M1" + } + ] + }, + { + "name": "micrometer-core", + "SPDXID": "SPDXRef-Package-java-archive-micrometer-core-3c0d8567351e2ae4", + "versionInfo": "1.13.0-M1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "49d54a8ed6d3266b4f2691027d95144e946bbe36" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer-core:micrometer-core:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer-core:micrometer_core:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer_core:micrometer-core:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer_core:micrometer_core:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer:micrometer-core:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer:micrometer_core:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/io.micrometer/micrometer-core@1.13.0-M1" + } + ] + }, + { + "name": "micrometer-jakarta9", + "SPDXID": "SPDXRef-Package-java-archive-micrometer-jakarta9-f4ea2c844b65a026", + "versionInfo": "1.13.0-M1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "74087b670cad9f9883228ee2aa871f51b53f827a" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer-jakarta9:micrometer-jakarta9:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer-jakarta9:micrometer_jakarta9:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer_jakarta9:micrometer-jakarta9:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer_jakarta9:micrometer_jakarta9:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer:micrometer-jakarta9:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer:micrometer_jakarta9:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/io.micrometer/micrometer-jakarta9@1.13.0-M1" + } + ] + }, + { + "name": "micrometer-observation", + "SPDXID": "SPDXRef-Package-java-archive-micrometer-observation-26b8a84479010ca8", + "versionInfo": "1.13.0-M1", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "c06e5e0f9b6edc9c0c0ac3dd46a2117ce6f16a9d" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer-observation:micrometer-observation:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer-observation:micrometer_observation:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer_observation:micrometer-observation:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer_observation:micrometer_observation:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer:micrometer-observation:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:micrometer:micrometer_observation:1.13.0-M1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/io.micrometer/micrometer-observation@1.13.0-M1" + } + ] + }, + { + "name": "sbom-test-gradle", + "SPDXID": "SPDXRef-Package-java-archive-sbom-test-gradle-93ed082a147d9796", + "versionInfo": "0.0.1-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "8ccd6688e9d8e15d18e0f10967867e5e30729a4c" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test-gradle:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test-gradle:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test_gradle:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test_gradle:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:JarLauncher:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:JarLauncher:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test-gradle:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test_gradle:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:JarLauncher:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:launch:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:launch:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:loader:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:loader:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test-gradle:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test-gradle:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test_gradle:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test_gradle:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test-gradle:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test_gradle:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:JarLauncher:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:JarLauncher:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:launch:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:loader:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:JarLauncher:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom-test:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom_test:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:launch:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:launch:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:loader:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:loader:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:launch:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:loader:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:sbom:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework.boot.loader.launch.JarLauncher/sbom-test-gradle@0.0.1-SNAPSHOT" + } + ] + }, + { + "name": "slf4j-api", + "SPDXID": "SPDXRef-Package-java-archive-slf4j-api-44752cfa6770756d", + "versionInfo": "2.0.11", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "ad96c3f8cf895e696dd35c2bc8e8ebe710be9e6d" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-http---www.opensource.org-licenses-mit-license.php", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:slf4j-api:slf4j-api:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:slf4j-api:slf4j_api:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:slf4j_api:slf4j-api:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:slf4j_api:slf4j_api:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:slf4j:slf4j-api:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:slf4j:slf4j_api:2.0.11:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.slf4j/slf4j-api@2.0.11" + } + ] + }, + { + "name": "snakeyaml", + "SPDXID": "SPDXRef-Package-java-archive-snakeyaml-f4585c65c0a5b26a", + "versionInfo": "2.2", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "3af797a25458550a16bf89acc8e4ab2b7f2bfce0" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-http---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:snakeyaml:snakeyaml:2.2:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:yaml:snakeyaml:2.2:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.yaml/snakeyaml@2.2" + } + ] + }, + { + "name": "spring-aop", + "SPDXID": "SPDXRef-Package-java-archive-spring-aop-1e7758a78bbc15ee", + "versionInfo": "6.1.4-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b02165904562fc487cde57ca75e063561d905f74" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0 AND BSD-3-Clause", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-aop:spring-aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-aop:spring_aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_aop:spring-aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_aop:spring_aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework/spring-aop@6.1.4-SNAPSHOT" + } + ] + }, + { + "name": "spring-beans", + "SPDXID": "SPDXRef-Package-java-archive-spring-beans-bb7e773a923726bb", + "versionInfo": "6.1.4-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "fa8be0f856958fdd33eef9e718b3a65f7130bbd2" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0 AND BSD-3-Clause", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-beans:spring-beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-beans:spring_beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_beans:spring-beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_beans:spring_beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework/spring-beans@6.1.4-SNAPSHOT" + } + ] + }, + { + "name": "spring-boot", + "SPDXID": "SPDXRef-Package-java-archive-spring-boot-a11948291446c2f5", + "versionInfo": "3.3.0-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d882660ea3deafe921faba8b17e7d94ef9556c47" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework.boot/spring-boot@3.3.0-SNAPSHOT" + } + ] + }, + { + "name": "spring-boot-actuator", + "SPDXID": "SPDXRef-Package-java-archive-spring-boot-actuator-f83d629168e25cce", + "versionInfo": "3.3.0-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d0d018780795da57afa8edae7436646bccd55722" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework.boot/spring-boot-actuator@3.3.0-SNAPSHOT" + } + ] + }, + { + "name": "spring-boot-actuator-autoconfigure", + "SPDXID": "SPDXRef-Package-java-archive-spring-boot-actuator-autoconfigure-b8eb893518786bb8", + "versionInfo": "3.3.0-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "8b8f74be822e6f2ab120ea0687acf629ef114399" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator-autoconfigure:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator-autoconfigure:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator_autoconfigure:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator_autoconfigure:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator-autoconfigure:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator_autoconfigure:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-actuator:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_actuator:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.3.0-SNAPSHOT" + } + ] + }, + { + "name": "spring-boot-autoconfigure", + "SPDXID": "SPDXRef-Package-java-archive-spring-boot-autoconfigure-b40bdc90eb8832a3", + "versionInfo": "3.3.0-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "31a960bb63af836f35760077af8ef58d24b548e3" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-autoconfigure:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-autoconfigure:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_autoconfigure:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_autoconfigure:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-autoconfigure:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_autoconfigure:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.3.0-SNAPSHOT" + } + ] + }, + { + "name": "spring-boot-jarmode-layertools", + "SPDXID": "SPDXRef-Package-java-archive-spring-boot-jarmode-layertools-8069f3f866b2e657", + "versionInfo": "3.3.0-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d86f1782ad3d9ee047863a5023aaa22f858cd9a4" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-jarmode-layertools:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-jarmode-layertools:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_jarmode_layertools:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_jarmode_layertools:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-jarmode:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-jarmode:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_jarmode:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_jarmode:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-jarmode-layertools:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_jarmode_layertools:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot-jarmode:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot_jarmode:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework.boot/spring-boot-jarmode-layertools@3.3.0-SNAPSHOT" + } + ] + }, + { + "name": "spring-context", + "SPDXID": "SPDXRef-Package-java-archive-spring-context-3d5d71e0e85398af", + "versionInfo": "6.1.4-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "75440f70a649ca15948af5923ebdef345848a856" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0 AND BSD-3-Clause", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-context:spring-context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-context:spring_context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_context:spring-context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_context:spring_context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework/spring-context@6.1.4-SNAPSHOT" + } + ] + }, + { + "name": "spring-core", + "SPDXID": "SPDXRef-Package-java-archive-spring-core-519fe54307d2d43d", + "versionInfo": "6.1.4-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "27d0900a14e240a7311c979e7b30cf65f9de9074" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0 AND BSD-3-Clause", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource-spring-framework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource_spring_framework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource-spring:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource_spring:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:pivotal_software:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-framework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_framework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource-spring-framework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource_spring_framework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-core:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_core:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource-spring-framework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource-spring-framework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource_spring_framework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource_spring_framework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource-spring:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource_spring:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:vmware:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:pivotal_software:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-framework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_framework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource-spring:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource-spring:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource_spring:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource_spring:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:pivotal_software:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:pivotal_software:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-core:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-framework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-framework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_core:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_framework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_framework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springsource:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-core:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-core:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_core:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_core:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:vmware:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:vmware:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:vmware:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework/spring-core@6.1.4-SNAPSHOT" + } + ] + }, + { + "name": "spring-expression", + "SPDXID": "SPDXRef-Package-java-archive-spring-expression-546794e924e39088", + "versionInfo": "6.1.4-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "a5d7041ca11fd188e9d17ac8a795eabed8be55e4" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0 AND BSD-3-Clause", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-expression:spring-expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-expression:spring_expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_expression:spring-expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_expression:spring_expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework/spring-expression@6.1.4-SNAPSHOT" + } + ] + }, + { + "name": "spring-jcl", + "SPDXID": "SPDXRef-Package-java-archive-spring-jcl-173ea637a5756944", + "versionInfo": "6.1.4-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "604cea28d23d8027a31c35f372d2b8d0fdec211d" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0 AND BSD-3-Clause", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-jcl:spring-jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-jcl:spring_jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_jcl:spring-jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_jcl:spring_jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework/spring-jcl@6.1.4-SNAPSHOT" + } + ] + }, + { + "name": "spring-web", + "SPDXID": "SPDXRef-Package-java-archive-spring-web-adc63cefcede34fc", + "versionInfo": "6.1.4-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "c0600dcd73db226c3d121af16d6a155ecee08d30" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0 AND BSD-3-Clause", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-web:spring-web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-web:spring_web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_web:spring-web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_web:spring_web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework/spring-web@6.1.4-SNAPSHOT" + } + ] + }, + { + "name": "spring-webmvc", + "SPDXID": "SPDXRef-Package-java-archive-spring-webmvc-940aed7082581b67", + "versionInfo": "6.1.4-SNAPSHOT", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "34a510cf565bec1c2f74f049b1730b22f877bd37" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "Apache-2.0 AND BSD-3-Clause", + "licenseDeclared": "NOASSERTION", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring-webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:springframework:spring_webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-webmvc:spring-webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring-webmvc:spring_webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_webmvc:spring-webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring_webmvc:spring_webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring-webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:spring:spring_webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.springframework/spring-webmvc@6.1.4-SNAPSHOT" + } + ] + }, + { + "name": "tomcat-embed-core", + "SPDXID": "SPDXRef-Package-java-archive-tomcat-embed-core-a753aca6ee68c738", + "versionInfo": "10.1.18", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "bff6c34649d1dd7b509e819794d73ba795947dcf" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-https---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat-embed-core:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat_embed_core:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:embed:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.18" + } + ] + }, + { + "name": "tomcat-embed-el", + "SPDXID": "SPDXRef-Package-java-archive-tomcat-embed-el-7a59d22722f7701b", + "versionInfo": "10.1.18", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b2c4dc05abd363c63b245523bb071727aa2f1046" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-https---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat-embed-el:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat_embed_el:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:embed:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.18" + } + ] + }, + { + "name": "tomcat-embed-websocket", + "SPDXID": "SPDXRef-Package-java-archive-tomcat-embed-websocket-6c04f8ee22f9157e", + "versionInfo": "10.1.18", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "83a3bc6898f2ceed2357ba231a5e83dc2016d454" + } + ], + "sourceInfo": "acquired package info from installed java archive: /sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "licenseConcluded": "NOASSERTION", + "licenseDeclared": "LicenseRef-https---www.apache.org-licenses-LICENSE-2.0.txt", + "copyrightText": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat-embed-websocket:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat_embed_websocket:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:tomcat:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:apache:embed:10.1.18:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.18" + } + ] + }, + { + "name": "sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "SPDXID": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "versionInfo": "sha256:f1802eb27e84114cfd7213ec83534a4b3219da6c4b2dcc827e0130b69ffa63b9", + "supplier": "NOASSERTION", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "f1802eb27e84114cfd7213ec83534a4b3219da6c4b2dcc827e0130b69ffa63b9" + } + ], + "primaryPackagePurpose": "FILE" + } + ], + "files": [ + { + "fileName": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "SPDXID": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "0000000000000000000000000000000000000000" + } + ], + "licenseConcluded": "NOASSERTION", + "copyrightText": "" + } + ], + "hasExtractedLicensingInfos": [ + { + "licenseId": "LicenseRef-85a9a90b97292e5203565dd71a1a086ca3fe4d8ccea74453294fee37d5b0c7ae", + "extractedText": "http://www.eclipse.org/legal/epl-2.0, https://www.gnu.org/software/classpath/license.html" + }, + { + "licenseId": "LicenseRef-Public-Domain--per-Creative-Commons-CC0", + "extractedText": "Public Domain, per Creative Commons CC0" + }, + { + "licenseId": "LicenseRef-b997c307e688e15a53c7603c100d346cb7dc9726146cb5644d66bddc7ed1c8ca", + "extractedText": "http://www.eclipse.org/legal/epl-v10.html, http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" + }, + { + "licenseId": "LicenseRef-bc2074dd7e94ae9ffbcea3c53de6625b1b651c330895f46cf72d207c3025b98b", + "extractedText": "\"Apache-2.0\";link=\"https://www.apache.org/licenses/LICENSE-2.0.txt\"" + }, + { + "licenseId": "LicenseRef-d509473237fa971bc0a8ad7708f3cd561fcf86ef2e611701ed8eec621fd6575e", + "extractedText": "http://creativecommons.org/publicdomain/zero/1.0/, https://opensource.org/licenses/BSD-2-Clause" + }, + { + "licenseId": "LicenseRef-http---www.apache.org-licenses-LICENSE-2.0.txt", + "extractedText": "http://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "licenseId": "LicenseRef-http---www.opensource.org-licenses-mit-license.php", + "extractedText": "http://www.opensource.org/licenses/mit-license.php" + }, + { + "licenseId": "LicenseRef-https---www.apache.org-licenses-LICENSE-2.0.txt", + "extractedText": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-Package-java-archive-jackson-core-0408f25059f495c5", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-jackson-datatype-jsr310-1347581c05f302c0", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-jcl-173ea637a5756944", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-aop-1e7758a78bbc15ee", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-micrometer-observation-26b8a84479010ca8", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-HdrHistogram-2c7953c2c68ec3bc", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-logback-core-3748310e1aac44ea", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-micrometer-core-3c0d8567351e2ae4", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-context-3d5d71e0e85398af", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-slf4j-api-44752cfa6770756d", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-core-519fe54307d2d43d", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-expression-546794e924e39088", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-jul-to-slf4j-598311f4a5b2a501", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-tomcat-embed-websocket-6c04f8ee22f9157e", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-jakarta.annotation-api-77a5bf527533d628", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-tomcat-embed-el-7a59d22722f7701b", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-boot-jarmode-layertools-8069f3f866b2e657", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-jackson-datatype-jdk8-846731ed2e85561c", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-log4j-to-slf4j-860f45be6a175d16", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-sbom-test-gradle-93ed082a147d9796", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-webmvc-940aed7082581b67", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-jackson-databind-9ad3756f611d1ed2", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-boot-a11948291446c2f5", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-tomcat-embed-core-a753aca6ee68c738", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-web-adc63cefcede34fc", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-boot-autoconfigure-b40bdc90eb8832a3", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-boot-actuator-autoconfigure-b8eb893518786bb8", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-beans-bb7e773a923726bb", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-jackson-annotations-c1e7975b6f55f7e8", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-log4j-api-c404b33d3a8ce0d8", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-micrometer-commons-c46f369578c77c43", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-logback-classic-d91fe3ae6bb15cad", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-snakeyaml-f4585c65c0a5b26a", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-micrometer-jakarta9-f4ea2c844b65a026", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-jackson-module-parameter-names-f5bca9d628ab321f", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-spring-boot-actuator-f83d629168e25cce", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-Package-java-archive-LatencyUtils-f9418986cc24a153", + "relatedSpdxElement": "SPDXRef-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar-af7261c65fbd5345", + "relationshipType": "OTHER", + "comment": "evident-by: indicates the package's existence is evident by the given file" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-HdrHistogram-2c7953c2c68ec3bc", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-LatencyUtils-f9418986cc24a153", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-jackson-annotations-c1e7975b6f55f7e8", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-jackson-core-0408f25059f495c5", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-jackson-databind-9ad3756f611d1ed2", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-jackson-datatype-jdk8-846731ed2e85561c", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-jackson-datatype-jsr310-1347581c05f302c0", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-jackson-module-parameter-names-f5bca9d628ab321f", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-jakarta.annotation-api-77a5bf527533d628", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-jul-to-slf4j-598311f4a5b2a501", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-log4j-api-c404b33d3a8ce0d8", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-log4j-to-slf4j-860f45be6a175d16", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-logback-classic-d91fe3ae6bb15cad", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-logback-core-3748310e1aac44ea", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-micrometer-commons-c46f369578c77c43", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-micrometer-core-3c0d8567351e2ae4", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-micrometer-jakarta9-f4ea2c844b65a026", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-micrometer-observation-26b8a84479010ca8", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-sbom-test-gradle-93ed082a147d9796", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-slf4j-api-44752cfa6770756d", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-snakeyaml-f4585c65c0a5b26a", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-aop-1e7758a78bbc15ee", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-beans-bb7e773a923726bb", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-boot-a11948291446c2f5", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-boot-actuator-f83d629168e25cce", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-boot-actuator-autoconfigure-b8eb893518786bb8", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-boot-autoconfigure-b40bdc90eb8832a3", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-boot-jarmode-layertools-8069f3f866b2e657", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-context-3d5d71e0e85398af", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-core-519fe54307d2d43d", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-expression-546794e924e39088", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-jcl-173ea637a5756944", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-web-adc63cefcede34fc", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-spring-webmvc-940aed7082581b67", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-tomcat-embed-core-a753aca6ee68c738", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-tomcat-embed-el-7a59d22722f7701b", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relatedSpdxElement": "SPDXRef-Package-java-archive-tomcat-embed-websocket-6c04f8ee22f9157e", + "relationshipType": "CONTAINS" + }, + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-DocumentRoot-File-sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "relationshipType": "DESCRIBES" + } + ] +} diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/syft.json b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/syft.json new file mode 100644 index 000000000000..526964e360a0 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-integration-tests/src/test/resources/org/springframework/boot/actuate/sbom/syft.json @@ -0,0 +1,7525 @@ +{ + "artifacts": [ + { + "id": "2c7953c2c68ec3bc", + "name": "HdrHistogram", + "version": "2.1.12", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/HdrHistogram-2.1.12.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://creativecommons.org/publicdomain/zero/1.0/, https://opensource.org/licenses/BSD-2-Clause", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/HdrHistogram-2.1.12.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:HdrHistogram:HdrHistogram:2.1.12:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:hdrhistogram:HdrHistogram:2.1.12:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.hdrhistogram/HdrHistogram@2.1.12", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/HdrHistogram-2.1.12.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bnd-LastModified", + "value": "1575980548657" + }, + { + "key": "Build-Jdk", + "value": "1.8.0_232" + }, + { + "key": "Built-By", + "value": "gil" + }, + { + "key": "Bundle-Description", + "value": "HdrHistogram supports the recording and analyzing sampled data value counts across a configurable integer value range with configurable value precision within the range. Value precision is expressed as the number of significant digits in the value recording, and provides control over value quantization behavior across the value range and the subsequent value resolutionat any given level." + }, + { + "key": "Bundle-License", + "value": "http://creativecommons.org/publicdomain/zero/1.0/, https://opensource.org/licenses/BSD-2-Clause" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "HdrHistogram" + }, + { + "key": "Bundle-SymbolicName", + "value": "org.hdrhistogram.HdrHistogram" + }, + { + "key": "Bundle-Version", + "value": "2.1.12" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin" + }, + { + "key": "Export-Package", + "value": "org.HdrHistogram;version=\"2.1.12\",org.HdrHistogram.packedarray;version=\"2.1.12\"" + }, + { + "key": "Implementation-Title", + "value": "HdrHistogram" + }, + { + "key": "Implementation-Vendor-Id", + "value": "org.hdrhistogram" + }, + { + "key": "Implementation-Version", + "value": "2.1.12" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.7))\"" + }, + { + "key": "Specification-Title", + "value": "HdrHistogram" + }, + { + "key": "Specification-Version", + "value": "2.1.12" + }, + { + "key": "Tool", + "value": "Bnd-2.3.0.201405100607" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/org.hdrhistogram/HdrHistogram/pom.properties", + "name": "", + "groupId": "org.hdrhistogram", + "artifactId": "HdrHistogram", + "version": "2.1.12" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "6eb7552156e0d517ae80cc2247be1427c8d90452" + } + ] + } + }, + { + "id": "f9418986cc24a153", + "name": "LatencyUtils", + "version": "2.0.3", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/LatencyUtils-2.0.3.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Public Domain, per Creative Commons CC0", + "spdxExpression": "", + "type": "declared", + "urls": [ + "http://creativecommons.org/publicdomain/zero/1.0/" + ], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/LatencyUtils-2.0.3.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:LatencyUtils:LatencyUtils:2.0.3:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:latencyutils:LatencyUtils:2.0.3:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.latencyutils/LatencyUtils@2.0.3", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/LatencyUtils-2.0.3.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Archiver-Version", + "value": "Plexus Archiver" + }, + { + "key": "Built-By", + "value": "gil" + }, + { + "key": "Created-By", + "value": "Apache Maven 3.2.3" + }, + { + "key": "Build-Jdk", + "value": "1.8.0_45" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/org.latencyutils/LatencyUtils/pom.properties", + "name": "", + "groupId": "org.latencyutils", + "artifactId": "LatencyUtils", + "version": "2.0.3" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "769c0b82cb2421c8256300e907298a9410a2a3d3" + } + ] + } + }, + { + "id": "c1e7975b6f55f7e8", + "name": "jackson-annotations", + "version": "2.16.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-annotations-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-annotations-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:jackson-annotations:jackson-annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-annotations:jackson_annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_annotations:jackson-annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_annotations:jackson_annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson-annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson_annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-annotations:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson-annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson_annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_annotations:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson-annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson_annotations:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.16.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-annotations-2.16.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-Description", + "value": "Core annotations used for value types, used by Jackson data binding package." + }, + { + "key": "Implementation-Title", + "value": "Jackson-annotations" + }, + { + "key": "Bundle-License", + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-SymbolicName", + "value": "com.fasterxml.jackson.core.jackson-annotations" + }, + { + "key": "Implementation-Version", + "value": "2.16.1" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Specification-Vendor", + "value": "FasterXML" + }, + { + "key": "Implementation-Vendor-Id", + "value": "com.fasterxml.jackson.core" + }, + { + "key": "Specification-Title", + "value": "Jackson-annotations" + }, + { + "key": "Bundle-DocURL", + "value": "https://github.com/FasterXML/jackson" + }, + { + "key": "Bundle-Vendor", + "value": "FasterXML" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.6))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + }, + { + "key": "Implementation-Vendor", + "value": "FasterXML" + }, + { + "key": "Export-Package", + "value": "com.fasterxml.jackson.annotation;version=\"2.16.1\"" + }, + { + "key": "Bundle-Name", + "value": "Jackson-annotations" + }, + { + "key": "Bundle-Version", + "value": "2.16.1" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.6" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.6" + }, + { + "key": "Build-Jdk-Spec", + "value": "1.8" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.9" + }, + { + "key": "Specification-Version", + "value": "2.16.1" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/com.fasterxml.jackson.core/jackson-annotations/pom.properties", + "name": "", + "groupId": "com.fasterxml.jackson.core", + "artifactId": "jackson-annotations", + "version": "2.16.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "fd441d574a71e7d10a4f73de6609f881d8cdfeec" + } + ] + } + }, + { + "id": "0408f25059f495c5", + "name": "jackson-core", + "version": "2.16.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-core-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-core-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:jackson-core:jackson-core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-core:jackson_core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_core:jackson-core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_core:jackson_core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson-core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson_core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-core:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson-core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson_core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_core:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson-core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson_core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-core:core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_core:core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:core:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.16.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-core-2.16.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-License", + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-SymbolicName", + "value": "com.fasterxml.jackson.core.jackson-core" + }, + { + "key": "Implementation-Vendor-Id", + "value": "com.fasterxml.jackson.core" + }, + { + "key": "Specification-Title", + "value": "Jackson-core" + }, + { + "key": "Bundle-DocURL", + "value": "https://github.com/FasterXML/jackson-core" + }, + { + "key": "Import-Package", + "value": "com.fasterxml.jackson.core;version=\"[2.16,3)\",com.fasterxml.jackson.core.async;version=\"[2.16,3)\",com.fasterxml.jackson.core.base;version=\"[2.16,3)\",com.fasterxml.jackson.core.exc;version=\"[2.16,3)\",com.fasterxml.jackson.core.format;version=\"[2.16,3)\",com.fasterxml.jackson.core.io;version=\"[2.16,3)\",com.fasterxml.jackson.core.io.schubfach;version=\"[2.16,3)\",com.fasterxml.jackson.core.json;version=\"[2.16,3)\",com.fasterxml.jackson.core.json.async;version=\"[2.16,3)\",com.fasterxml.jackson.core.sym;version=\"[2.16,3)\",com.fasterxml.jackson.core.type;version=\"[2.16,3)\",com.fasterxml.jackson.core.util;version=\"[2.16,3)\"" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Export-Package", + "value": "com.fasterxml.jackson.core;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core.async,com.fasterxml.jackson.core.exc,com.fasterxml.jackson.core.format,com.fasterxml.jackson.core.io,com.fasterxml.jackson.core.json,com.fasterxml.jackson.core.sym,com.fasterxml.jackson.core.type,com.fasterxml.jackson.core.util\",com.fasterxml.jackson.core.async;version=\"2.16.1\",com.fasterxml.jackson.core.base;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.exc,com.fasterxml.jackson.core.io,com.fasterxml.jackson.core.json,com.fasterxml.jackson.core.util\",com.fasterxml.jackson.core.exc;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.util\",com.fasterxml.jackson.core.filter;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.util\",com.fasterxml.jackson.core.format;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core\",com.fasterxml.jackson.core.io;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.util\",com.fasterxml.jackson.core.io.schubfach;version=\"2.16.1\",com.fasterxml.jackson.core.json;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.base,com.fasterxml.jackson.core.format,com.fasterxml.jackson.core.io,com.fasterxml.jackson.core.sym,com.fasterxml.jackson.core.util\",com.fasterxml.jackson.core.json.async;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.async,com.fasterxml.jackson.core.base,com.fasterxml.jackson.core.exc,com.fasterxml.jackson.core.io,com.fasterxml.jackson.core.sym,com.fasterxml.jackson.core.util\",com.fasterxml.jackson.core.sym;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.exc,com.fasterxml.jackson.core.util\",com.fasterxml.jackson.core.type;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core\",com.fasterxml.jackson.core.util;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.async,com.fasterxml.jackson.core.exc,com.fasterxml.jackson.core.io\"" + }, + { + "key": "Bundle-Name", + "value": "Jackson-core" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Build-Jdk-Spec", + "value": "1.8" + }, + { + "key": "Bundle-Description", + "value": "Core Jackson processing abstractions (aka Streaming API), implementation for JSON" + }, + { + "key": "Implementation-Title", + "value": "Jackson-core" + }, + { + "key": "Implementation-Version", + "value": "2.16.1" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Specification-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Vendor", + "value": "FasterXML" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + }, + { + "key": "Implementation-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Version", + "value": "2.16.1" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.9" + }, + { + "key": "Specification-Version", + "value": "2.16.1" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/com.fasterxml.jackson.core/jackson-core/pom.properties", + "name": "", + "groupId": "com.fasterxml.jackson.core", + "artifactId": "jackson-core", + "version": "2.16.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "9456bb3cdd0f79f91a5f730a1b1bb041a380c91f" + } + ] + } + }, + { + "id": "9ad3756f611d1ed2", + "name": "jackson-databind", + "version": "2.16.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-databind-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-databind-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:jackson-databind:jackson-databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-databind:jackson_databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_databind:jackson-databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_databind:jackson_databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson-databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson_databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-databind:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson-databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson_databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_databind:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson-databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson_databind:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:core:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.16.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-databind-2.16.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-License", + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-SymbolicName", + "value": "com.fasterxml.jackson.core.jackson-databind" + }, + { + "key": "Implementation-Vendor-Id", + "value": "com.fasterxml.jackson.core" + }, + { + "key": "Specification-Title", + "value": "jackson-databind" + }, + { + "key": "Bundle-DocURL", + "value": "https://github.com/FasterXML/jackson" + }, + { + "key": "Import-Package", + "value": "com.fasterxml.jackson.annotation;version=\"[2.16,3)\",com.fasterxml.jackson.core;version=\"[2.16,3)\",com.fasterxml.jackson.core.base;version=\"[2.16,3)\",com.fasterxml.jackson.core.exc;version=\"[2.16,3)\",com.fasterxml.jackson.core.filter;version=\"[2.16,3)\",com.fasterxml.jackson.core.format;version=\"[2.16,3)\",com.fasterxml.jackson.core.io;version=\"[2.16,3)\",com.fasterxml.jackson.core.json;version=\"[2.16,3)\",com.fasterxml.jackson.core.type;version=\"[2.16,3)\",com.fasterxml.jackson.core.util;version=\"[2.16,3)\",com.fasterxml.jackson.databind;version=\"[2.16,3)\",com.fasterxml.jackson.databind.annotation;version=\"[2.16,3)\",com.fasterxml.jackson.databind.cfg;version=\"[2.16,3)\",com.fasterxml.jackson.databind.deser;version=\"[2.16,3)\",com.fasterxml.jackson.databind.deser.impl;version=\"[2.16,3)\",com.fasterxml.jackson.databind.deser.std;version=\"[2.16,3)\",com.fasterxml.jackson.databind.exc;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ext;version=\"[2.16,3)\",com.fasterxml.jackson.databind.introspect;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jdk14;version=\"[2.16,3)\",com.fasterxml.jackson.databind.json;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jsonFormatVisitors;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jsonschema;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jsontype;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jsontype.impl;version=\"[2.16,3)\",com.fasterxml.jackson.databind.node;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ser;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ser.impl;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ser.std;version=\"[2.16,3)\",com.fasterxml.jackson.databind.type;version=\"[2.16,3)\",com.fasterxml.jackson.databind.util;version=\"[2.16,3)\",com.fasterxml.jackson.databind.util.internal;version=\"[2.16,3)\",javax.xml.datatype,javax.xml.namespace,javax.xml.parsers,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.stream,org.w3c.dom,org.xml.sax,org.w3c.dom.bootstrap;resolution:=optional" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Export-Package", + "value": "com.fasterxml.jackson.databind;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.exc,com.fasterxml.jackson.core.filter,com.fasterxml.jackson.core.format,com.fasterxml.jackson.core.io,com.fasterxml.jackson.core.type,com.fasterxml.jackson.core.util,com.fasterxml.jackson.databind.annotation,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.deser.impl,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsonFormatVisitors,com.fasterxml.jackson.databind.jsonschema,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.jsontype.impl,com.fasterxml.jackson.databind.node,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.ser.impl,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.annotation;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.cfg;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.type,com.fasterxml.jackson.core.util,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.node,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.deser;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.format,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.annotation,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.deser.impl,com.fasterxml.jackson.databind.deser.std,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsonFormatVisitors,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.node,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.deser.impl;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.deser.std,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.deser.std;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.annotation,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.deser.impl,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.exc;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.introspect\",com.fasterxml.jackson.databind.ext;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.annotation,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.deser.std,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsonFormatVisitors,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.ser.std,javax.xml.datatype,javax.xml.parsers,javax.xml.transform,org.w3c.dom\",com.fasterxml.jackson.databind.introspect;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.annotation,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.jsontype.impl,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.jdk14;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.introspect\",com.fasterxml.jackson.databind.json;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.json,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.cfg\",com.fasterxml.jackson.databind.jsonFormatVisitors;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.databind\",com.fasterxml.jackson.databind.jsonschema;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.node\",com.fasterxml.jackson.databind.jsontype;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.type,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.introspect\",com.fasterxml.jackson.databind.jsontype.impl;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.type,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.module;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.type\",com.fasterxml.jackson.databind.node;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.base,com.fasterxml.jackson.core.util,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.ser;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.io,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.annotation,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsonFormatVisitors,com.fasterxml.jackson.databind.jsonschema,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.node,com.fasterxml.jackson.databind.ser.impl,com.fasterxml.jackson.databind.ser.std,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.ser.impl;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.io,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.annotation,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsonFormatVisitors,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.node,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.ser.std,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.ser.std;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.type,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.annotation,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsonFormatVisitors,com.fasterxml.jackson.databind.jsonschema,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.node,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.ser.impl,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.type;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.type,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.util\",com.fasterxml.jackson.databind.util;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.base,com.fasterxml.jackson.core.io,com.fasterxml.jackson.core.json,com.fasterxml.jackson.core.util,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util.internal\",com.fasterxml.jackson.databind.util.internal;version=\"2.16.1\"" + }, + { + "key": "Bundle-Name", + "value": "jackson-databind" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Build-Jdk-Spec", + "value": "1.8" + }, + { + "key": "Bundle-Description", + "value": "General data-binding functionality for Jackson: works on core streaming API" + }, + { + "key": "Implementation-Title", + "value": "jackson-databind" + }, + { + "key": "Implementation-Version", + "value": "2.16.1" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Specification-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Vendor", + "value": "FasterXML" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + }, + { + "key": "Implementation-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Version", + "value": "2.16.1" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.9" + }, + { + "key": "Specification-Version", + "value": "2.16.1" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/com.fasterxml.jackson.core/jackson-databind/pom.properties", + "name": "", + "groupId": "com.fasterxml.jackson.core", + "artifactId": "jackson-databind", + "version": "2.16.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "02a16efeb840c45af1e2f31753dfe76795278b73" + } + ] + } + }, + { + "id": "846731ed2e85561c", + "name": "jackson-datatype-jdk8", + "version": "2.16.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-datatype-jdk8-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-datatype-jdk8-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:jackson-datatype-jdk8:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype-jdk8:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype_jdk8:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype_jdk8:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:datatype:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:datatype:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype-jdk8:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson-datatype-jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson_datatype_jdk8:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype_jdk8:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:datatype:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8@2.16.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-datatype-jdk8-2.16.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-License", + "value": "http://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-SymbolicName", + "value": "com.fasterxml.jackson.datatype.jackson-datatype-jdk8" + }, + { + "key": "Implementation-Vendor-Id", + "value": "com.fasterxml.jackson.datatype" + }, + { + "key": "Specification-Title", + "value": "Jackson datatype: jdk8" + }, + { + "key": "Bundle-DocURL", + "value": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8" + }, + { + "key": "Import-Package", + "value": "com.fasterxml.jackson.core;version=\"[2.16,3)\",com.fasterxml.jackson.core.io;version=\"[2.16,3)\",com.fasterxml.jackson.core.util;version=\"[2.16,3)\",com.fasterxml.jackson.databind;version=\"[2.16,3)\",com.fasterxml.jackson.databind.cfg;version=\"[2.16,3)\",com.fasterxml.jackson.databind.deser;version=\"[2.16,3)\",com.fasterxml.jackson.databind.deser.std;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jsonFormatVisitors;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jsontype;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ser;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ser.impl;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ser.std;version=\"[2.16,3)\",com.fasterxml.jackson.databind.type;version=\"[2.16,3)\",com.fasterxml.jackson.databind.util;version=\"[2.16,3)\"" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Export-Package", + "value": "com.fasterxml.jackson.datatype.jdk8;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.io,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.deser.std,com.fasterxml.jackson.databind.jsonFormatVisitors,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.ser,com.fasterxml.jackson.databind.ser.impl,com.fasterxml.jackson.databind.ser.std,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.databind.util\"" + }, + { + "key": "Bundle-Name", + "value": "Jackson datatype: jdk8" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Build-Jdk-Spec", + "value": "1.8" + }, + { + "key": "Bundle-Description", + "value": "Add-on module for Jackson (http://jackson.codehaus.org) to supportJDK 8 data types." + }, + { + "key": "Implementation-Title", + "value": "Jackson datatype: jdk8" + }, + { + "key": "Implementation-Version", + "value": "2.16.1" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Specification-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Vendor", + "value": "FasterXML" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + }, + { + "key": "Implementation-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Version", + "value": "2.16.1" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.9" + }, + { + "key": "Specification-Version", + "value": "2.16.1" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/com.fasterxml.jackson.datatype/jackson-datatype-jdk8/pom.properties", + "name": "", + "groupId": "com.fasterxml.jackson.datatype", + "artifactId": "jackson-datatype-jdk8", + "version": "2.16.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "695d9b8639cfc7a42a0507708cef2366fe492a44" + } + ] + } + }, + { + "id": "1347581c05f302c0", + "name": "jackson-datatype-jsr310", + "version": "2.16.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-datatype-jsr310-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-datatype-jsr310-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:jackson-datatype-jsr310:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype-jsr310:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype_jsr310:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype_jsr310:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:datatype:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:datatype:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype-jsr310:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson-datatype-jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson_datatype_jsr310:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype_jsr310:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-datatype:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_datatype:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:datatype:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310@2.16.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-datatype-jsr310-2.16.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-License", + "value": "http://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-SymbolicName", + "value": "com.fasterxml.jackson.datatype.jackson-datatype-jsr310" + }, + { + "key": "Implementation-Vendor-Id", + "value": "com.fasterxml.jackson.datatype" + }, + { + "key": "Specification-Title", + "value": "Jackson datatype: JSR310" + }, + { + "key": "Bundle-DocURL", + "value": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310" + }, + { + "key": "Import-Package", + "value": "com.fasterxml.jackson.annotation;version=\"[2.16,3)\",com.fasterxml.jackson.core;version=\"[2.16,3)\",com.fasterxml.jackson.core.io;version=\"[2.16,3)\",com.fasterxml.jackson.core.type;version=\"[2.16,3)\",com.fasterxml.jackson.core.util;version=\"[2.16,3)\",com.fasterxml.jackson.databind;version=\"[2.16,3)\",com.fasterxml.jackson.databind.cfg;version=\"[2.16,3)\",com.fasterxml.jackson.databind.deser;version=\"[2.16,3)\",com.fasterxml.jackson.databind.deser.std;version=\"[2.16,3)\",com.fasterxml.jackson.databind.introspect;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jsonFormatVisitors;version=\"[2.16,3)\",com.fasterxml.jackson.databind.jsontype;version=\"[2.16,3)\",com.fasterxml.jackson.databind.module;version=\"[2.16,3)\",com.fasterxml.jackson.databind.node;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ser;version=\"[2.16,3)\",com.fasterxml.jackson.databind.ser.std;version=\"[2.16,3)\",com.fasterxml.jackson.databind.type;version=\"[2.16,3)\",com.fasterxml.jackson.databind.util;version=\"[2.16,3)\",com.fasterxml.jackson.datatype.jsr310;version=\"[2.16,3)\",com.fasterxml.jackson.datatype.jsr310.deser;version=\"[2.16,3)\",com.fasterxml.jackson.datatype.jsr310.deser.key;version=\"[2.16,3)\",com.fasterxml.jackson.datatype.jsr310.ser;version=\"[2.16,3)\",com.fasterxml.jackson.datatype.jsr310.ser.key;version=\"[2.16,3)\",com.fasterxml.jackson.datatype.jsr310.util;version=\"[2.16,3)\"" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Export-Package", + "value": "com.fasterxml.jackson.datatype.jsr310;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.core.util,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.module\",com.fasterxml.jackson.datatype.jsr310.deser;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.core.util,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.deser,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.type,com.fasterxml.jackson.datatype.jsr310,com.fasterxml.jackson.datatype.jsr310.util\",com.fasterxml.jackson.datatype.jsr310.deser.key;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.databind\",com.fasterxml.jackson.datatype.jsr310.ser;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.jsonFormatVisitors,com.fasterxml.jackson.databind.jsontype,com.fasterxml.jackson.databind.ser.std,com.fasterxml.jackson.datatype.jsr310.util\",com.fasterxml.jackson.datatype.jsr310.ser.key;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.core,com.fasterxml.jackson.databind\",com.fasterxml.jackson.datatype.jsr310.util;version=\"2.16.1\"" + }, + { + "key": "Bundle-Name", + "value": "Jackson datatype: JSR310" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Build-Jdk-Spec", + "value": "1.8" + }, + { + "key": "Bundle-Description", + "value": "Add-on module to support JSR-310 (Java 8 Date & Time API) data types." + }, + { + "key": "Implementation-Title", + "value": "Jackson datatype: JSR310" + }, + { + "key": "Implementation-Version", + "value": "2.16.1" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Specification-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Vendor", + "value": "FasterXML" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + }, + { + "key": "Implementation-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Version", + "value": "2.16.1" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.9" + }, + { + "key": "Specification-Version", + "value": "2.16.1" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/pom.properties", + "name": "", + "groupId": "com.fasterxml.jackson.datatype", + "artifactId": "jackson-datatype-jsr310", + "version": "2.16.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "36a418325c618e440e5ccb80b75c705d894f50bd" + } + ] + } + }, + { + "id": "f5bca9d628ab321f", + "name": "jackson-module-parameter-names", + "version": "2.16.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-module-parameter-names-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-module-parameter-names-2.16.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:jackson-module-parameter-names:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-module-parameter-names:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module_parameter_names:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module_parameter_names:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-module-parameter:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-module-parameter:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module_parameter:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module_parameter:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-module:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-module:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-module-parameter-names:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module_parameter_names:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:module:jackson-module-parameter-names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:module:jackson_module_parameter_names:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-module-parameter:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module_parameter:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson-module:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson_module:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:fasterxml:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jackson:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:module:jackson:2.16.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/com.fasterxml.jackson.module/jackson-module-parameter-names@2.16.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jackson-module-parameter-names-2.16.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-License", + "value": "http://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-SymbolicName", + "value": "com.fasterxml.jackson.module.jackson-module-parameter-names" + }, + { + "key": "Implementation-Vendor-Id", + "value": "com.fasterxml.jackson.module" + }, + { + "key": "Specification-Title", + "value": "Jackson-module-parameter-names" + }, + { + "key": "Bundle-DocURL", + "value": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names" + }, + { + "key": "Import-Package", + "value": "com.fasterxml.jackson.annotation;version=\"[2.16,3)\",com.fasterxml.jackson.core;version=\"[2.16,3)\",com.fasterxml.jackson.core.util;version=\"[2.16,3)\",com.fasterxml.jackson.databind;version=\"[2.16,3)\",com.fasterxml.jackson.databind.cfg;version=\"[2.16,3)\",com.fasterxml.jackson.databind.introspect;version=\"[2.16,3)\",com.fasterxml.jackson.databind.module;version=\"[2.16,3)\"" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Export-Package", + "value": "com.fasterxml.jackson.module.paramnames;version=\"2.16.1\";uses:=\"com.fasterxml.jackson.annotation,com.fasterxml.jackson.core,com.fasterxml.jackson.databind,com.fasterxml.jackson.databind.cfg,com.fasterxml.jackson.databind.introspect,com.fasterxml.jackson.databind.module\"" + }, + { + "key": "Bundle-Name", + "value": "Jackson-module-parameter-names" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Build-Jdk-Spec", + "value": "1.8" + }, + { + "key": "Bundle-Description", + "value": "Add-on module for Jackson (http://jackson.codehaus.org) to supportintrospection of method/constructor parameter names,without having to add explicit property name annotation." + }, + { + "key": "Implementation-Title", + "value": "Jackson-module-parameter-names" + }, + { + "key": "Implementation-Version", + "value": "2.16.1" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Specification-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Vendor", + "value": "FasterXML" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + }, + { + "key": "Implementation-Vendor", + "value": "FasterXML" + }, + { + "key": "Bundle-Version", + "value": "2.16.1" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.9" + }, + { + "key": "Specification-Version", + "value": "2.16.1" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/com.fasterxml.jackson.module/jackson-module-parameter-names/pom.properties", + "name": "", + "groupId": "com.fasterxml.jackson.module", + "artifactId": "jackson-module-parameter-names", + "version": "2.16.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "9e167afd1596e6a6aa6fe4e1af17f4ce8be0676f" + } + ] + } + }, + { + "id": "77a5bf527533d628", + "name": "jakarta.annotation-api", + "version": "2.1.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jakarta.annotation-api-2.1.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.eclipse.org/legal/epl-2.0, https://www.gnu.org/software/classpath/license.html", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jakarta.annotation-api-2.1.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:jakarta.annotation-api:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jakarta.annotation-api:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jakarta.annotation_api:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jakarta.annotation_api:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:eclipse-foundation:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:eclipse-foundation:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:eclipse_foundation:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:eclipse_foundation:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jakarta.annotation:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jakarta.annotation:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:glassfish:jakarta.annotation-api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:glassfish:jakarta.annotation_api:2.1.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jakarta.annotation-api-2.1.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin" + }, + { + "key": "Build-Jdk-Spec", + "value": "11" + }, + { + "key": "Bundle-Description", + "value": "Jakarta Annotations API" + }, + { + "key": "Bundle-DocURL", + "value": "https://www.eclipse.org" + }, + { + "key": "Bundle-License", + "value": "http://www.eclipse.org/legal/epl-2.0, https://www.gnu.org/software/classpath/license.html" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "Jakarta Annotations API" + }, + { + "key": "Bundle-SymbolicName", + "value": "jakarta.annotation-api" + }, + { + "key": "Bundle-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Bundle-Version", + "value": "2.1.1" + }, + { + "key": "Export-Package", + "value": "jakarta.annotation;version=\"2.1.1\",jakarta.annotation.security;version=\"2.1.1\",jakarta.annotation.sql;version=\"2.1.1\"" + }, + { + "key": "Extension-Name", + "value": "jakarta.annotation" + }, + { + "key": "Implementation-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Implementation-Vendor-Id", + "value": "org.glassfish" + }, + { + "key": "Implementation-Version", + "value": "2.1.1" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "2.1" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/jakarta.annotation/jakarta.annotation-api/pom.properties", + "name": "", + "groupId": "jakarta.annotation", + "artifactId": "jakarta.annotation-api", + "version": "2.1.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "48b9bda22b091b1f48b13af03fe36db3be6e1ae3" + } + ] + } + }, + { + "id": "598311f4a5b2a501", + "name": "jul-to-slf4j", + "version": "2.0.11", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jul-to-slf4j-2.0.11.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.opensource.org/licenses/mit-license.php", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jul-to-slf4j-2.0.11.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:jul-to-slf4j:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul-to-slf4j:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul_to_slf4j:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul_to_slf4j:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul-to:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul-to:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul_to:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul_to:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:slf4j:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:slf4j:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul:jul-to-slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:jul:jul_to_slf4j:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.slf4j/jul-to-slf4j@2.0.11", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/jul-to-slf4j-2.0.11.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.9" + }, + { + "key": "Build-Jdk-Spec", + "value": "21" + }, + { + "key": "Bundle-Description", + "value": "JUL to SLF4J bridge" + }, + { + "key": "Bundle-DocURL", + "value": "http://www.slf4j.org" + }, + { + "key": "Bundle-License", + "value": "http://www.opensource.org/licenses/mit-license.php" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "JUL to SLF4J bridge" + }, + { + "key": "Bundle-SymbolicName", + "value": "jul.to.slf4j" + }, + { + "key": "Bundle-Vendor", + "value": "SLF4J.ORG" + }, + { + "key": "Bundle-Version", + "value": "2.0.11" + }, + { + "key": "Export-Package", + "value": "org.slf4j.bridge;uses:=\"org.slf4j,org.slf4j.spi\";version=\"2.0.11\"" + }, + { + "key": "Implementation-Title", + "value": "jul-to-slf4j" + }, + { + "key": "Implementation-Version", + "value": "2.0.11" + }, + { + "key": "Import-Package", + "value": "org.slf4j;version=\"[2.0,3)\",org.slf4j.spi;version=\"[2.0,3)\"" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + }, + { + "key": "X-Compile-Source-JDK", + "value": "8" + }, + { + "key": "X-Compile-Target-JDK", + "value": "8" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/org.slf4j/jul-to-slf4j/pom.properties", + "name": "", + "groupId": "org.slf4j", + "artifactId": "jul-to-slf4j", + "version": "2.0.11" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "279356f8e873b1a26badd8bbb3284b5c3b22c770" + } + ] + } + }, + { + "id": "c404b33d3a8ce0d8", + "name": "log4j-api", + "version": "2.22.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/log4j-api-2.22.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "\"Apache-2.0\";link=\"https://www.apache.org/licenses/LICENSE-2.0.txt\"", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/log4j-api-2.22.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:apache:log4j-api:2.22.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:log4j_api:2.22.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:log4j:2.22.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:api:2.22.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.apache.logging.log4j/log4j-api@2.22.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/log4j-api-2.22.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Created-By", + "value": "Maven JAR Plugin 3.3.0" + }, + { + "key": "Build-Jdk-Spec", + "value": "17" + }, + { + "key": "Specification-Title", + "value": "Apache Log4j API" + }, + { + "key": "Specification-Version", + "value": "2.22" + }, + { + "key": "Specification-Vendor", + "value": "The Apache Software Foundation" + }, + { + "key": "Implementation-Title", + "value": "Apache Log4j API" + }, + { + "key": "Implementation-Version", + "value": "2.22.1" + }, + { + "key": "Implementation-Vendor", + "value": "The Apache Software Foundation" + }, + { + "key": "Bundle-ActivationPolicy", + "value": "lazy" + }, + { + "key": "Bundle-Activator", + "value": "org.apache.logging.log4j.util.Activator" + }, + { + "key": "Bundle-Description", + "value": "The Apache Log4j API" + }, + { + "key": "Bundle-License", + "value": "\"Apache-2.0\";link=\"https://www.apache.org/licenses/LICENSE-2.0.txt\"" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "Apache Log4j API" + }, + { + "key": "Bundle-SymbolicName", + "value": "org.apache.logging.log4j.api" + }, + { + "key": "Bundle-Vendor", + "value": "The Apache Software Foundation" + }, + { + "key": "Bundle-Version", + "value": "2.22.1" + }, + { + "key": "Export-Package", + "value": "org.apache.logging.log4j;version=\"2.20.2\";uses:=\"org.apache.logging.log4j.message,org.apache.logging.log4j.spi,org.apache.logging.log4j.util\",org.apache.logging.log4j.message;version=\"2.22.0\";uses:=\"org.apache.logging.log4j.util\",org.apache.logging.log4j.simple;version=\"2.20.2\";uses:=\"org.apache.logging.log4j,org.apache.logging.log4j.message,org.apache.logging.log4j.spi,org.apache.logging.log4j.util\",org.apache.logging.log4j.spi;version=\"2.20.1\";uses:=\"org.apache.logging.log4j,org.apache.logging.log4j.message,org.apache.logging.log4j.util\",org.apache.logging.log4j.status;version=\"2.20.2\";uses:=\"org.apache.logging.log4j,org.apache.logging.log4j.message,org.apache.logging.log4j.spi\",org.apache.logging.log4j.util;version=\"2.22.0\";uses:=\"org.apache.logging.log4j.message,org.apache.logging.log4j.spi,org.osgi.framework\"" + }, + { + "key": "Import-Package", + "value": "org.apache.logging.log4j.simple;version=\"[2.20,3)\",org.apache.logging.log4j.status;version=\"[2.20,3)\",org.osgi.framework;version=\"[1.8,2)\",org.osgi.framework.wiring;version=\"[1.2,2)\"" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Private-Package", + "value": "org.apache.logging.log4j.internal,org.apache.logging.log4j.util.internal" + }, + { + "key": "Provide-Capability", + "value": "osgi.service;objectClass:List=\"org.apache.logging.log4j.util.PropertySource\";effective:=active,osgi.serviceloader;osgi.serviceloader=\"org.apache.logging.log4j.util.PropertySource\";register:=\"org.apache.logging.log4j.util.EnvironmentPropertySource\",osgi.serviceloader;osgi.serviceloader=\"org.apache.logging.log4j.util.PropertySource\";register:=\"org.apache.logging.log4j.util.SystemPropertiesPropertySource\"" + }, + { + "key": "Require-Capability", + "value": "osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))\";resolution:=optional,osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.registrar)(version>=1.0.0)(!(version>=2.0.0)))\";resolution:=optional,osgi.serviceloader;filter:=\"(osgi.serviceloader=org.apache.logging.log4j.message.ThreadDumpMessage$ThreadInfoFactory)\";osgi.serviceloader=\"org.apache.logging.log4j.message.ThreadDumpMessage$ThreadInfoFactory\";cardinality:=single;resolution:=optional,osgi.serviceloader;filter:=\"(osgi.serviceloader=org.apache.logging.log4j.spi.Provider)\";osgi.serviceloader=\"org.apache.logging.log4j.spi.Provider\";cardinality:=multiple;resolution:=optional,osgi.serviceloader;filter:=\"(osgi.serviceloader=org.apache.logging.log4j.util.PropertySource)\";osgi.serviceloader=\"org.apache.logging.log4j.util.PropertySource\";cardinality:=multiple;resolution:=optional,osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/org.apache.logging.log4j/log4j-api/pom.properties", + "name": "", + "groupId": "org.apache.logging.log4j", + "artifactId": "log4j-api", + "version": "2.22.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "bea6fede6328fabafd7e68363161a7ea6605abd1" + } + ] + } + }, + { + "id": "860f45be6a175d16", + "name": "log4j-to-slf4j", + "version": "2.22.1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/log4j-to-slf4j-2.22.1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "\"Apache-2.0\";link=\"https://www.apache.org/licenses/LICENSE-2.0.txt\"", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/log4j-to-slf4j-2.22.1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:apache:log4j-to-slf4j:2.22.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:log4j_to_slf4j:2.22.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:log4j:2.22.1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:slf4j:2.22.1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.22.1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/log4j-to-slf4j-2.22.1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Created-By", + "value": "Maven JAR Plugin 3.3.0" + }, + { + "key": "Build-Jdk-Spec", + "value": "17" + }, + { + "key": "Specification-Title", + "value": "Apache Log4j to SLF4J Adapter" + }, + { + "key": "Specification-Version", + "value": "2.22" + }, + { + "key": "Specification-Vendor", + "value": "The Apache Software Foundation" + }, + { + "key": "Implementation-Title", + "value": "Apache Log4j to SLF4J Adapter" + }, + { + "key": "Implementation-Version", + "value": "2.22.1" + }, + { + "key": "Implementation-Vendor", + "value": "The Apache Software Foundation" + }, + { + "key": "Bundle-ActivationPolicy", + "value": "lazy" + }, + { + "key": "Bundle-Activator", + "value": "org.apache.logging.slf4j.Activator" + }, + { + "key": "Bundle-Description", + "value": "The Apache Log4j binding between Log4j 2 API and SLF4J." + }, + { + "key": "Bundle-License", + "value": "\"Apache-2.0\";link=\"https://www.apache.org/licenses/LICENSE-2.0.txt\"" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "Apache Log4j to SLF4J Adapter" + }, + { + "key": "Bundle-SymbolicName", + "value": "org.apache.logging.log4j.to.slf4j" + }, + { + "key": "Bundle-Vendor", + "value": "The Apache Software Foundation" + }, + { + "key": "Bundle-Version", + "value": "2.22.1" + }, + { + "key": "Export-Package", + "value": "org.apache.logging.slf4j;version=\"2.20.1\";uses:=\"org.apache.logging.log4j,org.apache.logging.log4j.message,org.apache.logging.log4j.spi,org.apache.logging.log4j.util,org.slf4j\"" + }, + { + "key": "Import-Package", + "value": "org.slf4j;version=\"[1.7,3)\",org.slf4j.spi;version=\"[1.7,3)\",org.apache.logging.log4j;version=\"[2.20,3)\",org.apache.logging.log4j.message;version=\"[2.22,3)\",org.apache.logging.log4j.spi;version=\"[2.20,3)\",org.apache.logging.log4j.status;version=\"[2.20,3)\",org.apache.logging.log4j.util;version=\"[2.22,3)\"" + }, + { + "key": "Multi-Release", + "value": "false" + }, + { + "key": "Provide-Capability", + "value": "osgi.service;objectClass:List=\"org.apache.logging.log4j.spi.Provider\";effective:=active,osgi.serviceloader;osgi.serviceloader=\"org.apache.logging.log4j.spi.Provider\";register:=\"org.apache.logging.slf4j.SLF4JProvider\"" + }, + { + "key": "Require-Capability", + "value": "osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.registrar)(version>=1.0.0)(!(version>=2.0.0)))\";resolution:=optional,osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/org.apache.logging.log4j/log4j-to-slf4j/pom.properties", + "name": "", + "groupId": "org.apache.logging.log4j", + "artifactId": "log4j-to-slf4j", + "version": "2.22.1" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "b5e67b6acac768bfec1d1d6991504f45453abcad" + } + ] + } + }, + { + "id": "d91fe3ae6bb15cad", + "name": "logback-classic", + "version": "1.4.14", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/logback-classic-1.4.14.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.eclipse.org/legal/epl-v10.html, http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/logback-classic-1.4.14.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:logback-classic:logback-classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback-classic:logback_classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback_classic:logback-classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback_classic:logback_classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback:logback-classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback:logback_classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:qos-ch:logback-classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:qos-ch:logback_classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:qos_ch:logback-classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:qos_ch:logback_classic:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/ch.qos.logback/logback-classic@1.4.14", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/logback-classic-1.4.14.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.8" + }, + { + "key": "Build-Jdk-Spec", + "value": "21" + }, + { + "key": "Specification-Title", + "value": "Logback Classic Module" + }, + { + "key": "Specification-Version", + "value": "1.4" + }, + { + "key": "Specification-Vendor", + "value": "QOS.ch" + }, + { + "key": "Implementation-Title", + "value": "Logback Classic Module" + }, + { + "key": "Implementation-Version", + "value": "1.4.14" + }, + { + "key": "Implementation-Vendor", + "value": "QOS.ch" + }, + { + "key": "Bundle-Description", + "value": "logback-classic module" + }, + { + "key": "Bundle-DocURL", + "value": "http://www.qos.ch" + }, + { + "key": "Bundle-License", + "value": "http://www.eclipse.org/legal/epl-v10.html, http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "Logback Classic Module" + }, + { + "key": "Bundle-SymbolicName", + "value": "ch.qos.logback.classic" + }, + { + "key": "Bundle-Vendor", + "value": "QOS.ch" + }, + { + "key": "Bundle-Version", + "value": "1.4.14" + }, + { + "key": "Export-Package", + "value": "ch.qos.logback.classic;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.classic.turbo,ch.qos.logback.core,ch.qos.logback.core.pattern,ch.qos.logback.core.spi,ch.qos.logback.core.status,jakarta.servlet.http,org.slf4j,org.slf4j.event,org.slf4j.spi\",ch.qos.logback.classic.boolex;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core.boolex\",ch.qos.logback.classic.db.script;version=\"1.4.14\",ch.qos.logback.classic.encoder;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core.encoder,ch.qos.logback.core.pattern\",ch.qos.logback.classic.filter;version=\"1.4.14\";uses:=\"ch.qos.logback.classic,ch.qos.logback.classic.spi,ch.qos.logback.core.filter,ch.qos.logback.core.spi\",ch.qos.logback.classic.helpers;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core,jakarta.servlet\",ch.qos.logback.classic.html;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core.html,ch.qos.logback.core.pattern\",ch.qos.logback.classic.joran;version=\"1.4.14\";uses:=\"ch.qos.logback.classic,ch.qos.logback.classic.spi,ch.qos.logback.core,ch.qos.logback.core.joran,ch.qos.logback.core.joran.spi,ch.qos.logback.core.model,ch.qos.logback.core.model.processor,ch.qos.logback.core.spi\",ch.qos.logback.classic.joran.action;version=\"1.4.14\";uses:=\"ch.qos.logback.core.joran.action,ch.qos.logback.core.joran.spi,ch.qos.logback.core.model,org.xml.sax\",ch.qos.logback.classic.joran.sanity;version=\"1.4.14\";uses:=\"ch.qos.logback.core.joran.sanity,ch.qos.logback.core.model,ch.qos.logback.core.spi\",ch.qos.logback.classic.joran.serializedModel;version=\"1.4.14\";uses:=\"ch.qos.logback.core.net\",ch.qos.logback.classic.jul;version=\"1.4.14\";uses:=\"ch.qos.logback.classic,ch.qos.logback.classic.spi,ch.qos.logback.core.spi\",ch.qos.logback.classic.layout;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core\",ch.qos.logback.classic.log4j;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core\",ch.qos.logback.classic.model;version=\"1.4.14\";uses:=\"ch.qos.logback.core.model,ch.qos.logback.core.model.processor\",ch.qos.logback.classic.model.processor;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.model,ch.qos.logback.core,ch.qos.logback.core.joran.spi,ch.qos.logback.core.joran.util,ch.qos.logback.core.model,ch.qos.logback.core.model.processor\",ch.qos.logback.classic.model.util;version=\"1.4.14\";uses:=\"ch.qos.logback.core.model\",ch.qos.logback.classic.net;version=\"1.4.14\";uses:=\"ch.qos.logback.classic,ch.qos.logback.classic.spi,ch.qos.logback.core,ch.qos.logback.core.boolex,ch.qos.logback.core.helpers,ch.qos.logback.core.joran.spi,ch.qos.logback.core.net,ch.qos.logback.core.net.ssl,ch.qos.logback.core.pattern,ch.qos.logback.core.spi,javax.net,javax.net.ssl\",ch.qos.logback.classic.net.server;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.net,ch.qos.logback.classic.spi,ch.qos.logback.core.net,ch.qos.logback.core.net.server,ch.qos.logback.core.net.ssl,ch.qos.logback.core.spi,javax.net\",ch.qos.logback.classic.pattern;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core,ch.qos.logback.core.pattern,org.slf4j\",ch.qos.logback.classic.pattern.color;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core.pattern.color\",ch.qos.logback.classic.selector;version=\"1.4.14\";uses:=\"ch.qos.logback.classic\",ch.qos.logback.classic.selector.servlet;version=\"1.4.14\";uses:=\"jakarta.servlet\",ch.qos.logback.classic.servlet;version=\"1.4.14\";uses:=\"jakarta.servlet\",ch.qos.logback.classic.sift;version=\"1.4.14\";uses:=\"ch.qos.logback.classic.spi,ch.qos.logback.core.joran.spi,ch.qos.logback.core.sift\",ch.qos.logback.classic.spi;version=\"1.4.14\";uses:=\"ch.qos.logback.classic,ch.qos.logback.classic.turbo,ch.qos.logback.core,ch.qos.logback.core.spi,org.slf4j,org.slf4j.event,org.slf4j.spi\",ch.qos.logback.classic.turbo;version=\"1.4.14\";uses:=\"ch.qos.logback.classic,ch.qos.logback.core.spi,org.slf4j\",ch.qos.logback.classic.util;version=\"1.4.14\";uses:=\"ch.qos.logback.classic,ch.qos.logback.classic.selector,ch.qos.logback.classic.spi,ch.qos.logback.core.joran.spi,ch.qos.logback.core.spi,ch.qos.logback.core.status,org.slf4j.spi\"" + }, + { + "key": "Import-Package", + "value": "ch.qos.logback.classic;version=\"[1.4,2)\",ch.qos.logback.classic.boolex;version=\"[1.4,2)\",ch.qos.logback.classic.encoder;version=\"[1.4,2)\",ch.qos.logback.classic.joran;version=\"[1.4,2)\",ch.qos.logback.classic.joran.action;version=\"[1.4,2)\",ch.qos.logback.classic.joran.sanity;version=\"[1.4,2)\",ch.qos.logback.classic.joran.serializedModel;version=\"[1.4,2)\",ch.qos.logback.classic.layout;version=\"[1.4,2)\",ch.qos.logback.classic.model;version=\"[1.4,2)\",ch.qos.logback.classic.model.processor;version=\"[1.4,2)\",ch.qos.logback.classic.net;version=\"[1.4,2)\",ch.qos.logback.classic.net.server;version=\"[1.4,2)\",ch.qos.logback.classic.pattern;version=\"[1.4,2)\",ch.qos.logback.classic.pattern.color;version=\"[1.4,2)\",ch.qos.logback.classic.selector;version=\"[1.4,2)\",ch.qos.logback.classic.spi;version=\"[1.4,2)\",ch.qos.logback.classic.turbo;version=\"[1.4,2)\",ch.qos.logback.classic.util;version=\"[1.4,2)\",jakarta.servlet;resolution:=optional;version=\"[5.0,6)\",jakarta.servlet.http;resolution:=optional;version=\"[5.0,6)\",org.xml.sax;resolution:=optional,ch.qos.logback.core;version=\"[1.4,2)\",ch.qos.logback.core.boolex;version=\"[1.4,2)\",ch.qos.logback.core.encoder;version=\"[1.4,2)\",ch.qos.logback.core.filter;version=\"[1.4,2)\",ch.qos.logback.core.helpers;version=\"[1.4,2)\",ch.qos.logback.core.html;version=\"[1.4,2)\",ch.qos.logback.core.joran;version=\"[1.4,2)\",ch.qos.logback.core.joran.action;version=\"[1.4,2)\",ch.qos.logback.core.joran.sanity;version=\"[1.4,2)\",ch.qos.logback.core.joran.spi;version=\"[1.4,2)\",ch.qos.logback.core.joran.util;version=\"[1.4,2)\",ch.qos.logback.core.model;version=\"[1.4,2)\",ch.qos.logback.core.model.conditional;version=\"[1.4,2)\",ch.qos.logback.core.model.processor;version=\"[1.4,2)\",ch.qos.logback.core.model.util;version=\"[1.4,2)\",ch.qos.logback.core.net;version=\"[1.4,2)\",ch.qos.logback.core.net.server;version=\"[1.4,2)\",ch.qos.logback.core.net.ssl;version=\"[1.4,2)\",ch.qos.logback.core.pattern;version=\"[1.4,2)\",ch.qos.logback.core.pattern.color;version=\"[1.4,2)\",ch.qos.logback.core.pattern.parser;version=\"[1.4,2)\",ch.qos.logback.core.sift;version=\"[1.4,2)\",ch.qos.logback.core.spi;version=\"[1.4,2)\",ch.qos.logback.core.status;version=\"[1.4,2)\",ch.qos.logback.core.util;version=\"[1.4,2)\",java.io,java.lang,java.lang.annotation,java.lang.invoke,java.lang.reflect,java.net,java.nio.charset,java.security,java.text,java.time,java.util,java.util.concurrent,java.util.concurrent.atomic,java.util.function,java.util.logging,java.util.regex,javax.management,javax.naming,javax.net,javax.net.ssl,org.slf4j;version=\"[2.0,3)\",org.slf4j.event;version=\"[2.0,3)\",org.slf4j.helpers;version=\"[2.0,3)\",org.slf4j.spi;version=\"[2.0,3)\",sun.reflect;resolution:=optional,ch.qos.logback.core.rolling;version=\"[1.4,2)\",ch.qos.logback.core.rolling.helper;version=\"[1.4,2)\",ch.qos.logback.core.read;version=\"[1.4,2)\"" + }, + { + "key": "Originally-Created-By", + "value": "Apache Maven Bundle Plugin 5.1.8" + }, + { + "key": "Provide-Capability", + "value": "osgi.service;objectClass:List=\"jakarta.servlet.ServletContainerInitializer\";effective:=active,osgi.service;objectClass:List=\"org.slf4j.spi.SLF4JServiceProvider\";effective:=active,osgi.serviceloader;osgi.serviceloader=\"jakarta.servlet.ServletContainerInitializer\";register:=\"ch.qos.logback.classic.servlet.LogbackServletContainerInitializer\",osgi.serviceloader;osgi.serviceloader=\"org.slf4j.spi.SLF4JServiceProvider\";register:=\"ch.qos.logback.classic.spi.LogbackServiceProvider\"" + }, + { + "key": "Require-Capability", + "value": "osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))\";resolution:=optional,osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.registrar)(version>=1.0.0)(!(version>=2.0.0)))\",osgi.serviceloader;filter:=\"(osgi.serviceloader=ch.qos.logback.classic.spi.Configurator)\";osgi.serviceloader=\"ch.qos.logback.classic.spi.Configurator\";resolution:=optional;cardinality:=multiple,osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=11))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/ch.qos.logback/logback-classic/pom.properties", + "name": "", + "groupId": "ch.qos.logback", + "artifactId": "logback-classic", + "version": "1.4.14" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "d98bc162275134cdf1518774da4a2a17ef6fb94d" + } + ] + } + }, + { + "id": "3748310e1aac44ea", + "name": "logback-core", + "version": "1.4.14", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/logback-core-1.4.14.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.eclipse.org/legal/epl-v10.html, http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/logback-core-1.4.14.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:logback-core:logback-core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback-core:logback_core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback_core:logback-core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback_core:logback_core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback:logback-core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:logback:logback_core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:qos-ch:logback-core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:qos-ch:logback_core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:qos_ch:logback-core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:qos_ch:logback_core:1.4.14:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/ch.qos.logback/logback-core@1.4.14", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/logback-core-1.4.14.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.8" + }, + { + "key": "Build-Jdk-Spec", + "value": "21" + }, + { + "key": "Specification-Title", + "value": "Logback Core Module" + }, + { + "key": "Specification-Version", + "value": "1.4" + }, + { + "key": "Specification-Vendor", + "value": "QOS.ch" + }, + { + "key": "Implementation-Title", + "value": "Logback Core Module" + }, + { + "key": "Implementation-Version", + "value": "1.4.14" + }, + { + "key": "Implementation-Vendor", + "value": "QOS.ch" + }, + { + "key": "Bundle-Description", + "value": "logback-core module" + }, + { + "key": "Bundle-DocURL", + "value": "http://www.qos.ch" + }, + { + "key": "Bundle-License", + "value": "http://www.eclipse.org/legal/epl-v10.html, http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "Logback Core Module" + }, + { + "key": "Bundle-SymbolicName", + "value": "ch.qos.logback.core" + }, + { + "key": "Bundle-Vendor", + "value": "QOS.ch" + }, + { + "key": "Bundle-Version", + "value": "1.4.14" + }, + { + "key": "Export-Package", + "value": "ch.qos.logback.core;version=\"1.4.14\";uses:=\"ch.qos.logback.core.encoder,ch.qos.logback.core.filter,ch.qos.logback.core.helpers,ch.qos.logback.core.joran.spi,ch.qos.logback.core.spi,ch.qos.logback.core.status,ch.qos.logback.core.util\",ch.qos.logback.core.boolex;version=\"1.4.14\";uses:=\"ch.qos.logback.core.spi\",ch.qos.logback.core.encoder;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.spi\",ch.qos.logback.core.filter;version=\"1.4.14\";uses:=\"ch.qos.logback.core.boolex,ch.qos.logback.core.spi\",ch.qos.logback.core.helpers;version=\"1.4.14\";uses:=\"ch.qos.logback.core\",ch.qos.logback.core.hook;version=\"1.4.14\";uses:=\"ch.qos.logback.core.spi,ch.qos.logback.core.util\",ch.qos.logback.core.html;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.pattern\",ch.qos.logback.core.joran;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.event,ch.qos.logback.core.joran.sanity,ch.qos.logback.core.joran.spi,ch.qos.logback.core.joran.util.beans,ch.qos.logback.core.model,ch.qos.logback.core.model.processor,ch.qos.logback.core.spi,org.xml.sax\",ch.qos.logback.core.joran.action;version=\"1.4.14\";uses:=\"ch.qos.logback.core.joran.spi,ch.qos.logback.core.joran.util,ch.qos.logback.core.model,ch.qos.logback.core.model.processor,ch.qos.logback.core.spi,ch.qos.logback.core.util,org.xml.sax\",ch.qos.logback.core.joran.conditional;version=\"1.4.14\";uses:=\"ch.qos.logback.core.joran.action,ch.qos.logback.core.joran.spi,ch.qos.logback.core.model,ch.qos.logback.core.spi,org.codehaus.commons.compiler,org.xml.sax\",ch.qos.logback.core.joran.event;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.spi,ch.qos.logback.core.spi,ch.qos.logback.core.status,org.xml.sax,org.xml.sax.helpers\",ch.qos.logback.core.joran.event.stax;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.spi,ch.qos.logback.core.spi,javax.xml.stream,javax.xml.stream.events\",ch.qos.logback.core.joran.node;version=\"1.4.14\",ch.qos.logback.core.joran.sanity;version=\"1.4.14\";uses:=\"ch.qos.logback.core.model,ch.qos.logback.core.spi\",ch.qos.logback.core.joran.spi;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.action,ch.qos.logback.core.joran.event,ch.qos.logback.core.model,ch.qos.logback.core.model.processor,ch.qos.logback.core.spi,ch.qos.logback.core.status,org.xml.sax\",ch.qos.logback.core.joran.util;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.spi,ch.qos.logback.core.joran.util.beans,ch.qos.logback.core.spi,ch.qos.logback.core.util\",ch.qos.logback.core.joran.util.beans;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.spi\",ch.qos.logback.core.layout;version=\"1.4.14\";uses:=\"ch.qos.logback.core\",ch.qos.logback.core.model;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.action,ch.qos.logback.core.model.processor\",ch.qos.logback.core.model.conditional;version=\"1.4.14\";uses:=\"ch.qos.logback.core.model\",ch.qos.logback.core.model.processor;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.action,ch.qos.logback.core.joran.spi,ch.qos.logback.core.joran.util.beans,ch.qos.logback.core.model,ch.qos.logback.core.spi\",ch.qos.logback.core.model.processor.conditional;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.model,ch.qos.logback.core.model.conditional,ch.qos.logback.core.model.processor\",ch.qos.logback.core.model.util;version=\"1.4.14\";uses:=\"ch.qos.logback.core.model\",ch.qos.logback.core.net;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.boolex,ch.qos.logback.core.helpers,ch.qos.logback.core.net.ssl,ch.qos.logback.core.pattern,ch.qos.logback.core.sift,ch.qos.logback.core.spi,ch.qos.logback.core.util,jakarta.mail,jakarta.mail.internet,javax.net\",ch.qos.logback.core.net.server;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.net.ssl,ch.qos.logback.core.spi,javax.net\",ch.qos.logback.core.net.ssl;version=\"1.4.14\";uses:=\"ch.qos.logback.core.joran.spi,ch.qos.logback.core.spi,javax.net,javax.net.ssl\",ch.qos.logback.core.pattern;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.encoder,ch.qos.logback.core.spi,ch.qos.logback.core.status\",ch.qos.logback.core.pattern.color;version=\"1.4.14\";uses:=\"ch.qos.logback.core.pattern\",ch.qos.logback.core.pattern.parser;version=\"1.4.14\";uses:=\"ch.qos.logback.core.pattern,ch.qos.logback.core.pattern.util,ch.qos.logback.core.spi\",ch.qos.logback.core.pattern.util;version=\"1.4.14\",ch.qos.logback.core.property;version=\"1.4.14\";uses:=\"ch.qos.logback.core\",ch.qos.logback.core.read;version=\"1.4.14\";uses:=\"ch.qos.logback.core\",ch.qos.logback.core.recovery;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.status\",ch.qos.logback.core.rolling;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.spi,ch.qos.logback.core.rolling.helper,ch.qos.logback.core.spi,ch.qos.logback.core.util\",ch.qos.logback.core.rolling.helper;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.pattern,ch.qos.logback.core.rolling,ch.qos.logback.core.spi\",ch.qos.logback.core.sift;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.joran.spi,ch.qos.logback.core.model,ch.qos.logback.core.model.processor,ch.qos.logback.core.spi,ch.qos.logback.core.util\",ch.qos.logback.core.spi;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.filter,ch.qos.logback.core.helpers,ch.qos.logback.core.status\",ch.qos.logback.core.status;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.spi,jakarta.servlet,jakarta.servlet.http\",ch.qos.logback.core.subst;version=\"1.4.14\";uses:=\"ch.qos.logback.core.spi\",ch.qos.logback.core.testUtil;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.encoder,ch.qos.logback.core.read,ch.qos.logback.core.spi,ch.qos.logback.core.status,javax.naming,javax.naming.spi\",ch.qos.logback.core.util;version=\"1.4.14\";uses:=\"ch.qos.logback.core,ch.qos.logback.core.rolling,ch.qos.logback.core.rolling.helper,ch.qos.logback.core.spi,ch.qos.logback.core.status,javax.naming\"" + }, + { + "key": "Import-Package", + "value": "ch.qos.logback.core;version=\"[1.4,2)\",ch.qos.logback.core.boolex;version=\"[1.4,2)\",ch.qos.logback.core.encoder;version=\"[1.4,2)\",ch.qos.logback.core.filter;version=\"[1.4,2)\",ch.qos.logback.core.helpers;version=\"[1.4,2)\",ch.qos.logback.core.hook;version=\"[1.4,2)\",ch.qos.logback.core.joran;version=\"[1.4,2)\",ch.qos.logback.core.joran.action;version=\"[1.4,2)\",ch.qos.logback.core.joran.conditional;version=\"[1.4,2)\",ch.qos.logback.core.joran.event;version=\"[1.4,2)\",ch.qos.logback.core.joran.sanity;version=\"[1.4,2)\",ch.qos.logback.core.joran.spi;version=\"[1.4,2)\",ch.qos.logback.core.joran.util;version=\"[1.4,2)\",ch.qos.logback.core.joran.util.beans;version=\"[1.4,2)\",ch.qos.logback.core.model;version=\"[1.4,2)\",ch.qos.logback.core.model.conditional;version=\"[1.4,2)\",ch.qos.logback.core.model.processor;version=\"[1.4,2)\",ch.qos.logback.core.model.processor.conditional;version=\"[1.4,2)\",ch.qos.logback.core.net;version=\"[1.4,2)\",ch.qos.logback.core.net.ssl;version=\"[1.4,2)\",ch.qos.logback.core.pattern;version=\"[1.4,2)\",ch.qos.logback.core.pattern.parser;version=\"[1.4,2)\",ch.qos.logback.core.pattern.util;version=\"[1.4,2)\",ch.qos.logback.core.read;version=\"[1.4,2)\",ch.qos.logback.core.recovery;version=\"[1.4,2)\",ch.qos.logback.core.rolling;version=\"[1.4,2)\",ch.qos.logback.core.rolling.helper;version=\"[1.4,2)\",ch.qos.logback.core.sift;version=\"[1.4,2)\",ch.qos.logback.core.spi;version=\"[1.4,2)\",ch.qos.logback.core.status;version=\"[1.4,2)\",ch.qos.logback.core.subst;version=\"[1.4,2)\",ch.qos.logback.core.util;version=\"[1.4,2)\",jakarta.mail;resolution:=optional;version=\"[2.1,3)\",jakarta.mail.internet;resolution:=optional;version=\"[2.1,3)\",jakarta.servlet;resolution:=optional;version=\"[5.0,6)\",jakarta.servlet.http;resolution:=optional;version=\"[5.0,6)\",org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional,org.codehaus.janino;resolution:=optional;version=\"[3.1,4)\",org.codehaus.commons.compiler;resolution:=optional;version=\"[3.1,4)\",java.io,java.lang,java.lang.annotation,java.lang.invoke,java.lang.module,java.lang.reflect,java.math,java.net,java.nio,java.nio.channels,java.nio.charset,java.nio.file,java.security,java.security.cert,java.text,java.time,java.time.format,java.time.temporal,java.util,java.util.concurrent,java.util.concurrent.atomic,java.util.concurrent.locks,java.util.function,java.util.regex,java.util.stream,java.util.zip,javax.naming,javax.naming.spi,javax.net,javax.net.ssl,javax.xml.namespace,javax.xml.parsers,javax.xml.stream,javax.xml.stream.events,org.fusesource.jansi;resolution:=optional;version=\"[2.4,3)\"" + }, + { + "key": "Originally-Created-By", + "value": "Apache Maven Bundle Plugin 5.1.8" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=11))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/ch.qos.logback/logback-core/pom.properties", + "name": "", + "groupId": "ch.qos.logback", + "artifactId": "logback-core", + "version": "1.4.14" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "4d3c2248219ac0effeb380ed4c5280a80bf395e8" + } + ] + } + }, + { + "id": "c46f369578c77c43", + "name": "micrometer-commons", + "version": "1.13.0-M1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-commons-1.13.0-M1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-commons-1.13.0-M1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:micrometer-commons:micrometer-commons:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer-commons:micrometer_commons:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer_commons:micrometer-commons:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer_commons:micrometer_commons:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer:micrometer-commons:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer:micrometer_commons:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/io.micrometer/micrometer-commons@1.13.0-M1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-commons-1.13.0-M1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "micrometer.commons" + }, + { + "key": "Bnd-LastModified", + "value": "1707769856136" + }, + { + "key": "Branch", + "value": "HEAD" + }, + { + "key": "Build-Date", + "value": "2024-02-12_20:30:25" + }, + { + "key": "Build-Date-UTC", + "value": "2024-02-12T20:30:25.169807141Z" + }, + { + "key": "Build-Host", + "value": "bea640c5c9a6" + }, + { + "key": "Build-Id", + "value": "30241" + }, + { + "key": "Build-Java-Version", + "value": "21" + }, + { + "key": "Build-Job", + "value": "deploy" + }, + { + "key": "Build-Number", + "value": "30241" + }, + { + "key": "Build-Timezone", + "value": "Etc/UTC" + }, + { + "key": "Build-Url", + "value": "https://circleci.com/gh/micrometer-metrics/micrometer/30241" + }, + { + "key": "Built-By", + "value": "circleci" + }, + { + "key": "Built-OS", + "value": "Linux" + }, + { + "key": "Built-Status", + "value": "candidate" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "micrometer-commons" + }, + { + "key": "Bundle-SymbolicName", + "value": "micrometer-commons" + }, + { + "key": "Bundle-Version", + "value": "1.13.0.M1" + }, + { + "key": "Change", + "value": "639c93a" + }, + { + "key": "Created-By", + "value": "21.0.2 (Eclipse Adoptium)" + }, + { + "key": "DynamicImport-Package", + "value": "org.aspectj.lang,org.aspectj.lang.reflect" + }, + { + "key": "Export-Package", + "value": "io.micrometer.common;uses:=\"io.micrometer.common.docs,io.micrometer.common.lang\";version=\"1.13.0\",io.micrometer.common.annotation;uses:=\"io.micrometer.common,io.micrometer.common.lang,org.aspectj.lang\";version=\"1.13.0\",io.micrometer.common.docs;uses:=\"io.micrometer.common\";version=\"1.13.0\",io.micrometer.common.lang;uses:=\"javax.annotation,javax.annotation.meta\";version=\"1.13.0\",io.micrometer.common.util;uses:=\"io.micrometer.common.lang\";version=\"1.13.0\",io.micrometer.common.util.internal.logging;version=\"1.13.0\"" + }, + { + "key": "Full-Change", + "value": "639c93af0d0507b4cfa0e0581146719863b691b1" + }, + { + "key": "Gradle-Version", + "value": "8.6" + }, + { + "key": "Implementation-Title", + "value": "io.micrometer#micrometer-commons;1.13.0-M1" + }, + { + "key": "Implementation-Version", + "value": "1.13.0-M1" + }, + { + "key": "Import-Package", + "value": "io.micrometer.common,io.micrometer.common.docs,io.micrometer.common.lang,io.micrometer.common.util.internal.logging,javax.annotation;version=\"[3.0,4)\",javax.annotation.meta;version=\"[3.0,4)\",org.slf4j;version=\"[1.7,2)\",org.slf4j.helpers;version=\"[1.7,2)\",org.slf4j.spi;version=\"[1.7,2)\"" + }, + { + "key": "Module-Email", + "value": "tludwig@vmware.com" + }, + { + "key": "Module-Origin", + "value": "git@github.com:micrometer-metrics/micrometer.git" + }, + { + "key": "Module-Owner", + "value": "tludwig@vmware.com" + }, + { + "key": "Module-Source", + "value": "/micrometer-commons" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.4.0.202211291949" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "e738daf6678eedf8e0c40a782bdb0df064a391e5" + } + ] + } + }, + { + "id": "3c0d8567351e2ae4", + "name": "micrometer-core", + "version": "1.13.0-M1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-core-1.13.0-M1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-core-1.13.0-M1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:micrometer-core:micrometer-core:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer-core:micrometer_core:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer_core:micrometer-core:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer_core:micrometer_core:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer:micrometer-core:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer:micrometer_core:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/io.micrometer/micrometer-core@1.13.0-M1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-core-1.13.0-M1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "micrometer.core" + }, + { + "key": "Bnd-LastModified", + "value": "1707769876578" + }, + { + "key": "Branch", + "value": "HEAD" + }, + { + "key": "Build-Date", + "value": "2024-02-12_20:30:25" + }, + { + "key": "Build-Date-UTC", + "value": "2024-02-12T20:30:25.236904273Z" + }, + { + "key": "Build-Host", + "value": "bea640c5c9a6" + }, + { + "key": "Build-Id", + "value": "30241" + }, + { + "key": "Build-Java-Version", + "value": "21" + }, + { + "key": "Build-Job", + "value": "deploy" + }, + { + "key": "Build-Number", + "value": "30241" + }, + { + "key": "Build-Timezone", + "value": "Etc/UTC" + }, + { + "key": "Build-Url", + "value": "https://circleci.com/gh/micrometer-metrics/micrometer/30241" + }, + { + "key": "Built-By", + "value": "circleci" + }, + { + "key": "Built-OS", + "value": "Linux" + }, + { + "key": "Built-Status", + "value": "candidate" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "micrometer-core" + }, + { + "key": "Bundle-SymbolicName", + "value": "micrometer-core" + }, + { + "key": "Bundle-Version", + "value": "1.13.0.M1" + }, + { + "key": "Change", + "value": "639c93a" + }, + { + "key": "Created-By", + "value": "21.0.2 (Eclipse Adoptium)" + }, + { + "key": "DynamicImport-Package", + "value": "org.aspectj.lang,org.aspectj.lang.annotation,org.aspectj.lang.reflect,com.github.benmanes.caffeine.cache;version=\"2.9.3\",com.github.benmanes.caffeine.cache.stats;version=\"2.9.3\",net.sf.ehcache;version=\"2.10.9\",net.sf.ehcache.statistics;version=\"2.10.9\",javax.cache;version=\"1.1.1\",org.hibernate;version=\"5.6.15.Final\",org.hibernate.engine.spi;version=\"5.6.15.Final\",org.hibernate.event.service.spi;version=\"5.6.15.Final\",org.hibernate.event.spi;version=\"5.6.15.Final\",org.hibernate.service;version=\"5.6.15.Final\",org.hibernate.service.spi;version=\"5.6.15.Final\",org.hibernate.stat;version=\"5.6.15.Final\",org.hibernate.stat.spi;version=\"5.6.15.Final\",org.eclipse.jetty.client.api;version=\"9.4.53\",org.eclipse.jetty.http;version=\"9.4.53\",org.eclipse.jetty.io;version=\"9.4.53\",org.eclipse.jetty.io.ssl;version=\"9.4.53\",org.eclipse.jetty.server;version=\"9.4.53\",org.eclipse.jetty.server.handler;version=\"9.4.53\",org.eclipse.jetty.util;version=\"9.4.53\",org.eclipse.jetty.util.component;version=\"9.4.53\",org.eclipse.jetty.util.thread;version=\"9.4.53\",org.glassfish.jersey.server;version=\"2.41\",org.glassfish.jersey.server.model;version=\"2.41\",org.glassfish.jersey.server.monitoring;version=\"2.41\",org.glassfish.jersey.uri;version=\"2.41\",io.grpc,io.grpc.kotlin,org.apache.hc.client5.http,org.apache.hc.client5.http.async,org.apache.hc.client5.http.classic,org.apache.hc.client5.http.protocol,org.apache.hc.core5.concurrent,org.apache.hc.core5.http,org.apache.hc.core5.http.impl,org.apache.hc.core5.http.impl.io,org.apache.hc.core5.http.io,org.apache.hc.core5.http.nio,org.apache.hc.core5.http.protocol,org.apache.hc.core5.pool,org.apache.hc.core5.util,org.apache.http,org.apache.http.conn.routing,org.apache.http.pool,org.apache.http.protocol,com.netflix.hystrix;version=\"1.5.12\",com.netflix.hystrix.metric;version=\"1.5.12\",com.netflix.hystrix.strategy;version=\"1.5.12\",com.netflix.hystrix.strategy.concurrency;version=\"1.5.12\",com.netflix.hystrix.strategy.eventnotifier;version=\"1.5.12\",com.netflix.hystrix.strategy.executionhook;version=\"1.5.12\",com.netflix.hystrix.strategy.metrics;version=\"1.5.12\",com.netflix.hystrix.strategy.properties;version=\"1.5.12\",ch.qos.logback.classic;version=\"1.2.13\",ch.qos.logback.classic.spi;version=\"1.2.13\",ch.qos.logback.classic.turbo;version=\"1.2.13\",ch.qos.logback.core.spi;version=\"1.2.13\",org.apache.logging.log4j;version=\"2.20.2\",org.apache.logging.log4j.core;version=\"2.20.2\",org.apache.logging.log4j.core.config;version=\"2.21.0\",org.apache.logging.log4j.core.filter;version=\"2.21.0\",org.apache.logging.log4j.spi;version=\"2.20.1\",okhttp3,com.mongodb;version=\"4.11.1\",com.mongodb.connection;version=\"4.11.1\",com.mongodb.event;version=\"4.11.1\",org.jooq;version=\"3.14.16\",org.jooq.exception;version=\"3.14.16\",org.jooq.impl;version=\"3.14.16\",org.apache.kafka.clients.admin,org.apache.kafka.clients.consumer,org.apache.kafka.clients.producer,org.apache.kafka.common,org.apache.kafka.common.metrics,org.apache.kafka.streams,com.codahale.metrics;version=\"4.2.25\",com.google.common.cache;version=\"32.1.2\",jakarta.servlet.http;version=\"5.0.0\",javax.servlet;version=\"4.0.0\",javax.servlet.http;version=\"4.0.0\",io.micrometer.context,io.micrometer.observation;version=\"1.13.0\",io.micrometer.observation.docs;version=\"1.13.0\",io.micrometer.observation.transport;version=\"1.13.0\",kotlin,kotlin.coroutines,kotlin.jvm.functions,kotlin.jvm.internal,kotlinx.coroutines,org.LatencyUtils,org.HdrHistogram;version=\"2.1.12\",org.apache.catalina,org.bson;version=\"4.11.1\",rx;version=\"1.2.0\",rx.functions;version=\"1.2.0\",javax.persistence;version=\"2.2.0\",io.netty.buffer;version=\"4.1.106\",io.netty.util.concurrent;version=\"4.1.106\"" + }, + { + "key": "Export-Package", + "value": "io.micrometer.core.annotation;version=\"1.13.0\",io.micrometer.core.aop;uses:=\"io.micrometer.common.annotation,io.micrometer.common.lang,io.micrometer.core.annotation,io.micrometer.core.instrument,org.aspectj.lang,org.aspectj.lang.annotation\";version=\"1.13.0\",io.micrometer.core.instrument;uses:=\"io.micrometer.common.lang,io.micrometer.core.annotation,io.micrometer.core.instrument.composite,io.micrometer.core.instrument.config,io.micrometer.core.instrument.distribution,io.micrometer.core.instrument.distribution.pause,io.micrometer.core.instrument.search\";version=\"1.13.0\",io.micrometer.core.instrument.binder;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument\";version=\"1.13.0\",io.micrometer.core.instrument.binder.cache;uses:=\"com.github.benmanes.caffeine.cache,com.github.benmanes.caffeine.cache.stats,com.google.common.cache,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,javax.cache,net.sf.ehcache\";version=\"1.13.0\",io.micrometer.core.instrument.binder.commonspool2;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,javax.management\";version=\"1.13.0\",io.micrometer.core.instrument.binder.db;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,javax.sql,org.jooq,org.jooq.impl\";version=\"1.13.0\",io.micrometer.core.instrument.binder.grpc;uses:=\"io.grpc,io.micrometer.common,io.micrometer.common.docs,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.observation,io.micrometer.observation.docs,io.micrometer.observation.transport\";version=\"1.13.0\",io.micrometer.core.instrument.binder.http;uses:=\"io.micrometer.common,io.micrometer.common.lang,io.micrometer.core.instrument,jakarta.servlet.http,javax.servlet.http\";version=\"1.13.0\",io.micrometer.core.instrument.binder.httpcomponents;uses:=\"io.micrometer.common,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,io.micrometer.observation,io.micrometer.observation.docs,io.micrometer.observation.transport,org.apache.http,org.apache.http.conn.routing,org.apache.http.pool,org.apache.http.protocol\";version=\"1.13.0\",io.micrometer.core.instrument.binder.httpcomponents.hc5;uses:=\"io.micrometer.common,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,io.micrometer.observation,io.micrometer.observation.docs,io.micrometer.observation.transport,org.apache.hc.client5.http,org.apache.hc.client5.http.async,org.apache.hc.client5.http.classic,org.apache.hc.client5.http.protocol,org.apache.hc.core5.http,org.apache.hc.core5.http.impl.io,org.apache.hc.core5.http.io,org.apache.hc.core5.http.nio,org.apache.hc.core5.http.protocol,org.apache.hc.core5.pool,org.apache.hc.core5.util\";version=\"1.13.0\",io.micrometer.core.instrument.binder.hystrix;uses:=\"com.netflix.hystrix,com.netflix.hystrix.strategy.metrics,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder\";version=\"1.13.0\",io.micrometer.core.instrument.binder.jersey.server;uses:=\"io.micrometer.common,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.observation,io.micrometer.observation.docs,io.micrometer.observation.transport,org.glassfish.jersey.server,org.glassfish.jersey.server.monitoring\";version=\"1.13.0\",io.micrometer.core.instrument.binder.jetty;uses:=\"io.micrometer.common,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,io.micrometer.core.instrument.binder.http,io.micrometer.observation,io.micrometer.observation.docs,io.micrometer.observation.transport,javax.servlet,javax.servlet.http,org.eclipse.jetty.client.api,org.eclipse.jetty.io,org.eclipse.jetty.io.ssl,org.eclipse.jetty.server,org.eclipse.jetty.server.handler,org.eclipse.jetty.util.component,org.eclipse.jetty.util.thread\";version=\"1.13.0\",io.micrometer.core.instrument.binder.jpa;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,javax.persistence,org.hibernate\";version=\"1.13.0\",io.micrometer.core.instrument.binder.jvm;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder\";version=\"1.13.0\",io.micrometer.core.instrument.binder.kafka;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,javax.management,org.apache.kafka.clients.admin,org.apache.kafka.clients.consumer,org.apache.kafka.clients.producer,org.apache.kafka.streams\";version=\"1.13.0\",io.micrometer.core.instrument.binder.logging;uses:=\"ch.qos.logback.classic,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,org.apache.logging.log4j.core\";version=\"1.13.0\",io.micrometer.core.instrument.binder.mongodb;uses:=\"com.mongodb.event,io.micrometer.common.lang,io.micrometer.core.instrument,org.bson\";version=\"1.13.0\",io.micrometer.core.instrument.binder.netty4;uses:=\"io.micrometer.core.instrument,io.micrometer.core.instrument.binder,io.micrometer.core.instrument.docs,io.netty.buffer,io.netty.util.concurrent\";version=\"1.13.0\",io.micrometer.core.instrument.binder.okhttp3;uses:=\"io.micrometer.common,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,io.micrometer.observation,io.micrometer.observation.docs,io.micrometer.observation.transport,okhttp3\";version=\"1.13.0\",io.micrometer.core.instrument.binder.system;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder\";version=\"1.13.0\",io.micrometer.core.instrument.binder.tomcat;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,javax.management,org.apache.catalina\";version=\"1.13.0\",io.micrometer.core.instrument.composite;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.distribution,io.micrometer.core.instrument.distribution.pause\";version=\"1.13.0\",io.micrometer.core.instrument.config;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.config.validate,io.micrometer.core.instrument.distribution\";version=\"1.13.0\",io.micrometer.core.instrument.config.validate;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument.config\";version=\"1.13.0\",io.micrometer.core.instrument.cumulative;uses:=\"io.micrometer.core.instrument,io.micrometer.core.instrument.distribution,io.micrometer.core.instrument.distribution.pause\";version=\"1.13.0\",io.micrometer.core.instrument.distribution;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.internal,io.micrometer.core.instrument.step,org.HdrHistogram\";version=\"1.13.0\",io.micrometer.core.instrument.distribution.pause;version=\"1.13.0\",io.micrometer.core.instrument.docs;uses:=\"io.micrometer.common.docs,io.micrometer.common.lang,io.micrometer.core.instrument\";version=\"1.13.0\",io.micrometer.core.instrument.dropwizard;uses:=\"com.codahale.metrics,io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.config,io.micrometer.core.instrument.config.validate,io.micrometer.core.instrument.distribution,io.micrometer.core.instrument.distribution.pause,io.micrometer.core.instrument.util\";version=\"1.13.0\",io.micrometer.core.instrument.internal;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.config,io.micrometer.core.instrument.distribution\";version=\"1.13.0\",io.micrometer.core.instrument.kotlin;uses:=\"io.grpc,io.grpc.kotlin,io.micrometer.observation,kotlin,kotlin.coroutines\";version=\"1.13.0\",io.micrometer.core.instrument.logging;uses:=\"io.micrometer.core.instrument,io.micrometer.core.instrument.distribution,io.micrometer.core.instrument.distribution.pause,io.micrometer.core.instrument.step\";version=\"1.13.0\",io.micrometer.core.instrument.noop;uses:=\"io.micrometer.core.instrument,io.micrometer.core.instrument.distribution\";version=\"1.13.0\",io.micrometer.core.instrument.observation;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.observation\";version=\"1.13.0\",io.micrometer.core.instrument.push;uses:=\"io.micrometer.core.instrument,io.micrometer.core.instrument.config,io.micrometer.core.instrument.config.validate\";version=\"1.13.0\",io.micrometer.core.instrument.search;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.config\";version=\"1.13.0\",io.micrometer.core.instrument.simple;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.config,io.micrometer.core.instrument.config.validate,io.micrometer.core.instrument.distribution,io.micrometer.core.instrument.distribution.pause\";version=\"1.13.0\",io.micrometer.core.instrument.step;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.config.validate,io.micrometer.core.instrument.distribution,io.micrometer.core.instrument.distribution.pause,io.micrometer.core.instrument.push\";version=\"1.13.0\",io.micrometer.core.instrument.util;uses:=\"io.micrometer.common.lang,io.micrometer.core.instrument,io.micrometer.core.instrument.config\";version=\"1.13.0\",io.micrometer.core.ipc.http;uses:=\"io.micrometer.common.lang,okhttp3\";version=\"1.13.0\",io.micrometer.core.lang;uses:=\"javax.annotation,javax.annotation.meta\";version=\"1.13.0\",io.micrometer.core.util.internal.logging;version=\"1.13.0\"" + }, + { + "key": "Full-Change", + "value": "639c93af0d0507b4cfa0e0581146719863b691b1" + }, + { + "key": "Gradle-Version", + "value": "8.6" + }, + { + "key": "Implementation-Title", + "value": "io.micrometer#micrometer-core;1.13.0-M1" + }, + { + "key": "Implementation-Version", + "value": "1.13.0-M1" + }, + { + "key": "Import-Package", + "value": "com.sun.management,io.micrometer.common;version=\"[1.13,2)\",io.micrometer.common.annotation;version=\"[1.13,2)\",io.micrometer.common.docs;version=\"[1.13,2)\",io.micrometer.common.lang;version=\"[1.13,2)\",io.micrometer.common.util;version=\"[1.13,2)\",io.micrometer.common.util.internal.logging;version=\"[1.13,2)\",io.micrometer.core.annotation,io.micrometer.core.instrument,io.micrometer.core.instrument.binder,io.micrometer.core.instrument.binder.http,io.micrometer.core.instrument.composite,io.micrometer.core.instrument.config,io.micrometer.core.instrument.config.validate,io.micrometer.core.instrument.cumulative,io.micrometer.core.instrument.distribution,io.micrometer.core.instrument.distribution.pause,io.micrometer.core.instrument.docs,io.micrometer.core.instrument.internal,io.micrometer.core.instrument.noop,io.micrometer.core.instrument.observation,io.micrometer.core.instrument.push,io.micrometer.core.instrument.search,io.micrometer.core.instrument.step,io.micrometer.core.instrument.util,javax.annotation;version=\"[3.0,4)\",javax.annotation.meta;version=\"[3.0,4)\",javax.management,javax.management.openmbean,javax.net.ssl,javax.sql,org.slf4j;version=\"[1.7,2)\",org.slf4j.helpers;version=\"[1.7,2)\",org.slf4j.spi;version=\"[1.7,2)\"" + }, + { + "key": "Module-Email", + "value": "tludwig@vmware.com" + }, + { + "key": "Module-Origin", + "value": "git@github.com:micrometer-metrics/micrometer.git" + }, + { + "key": "Module-Owner", + "value": "tludwig@vmware.com" + }, + { + "key": "Module-Source", + "value": "/micrometer-core" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.4.0.202211291949" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "49d54a8ed6d3266b4f2691027d95144e946bbe36" + } + ] + } + }, + { + "id": "f4ea2c844b65a026", + "name": "micrometer-jakarta9", + "version": "1.13.0-M1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-jakarta9-1.13.0-M1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-jakarta9-1.13.0-M1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:micrometer-jakarta9:micrometer-jakarta9:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer-jakarta9:micrometer_jakarta9:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer_jakarta9:micrometer-jakarta9:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer_jakarta9:micrometer_jakarta9:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer:micrometer-jakarta9:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer:micrometer_jakarta9:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/io.micrometer/micrometer-jakarta9@1.13.0-M1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-jakarta9-1.13.0-M1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "micrometer.jakarta9" + }, + { + "key": "Bnd-LastModified", + "value": "1707769878958" + }, + { + "key": "Branch", + "value": "HEAD" + }, + { + "key": "Build-Date", + "value": "2024-02-12_20:30:25" + }, + { + "key": "Build-Date-UTC", + "value": "2024-02-12T20:30:25.305566010Z" + }, + { + "key": "Build-Host", + "value": "bea640c5c9a6" + }, + { + "key": "Build-Id", + "value": "30241" + }, + { + "key": "Build-Java-Version", + "value": "21" + }, + { + "key": "Build-Job", + "value": "deploy" + }, + { + "key": "Build-Number", + "value": "30241" + }, + { + "key": "Build-Timezone", + "value": "Etc/UTC" + }, + { + "key": "Build-Url", + "value": "https://circleci.com/gh/micrometer-metrics/micrometer/30241" + }, + { + "key": "Built-By", + "value": "circleci" + }, + { + "key": "Built-OS", + "value": "Linux" + }, + { + "key": "Built-Status", + "value": "candidate" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "micrometer-jakarta9" + }, + { + "key": "Bundle-SymbolicName", + "value": "micrometer-jakarta9" + }, + { + "key": "Bundle-Version", + "value": "1.13.0.M1" + }, + { + "key": "Change", + "value": "639c93a" + }, + { + "key": "Created-By", + "value": "21.0.2 (Eclipse Adoptium)" + }, + { + "key": "DynamicImport-Package", + "value": "jakarta.jms;version=\"3.0.0\",io.micrometer.observation;version=\"1.13.0\",io.micrometer.observation.docs;version=\"1.13.0\",io.micrometer.observation.transport;version=\"1.13.0\"" + }, + { + "key": "Export-Package", + "value": "io.micrometer.jakarta9.instrument.jms;uses:=\"io.micrometer.common,io.micrometer.common.docs,io.micrometer.common.lang,io.micrometer.observation,io.micrometer.observation.docs,io.micrometer.observation.transport,jakarta.jms\";version=\"1.13.0\"" + }, + { + "key": "Full-Change", + "value": "639c93af0d0507b4cfa0e0581146719863b691b1" + }, + { + "key": "Gradle-Version", + "value": "8.6" + }, + { + "key": "Implementation-Title", + "value": "io.micrometer#micrometer-jakarta9;1.13.0-M1" + }, + { + "key": "Implementation-Version", + "value": "1.13.0-M1" + }, + { + "key": "Import-Package", + "value": "io.micrometer.common;version=\"[1.13,2)\",io.micrometer.common.docs;version=\"[1.13,2)\",io.micrometer.common.lang;version=\"[1.13,2)\"" + }, + { + "key": "Module-Email", + "value": "tludwig@vmware.com" + }, + { + "key": "Module-Origin", + "value": "git@github.com:micrometer-metrics/micrometer.git" + }, + { + "key": "Module-Owner", + "value": "tludwig@vmware.com" + }, + { + "key": "Module-Source", + "value": "/micrometer-jakarta9" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.4.0.202211291949" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "74087b670cad9f9883228ee2aa871f51b53f827a" + } + ] + } + }, + { + "id": "26b8a84479010ca8", + "name": "micrometer-observation", + "version": "1.13.0-M1", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-observation-1.13.0-M1.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-observation-1.13.0-M1.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:micrometer-observation:micrometer-observation:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer-observation:micrometer_observation:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer_observation:micrometer-observation:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer_observation:micrometer_observation:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer:micrometer-observation:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:micrometer:micrometer_observation:1.13.0-M1:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/io.micrometer/micrometer-observation@1.13.0-M1", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/micrometer-observation-1.13.0-M1.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "micrometer.observation" + }, + { + "key": "Bnd-LastModified", + "value": "1707769856490" + }, + { + "key": "Branch", + "value": "HEAD" + }, + { + "key": "Build-Date", + "value": "2024-02-12_20:30:25" + }, + { + "key": "Build-Date-UTC", + "value": "2024-02-12T20:30:25.426326246Z" + }, + { + "key": "Build-Host", + "value": "bea640c5c9a6" + }, + { + "key": "Build-Id", + "value": "30241" + }, + { + "key": "Build-Java-Version", + "value": "21" + }, + { + "key": "Build-Job", + "value": "deploy" + }, + { + "key": "Build-Number", + "value": "30241" + }, + { + "key": "Build-Timezone", + "value": "Etc/UTC" + }, + { + "key": "Build-Url", + "value": "https://circleci.com/gh/micrometer-metrics/micrometer/30241" + }, + { + "key": "Built-By", + "value": "circleci" + }, + { + "key": "Built-OS", + "value": "Linux" + }, + { + "key": "Built-Status", + "value": "candidate" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "micrometer-observation" + }, + { + "key": "Bundle-SymbolicName", + "value": "micrometer-observation" + }, + { + "key": "Bundle-Version", + "value": "1.13.0.M1" + }, + { + "key": "Change", + "value": "639c93a" + }, + { + "key": "Created-By", + "value": "21.0.2 (Eclipse Adoptium)" + }, + { + "key": "Export-Package", + "value": "io.micrometer.observation;uses:=\"io.micrometer.common,io.micrometer.common.lang\";version=\"1.13.0\",io.micrometer.observation.annotation;version=\"1.13.0\",io.micrometer.observation.aop;uses:=\"io.micrometer.common.lang,io.micrometer.observation,org.aspectj.lang,org.aspectj.lang.annotation\";version=\"1.13.0\",io.micrometer.observation.contextpropagation;uses:=\"io.micrometer.context,io.micrometer.observation\";version=\"1.13.0\",io.micrometer.observation.docs;uses:=\"io.micrometer.common.docs,io.micrometer.common.lang,io.micrometer.observation\";version=\"1.13.0\",io.micrometer.observation.transport;uses:=\"io.micrometer.common.lang,io.micrometer.observation\";version=\"1.13.0\"" + }, + { + "key": "Full-Change", + "value": "639c93af0d0507b4cfa0e0581146719863b691b1" + }, + { + "key": "Gradle-Version", + "value": "8.6" + }, + { + "key": "Implementation-Title", + "value": "io.micrometer#micrometer-observation;1.13.0-M1" + }, + { + "key": "Implementation-Version", + "value": "1.13.0-M1" + }, + { + "key": "Import-Package", + "value": "io.micrometer.context;resolution:=optional,org.aspectj.lang;resolution:=optional,org.aspectj.lang.annotation;resolution:=optional,org.aspectj.lang.reflect;resolution:=optional,io.micrometer.common;version=\"[1.13,2)\",io.micrometer.common.docs;version=\"[1.13,2)\",io.micrometer.common.lang;version=\"[1.13,2)\",io.micrometer.common.util;version=\"[1.13,2)\",io.micrometer.common.util.internal.logging;version=\"[1.13,2)\",io.micrometer.observation,io.micrometer.observation.annotation,io.micrometer.observation.docs" + }, + { + "key": "Module-Email", + "value": "tludwig@vmware.com" + }, + { + "key": "Module-Origin", + "value": "git@github.com:micrometer-metrics/micrometer.git" + }, + { + "key": "Module-Owner", + "value": "tludwig@vmware.com" + }, + { + "key": "Module-Source", + "value": "/micrometer-observation" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.4.0.202211291949" + }, + { + "key": "X-Compile-Source-JDK", + "value": "1.8" + }, + { + "key": "X-Compile-Target-JDK", + "value": "1.8" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "c06e5e0f9b6edc9c0c0ac3dd46a2117ce6f16a9d" + } + ] + } + }, + { + "id": "93ed082a147d9796", + "name": "sbom-test-gradle", + "version": "0.0.1-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:sbom-test-gradle:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test-gradle:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test_gradle:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test_gradle:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:JarLauncher:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:JarLauncher:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test-gradle:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test_gradle:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:JarLauncher:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:launch:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:launch:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:loader:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:loader:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test-gradle:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test-gradle:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test_gradle:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test_gradle:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test-gradle:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom:sbom-test-gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom:sbom_test_gradle:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test_gradle:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:JarLauncher:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:JarLauncher:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:launch:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:loader:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:JarLauncher:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom:JarLauncher:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom-test:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom_test:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:launch:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:launch:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:loader:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:loader:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:launch:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:loader:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom:launch:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom:loader:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:sbom:boot:0.0.1-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework.boot.loader.launch.JarLauncher/sbom-test-gradle@0.0.1-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Main-Class", + "value": "org.springframework.boot.loader.launch.JarLauncher" + }, + { + "key": "Start-Class", + "value": "com.example.sbomtestgradle.SbomTestGradleApplication" + }, + { + "key": "Spring-Boot-Version", + "value": "3.3.0-SNAPSHOT" + }, + { + "key": "Spring-Boot-Classes", + "value": "BOOT-INF/classes/" + }, + { + "key": "Spring-Boot-Lib", + "value": "BOOT-INF/lib/" + }, + { + "key": "Spring-Boot-Classpath-Index", + "value": "BOOT-INF/classpath.idx" + }, + { + "key": "Spring-Boot-Layers-Index", + "value": "BOOT-INF/layers.idx" + }, + { + "key": "Build-Jdk-Spec", + "value": "17" + }, + { + "key": "Implementation-Title", + "value": "sbom-test-gradle" + }, + { + "key": "Implementation-Version", + "value": "0.0.1-SNAPSHOT" + }, + { + "key": "Sbom-Location", + "value": "META-INF/sbom/bom.json" + }, + { + "key": "Sbom-Format", + "value": "CycloneDX" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "8ccd6688e9d8e15d18e0f10967867e5e30729a4c" + } + ] + } + }, + { + "id": "44752cfa6770756d", + "name": "slf4j-api", + "version": "2.0.11", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/slf4j-api-2.0.11.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.opensource.org/licenses/mit-license.php", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/slf4j-api-2.0.11.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:slf4j-api:slf4j-api:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:slf4j-api:slf4j_api:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:slf4j_api:slf4j-api:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:slf4j_api:slf4j_api:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:slf4j:slf4j-api:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:slf4j:slf4j_api:2.0.11:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.slf4j/slf4j-api@2.0.11", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/slf4j-api-2.0.11.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.9" + }, + { + "key": "Build-Jdk-Spec", + "value": "21" + }, + { + "key": "Bundle-Description", + "value": "The slf4j API" + }, + { + "key": "Bundle-DocURL", + "value": "http://www.slf4j.org" + }, + { + "key": "Bundle-License", + "value": "http://www.opensource.org/licenses/mit-license.php" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "SLF4J API Module" + }, + { + "key": "Bundle-SymbolicName", + "value": "slf4j.api" + }, + { + "key": "Bundle-Vendor", + "value": "SLF4J.ORG" + }, + { + "key": "Bundle-Version", + "value": "2.0.11" + }, + { + "key": "Export-Package", + "value": "org.slf4j;uses:=\"org.slf4j.event,org.slf4j.helpers,org.slf4j.spi\";version=\"2.0.11\",org.slf4j.event;uses:=\"org.slf4j,org.slf4j.helpers\";version=\"2.0.11\",org.slf4j.helpers;uses:=\"org.slf4j,org.slf4j.event,org.slf4j.spi\";version=\"2.0.11\",org.slf4j.spi;uses:=\"org.slf4j,org.slf4j.event,org.slf4j.helpers\";version=\"2.0.11\",org.slf4j;version=\"1.7.36\",org.slf4j.helpers;version=\"1.7.36\"" + }, + { + "key": "Implementation-Title", + "value": "slf4j-api" + }, + { + "key": "Implementation-Version", + "value": "2.0.11" + }, + { + "key": "Import-Package", + "value": "org.slf4j.spi;version=\"[2.0.11,3)\"" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Require-Capability", + "value": "osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))\",osgi.serviceloader;filter:=\"(osgi.serviceloader=org.slf4j.spi.SLF4JServiceProvider)\";osgi.serviceloader=\"org.slf4j.spi.SLF4JServiceProvider\",osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + }, + { + "key": "X-Compile-Source-JDK", + "value": "8" + }, + { + "key": "X-Compile-Target-JDK", + "value": "8" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/org.slf4j/slf4j-api/pom.properties", + "name": "", + "groupId": "org.slf4j", + "artifactId": "slf4j-api", + "version": "2.0.11" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "ad96c3f8cf895e696dd35c2bc8e8ebe710be9e6d" + } + ] + } + }, + { + "id": "f4585c65c0a5b26a", + "name": "snakeyaml", + "version": "2.2", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/snakeyaml-2.2.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "http://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/snakeyaml-2.2.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:snakeyaml:snakeyaml:2.2:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:yaml:snakeyaml:2.2:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.yaml/snakeyaml@2.2", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/snakeyaml-2.2.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bnd-LastModified", + "value": "1693124775469" + }, + { + "key": "Build-Jdk-Spec", + "value": "11" + }, + { + "key": "Bundle-Description", + "value": "YAML 1.1 parser and emitter for Java" + }, + { + "key": "Bundle-License", + "value": "http://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "SnakeYAML" + }, + { + "key": "Bundle-SymbolicName", + "value": "org.yaml.snakeyaml" + }, + { + "key": "Bundle-Version", + "value": "2.2.0" + }, + { + "key": "Created-By", + "value": "Apache Maven Bundle Plugin 5.1.8" + }, + { + "key": "Export-Package", + "value": "org.yaml.snakeyaml;version=\"2.2\",org.yaml.snakeyaml.comments;version=\"2.2\",org.yaml.snakeyaml.composer;version=\"2.2\",org.yaml.snakeyaml.constructor;version=\"2.2\",org.yaml.snakeyaml.emitter;version=\"2.2\",org.yaml.snakeyaml.env;version=\"2.2\",org.yaml.snakeyaml.error;version=\"2.2\",org.yaml.snakeyaml.events;version=\"2.2\",org.yaml.snakeyaml.extensions.compactnotation;version=\"2.2\",org.yaml.snakeyaml.inspector;version=\"2.2\",org.yaml.snakeyaml.internal;version=\"2.2\",org.yaml.snakeyaml.introspector;version=\"2.2\",org.yaml.snakeyaml.nodes;version=\"2.2\",org.yaml.snakeyaml.parser;version=\"2.2\",org.yaml.snakeyaml.reader;version=\"2.2\",org.yaml.snakeyaml.representer;version=\"2.2\",org.yaml.snakeyaml.resolver;version=\"2.2\",org.yaml.snakeyaml.scanner;version=\"2.2\",org.yaml.snakeyaml.serializer;version=\"2.2\",org.yaml.snakeyaml.tokens;version=\"2.2\",org.yaml.snakeyaml.util;version=\"2.2\"" + }, + { + "key": "Import-Package", + "value": "org.yaml.snakeyaml;version=\"[2.2,3)\",org.yaml.snakeyaml.comments;version=\"[2.2,3)\",org.yaml.snakeyaml.composer;version=\"[2.2,3)\",org.yaml.snakeyaml.emitter;version=\"[2.2,3)\",org.yaml.snakeyaml.error;version=\"[2.2,3)\",org.yaml.snakeyaml.events;version=\"[2.2,3)\",org.yaml.snakeyaml.inspector;version=\"[2.2,3)\",org.yaml.snakeyaml.internal;version=\"[2.2,3)\",org.yaml.snakeyaml.introspector;version=\"[2.2,3)\",org.yaml.snakeyaml.nodes;version=\"[2.2,3)\",org.yaml.snakeyaml.parser;version=\"[2.2,3)\",org.yaml.snakeyaml.reader;version=\"[2.2,3)\",org.yaml.snakeyaml.resolver;version=\"[2.2,3)\",org.yaml.snakeyaml.scanner;version=\"[2.2,3)\",org.yaml.snakeyaml.serializer;version=\"[2.2,3)\",org.yaml.snakeyaml.tokens;version=\"[2.2,3)\"" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Require-Capability", + "value": "osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.7))\"" + }, + { + "key": "Tool", + "value": "Bnd-6.3.1.202206071316" + } + ] + }, + "pomProperties": { + "path": "META-INF/maven/org.yaml/snakeyaml/pom.properties", + "name": "", + "groupId": "org.yaml", + "artifactId": "snakeyaml", + "version": "2.2" + }, + "digest": [ + { + "algorithm": "sha1", + "value": "3af797a25458550a16bf89acc8e4ab2b7f2bfce0" + } + ] + } + }, + { + "id": "1e7758a78bbc15ee", + "name": "spring-aop", + "version": "6.1.4-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-aop-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-aop-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + }, + { + "value": "BSD-3-Clause", + "spdxExpression": "BSD-3-Clause", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-aop-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:springframework:spring-aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-aop:spring-aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-aop:spring_aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_aop:spring-aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_aop:spring_aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_aop:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework/spring-aop@6.1.4-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-aop-6.1.4-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Implementation-Title", + "value": "spring-aop" + }, + { + "key": "Implementation-Version", + "value": "6.1.4-SNAPSHOT" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.aop" + }, + { + "key": "Created-By", + "value": "17.0.10 (Oracle Corporation)" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "b02165904562fc487cde57ca75e063561d905f74" + } + ] + } + }, + { + "id": "bb7e773a923726bb", + "name": "spring-beans", + "version": "6.1.4-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-beans-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-beans-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + }, + { + "value": "BSD-3-Clause", + "spdxExpression": "BSD-3-Clause", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-beans-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:springframework:spring-beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-beans:spring-beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-beans:spring_beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_beans:spring-beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_beans:spring_beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_beans:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework/spring-beans@6.1.4-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-beans-6.1.4-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Implementation-Title", + "value": "spring-beans" + }, + { + "key": "Implementation-Version", + "value": "6.1.4-SNAPSHOT" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.beans" + }, + { + "key": "Created-By", + "value": "17.0.10 (Oracle Corporation)" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "fa8be0f856958fdd33eef9e718b3a65f7130bbd2" + } + ] + } + }, + { + "id": "a11948291446c2f5", + "name": "spring-boot", + "version": "3.3.0-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:springframework:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring-boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring_boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework.boot/spring-boot@3.3.0-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-3.3.0-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.boot" + }, + { + "key": "Build-Jdk-Spec", + "value": "17" + }, + { + "key": "Built-By", + "value": "Spring" + }, + { + "key": "Implementation-Title", + "value": "Spring Boot" + }, + { + "key": "Implementation-Version", + "value": "3.3.0-SNAPSHOT" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "d882660ea3deafe921faba8b17e7d94ef9556c47" + } + ] + } + }, + { + "id": "f83d629168e25cce", + "name": "spring-boot-actuator", + "version": "3.3.0-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-actuator-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-actuator-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:spring-boot-actuator:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-actuator:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring-boot-actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring_boot_actuator:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-actuator:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework.boot/spring-boot-actuator@3.3.0-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-actuator-3.3.0-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.boot.actuator" + }, + { + "key": "Build-Jdk-Spec", + "value": "17" + }, + { + "key": "Built-By", + "value": "Spring" + }, + { + "key": "Implementation-Title", + "value": "Spring Boot Actuator" + }, + { + "key": "Implementation-Version", + "value": "3.3.0-SNAPSHOT" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "d0d018780795da57afa8edae7436646bccd55722" + } + ] + } + }, + { + "id": "b8eb893518786bb8", + "name": "spring-boot-actuator-autoconfigure", + "version": "3.3.0-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-actuator-autoconfigure-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-actuator-autoconfigure-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:spring-boot-actuator-autoconfigure:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-actuator-autoconfigure:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator_autoconfigure:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator_autoconfigure:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-actuator:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-actuator:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring-boot-actuator-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring_boot_actuator_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-actuator-autoconfigure:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator_autoconfigure:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-actuator:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_actuator:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@3.3.0-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-actuator-autoconfigure-3.3.0-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.boot.actuator.autoconfigure" + }, + { + "key": "Build-Jdk-Spec", + "value": "17" + }, + { + "key": "Built-By", + "value": "Spring" + }, + { + "key": "Implementation-Title", + "value": "Spring Boot Actuator AutoConfigure" + }, + { + "key": "Implementation-Version", + "value": "3.3.0-SNAPSHOT" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "8b8f74be822e6f2ab120ea0687acf629ef114399" + } + ] + } + }, + { + "id": "b40bdc90eb8832a3", + "name": "spring-boot-autoconfigure", + "version": "3.3.0-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-autoconfigure-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-autoconfigure-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:spring-boot-autoconfigure:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-autoconfigure:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_autoconfigure:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_autoconfigure:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring-boot-autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring_boot_autoconfigure:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-autoconfigure:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_autoconfigure:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.3.0-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-autoconfigure-3.3.0-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.boot.autoconfigure" + }, + { + "key": "Build-Jdk-Spec", + "value": "17" + }, + { + "key": "Built-By", + "value": "Spring" + }, + { + "key": "Implementation-Title", + "value": "Spring Boot AutoConfigure" + }, + { + "key": "Implementation-Version", + "value": "3.3.0-SNAPSHOT" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "31a960bb63af836f35760077af8ef58d24b548e3" + } + ] + } + }, + { + "id": "8069f3f866b2e657", + "name": "spring-boot-jarmode-layertools", + "version": "3.3.0-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-jarmode-layertools-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-jarmode-layertools-3.3.0-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:spring-boot-jarmode-layertools:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-jarmode-layertools:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_jarmode_layertools:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_jarmode_layertools:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-jarmode:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-jarmode:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_jarmode:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_jarmode:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring-boot-jarmode-layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:spring_boot_jarmode_layertools:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-jarmode-layertools:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_jarmode_layertools:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot-jarmode:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot_jarmode:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:boot:boot:3.3.0-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework.boot/spring-boot-jarmode-layertools@3.3.0-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-boot-jarmode-layertools-3.3.0-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.boot.jarmode.layertools" + }, + { + "key": "Build-Jdk-Spec", + "value": "17" + }, + { + "key": "Built-By", + "value": "Spring" + }, + { + "key": "Implementation-Title", + "value": "Spring Boot Layers Tools" + }, + { + "key": "Implementation-Version", + "value": "3.3.0-SNAPSHOT" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "d86f1782ad3d9ee047863a5023aaa22f858cd9a4" + } + ] + } + }, + { + "id": "3d5d71e0e85398af", + "name": "spring-context", + "version": "6.1.4-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-context-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-context-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + }, + { + "value": "BSD-3-Clause", + "spdxExpression": "BSD-3-Clause", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-context-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:springframework:spring-context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-context:spring-context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-context:spring_context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_context:spring-context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_context:spring_context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_context:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework/spring-context@6.1.4-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-context-6.1.4-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Implementation-Title", + "value": "spring-context" + }, + { + "key": "Implementation-Version", + "value": "6.1.4-SNAPSHOT" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.context" + }, + { + "key": "Created-By", + "value": "17.0.10 (Oracle Corporation)" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "75440f70a649ca15948af5923ebdef345848a856" + } + ] + } + }, + { + "id": "519fe54307d2d43d", + "name": "spring-core", + "version": "6.1.4-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-core-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-core-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + }, + { + "value": "BSD-3-Clause", + "spdxExpression": "BSD-3-Clause", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-core-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:springsource-spring-framework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource_spring_framework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource-spring:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource_spring:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:pivotal_software:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-framework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_framework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource-spring-framework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource_spring_framework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-core:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_core:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource-spring-framework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource-spring-framework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource_spring_framework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource_spring_framework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource-spring:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource_spring:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:vmware:springsource_spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:pivotal_software:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-framework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_framework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource-spring:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource-spring:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource_spring:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource_spring:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:pivotal_software:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:pivotal_software:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-core:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-framework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-framework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_core:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_framework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_framework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springsource:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-core:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-core:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_core:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_core:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:vmware:spring_framework:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:vmware:spring-core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:vmware:spring_core:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework/spring-core@6.1.4-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-core-6.1.4-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Implementation-Title", + "value": "spring-core" + }, + { + "key": "Implementation-Version", + "value": "6.1.4-SNAPSHOT" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.core" + }, + { + "key": "Created-By", + "value": "17.0.10 (Oracle Corporation)" + }, + { + "key": "Multi-Release", + "value": "true" + }, + { + "key": "Dependencies", + "value": "jdk.unsupported,org.jboss.vfs" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "27d0900a14e240a7311c979e7b30cf65f9de9074" + } + ] + } + }, + { + "id": "546794e924e39088", + "name": "spring-expression", + "version": "6.1.4-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-expression-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-expression-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + }, + { + "value": "BSD-3-Clause", + "spdxExpression": "BSD-3-Clause", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-expression-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:spring-expression:spring-expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-expression:spring_expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_expression:spring-expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_expression:spring_expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring-expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_expression:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework/spring-expression@6.1.4-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-expression-6.1.4-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Implementation-Title", + "value": "spring-expression" + }, + { + "key": "Implementation-Version", + "value": "6.1.4-SNAPSHOT" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.expression" + }, + { + "key": "Created-By", + "value": "17.0.10 (Oracle Corporation)" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "a5d7041ca11fd188e9d17ac8a795eabed8be55e4" + } + ] + } + }, + { + "id": "173ea637a5756944", + "name": "spring-jcl", + "version": "6.1.4-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-jcl-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-jcl-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + }, + { + "value": "BSD-3-Clause", + "spdxExpression": "BSD-3-Clause", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-jcl-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:springframework:spring-jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-jcl:spring-jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-jcl:spring_jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_jcl:spring-jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_jcl:spring_jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_jcl:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework/spring-jcl@6.1.4-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-jcl-6.1.4-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Implementation-Title", + "value": "spring-jcl" + }, + { + "key": "Implementation-Version", + "value": "6.1.4-SNAPSHOT" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.jcl" + }, + { + "key": "Created-By", + "value": "17.0.10 (Oracle Corporation)" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "604cea28d23d8027a31c35f372d2b8d0fdec211d" + } + ] + } + }, + { + "id": "adc63cefcede34fc", + "name": "spring-web", + "version": "6.1.4-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-web-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-web-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + }, + { + "value": "BSD-3-Clause", + "spdxExpression": "BSD-3-Clause", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-web-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:springframework:spring-web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-web:spring-web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-web:spring_web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_web:spring-web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_web:spring_web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_web:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework/spring-web@6.1.4-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-web-6.1.4-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Implementation-Title", + "value": "spring-web" + }, + { + "key": "Implementation-Version", + "value": "6.1.4-SNAPSHOT" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.web" + }, + { + "key": "Created-By", + "value": "17.0.10 (Oracle Corporation)" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "c0600dcd73db226c3d121af16d6a155ecee08d30" + } + ] + } + }, + { + "id": "940aed7082581b67", + "name": "spring-webmvc", + "version": "6.1.4-SNAPSHOT", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-webmvc-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "Apache-2.0", + "spdxExpression": "Apache-2.0", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-webmvc-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + }, + { + "value": "BSD-3-Clause", + "spdxExpression": "BSD-3-Clause", + "type": "concluded", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-webmvc-6.1.4-SNAPSHOT.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:springframework:spring-webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:springframework:spring_webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-webmvc:spring-webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring-webmvc:spring_webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_webmvc:spring-webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring_webmvc:spring_webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring-webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:spring:spring_webmvc:6.1.4-SNAPSHOT:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.springframework/spring-webmvc@6.1.4-SNAPSHOT", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/spring-webmvc-6.1.4-SNAPSHOT.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Implementation-Title", + "value": "spring-webmvc" + }, + { + "key": "Implementation-Version", + "value": "6.1.4-SNAPSHOT" + }, + { + "key": "Automatic-Module-Name", + "value": "spring.webmvc" + }, + { + "key": "Created-By", + "value": "17.0.10 (Oracle Corporation)" + } + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "34a510cf565bec1c2f74f049b1730b22f877bd37" + } + ] + } + }, + { + "id": "a753aca6ee68c738", + "name": "tomcat-embed-core", + "version": "10.1.18", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-core-10.1.18.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-core-10.1.18.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:apache:tomcat-embed-core:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:tomcat_embed_core:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:tomcat:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:embed:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@10.1.18", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-core-10.1.18.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-License", + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "tomcat-embed-core" + }, + { + "key": "Bundle-SymbolicName", + "value": "org.apache.tomcat-embed-core" + }, + { + "key": "Bundle-Version", + "value": "10.1.18" + }, + { + "key": "Export-Package", + "value": "jakarta.security.auth.message;version=\"3.0\";uses:=\"javax.security.auth,javax.security.auth.login\",jakarta.security.auth.message.callback;version=\"3.0\";uses:=\"javax.crypto,javax.security.auth,javax.security.auth.callback,javax.security.auth.x500\",jakarta.security.auth.message.config;version=\"3.0\";uses:=\"jakarta.security.auth.message,jakarta.security.auth.message.module,javax.security.auth,javax.security.auth.callback\",jakarta.security.auth.message.module;version=\"3.0\";uses:=\"jakarta.security.auth.message,javax.security.auth.callback\",jakarta.servlet;version=\"6.0\";uses:=\"jakarta.servlet.annotation,jakarta.servlet.descriptor\",jakarta.servlet.annotation;version=\"6.0\";uses:=\"jakarta.servlet\",jakarta.servlet.descriptor;version=\"6.0\",jakarta.servlet.http;version=\"6.0\";uses:=\"jakarta.servlet\",jakarta.servlet.resources;version=\"6.0\",org.apache.catalina;uses:=\"jakarta.servlet,jakarta.servlet.descriptor,jakarta.servlet.http,javax.management,javax.naming,org.apache.catalina.connector,org.apache.catalina.deploy,org.apache.catalina.mapper,org.apache.catalina.startup,org.apache.juli.logging,org.apache.tomcat,org.apache.tomcat.util.descriptor.web,org.apache.tomcat.util.file,org.apache.tomcat.util.http,org.ietf.jgss\";version=\"10.1.18\",org.apache.catalina.authenticator;uses:=\"jakarta.security.auth.message.config,jakarta.servlet,jakarta.servlet.http,org.apache.catalina,org.apache.catalina.connector,org.apache.catalina.util,org.apache.catalina.valves,org.apache.tomcat.util.buf,org.apache.tomcat.util.descriptor.web,org.apache.tomcat.util.res,org.ietf.jgss\";version=\"10.1.18\",org.apache.catalina.authenticator.jaspic;uses:=\"jakarta.security.auth.message,jakarta.security.auth.message.config,jakarta.security.auth.message.module,jakarta.servlet.http,javax.security.auth,javax.security.auth.callback,org.apache.catalina,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.connector;uses:=\"jakarta.servlet,jakarta.servlet.http,javax.security.auth,org.apache.catalina,org.apache.catalina.core,org.apache.catalina.mapper,org.apache.catalina.util,org.apache.coyote,org.apache.tomcat.util.buf,org.apache.tomcat.util.http,org.apache.tomcat.util.net,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.core;uses:=\"jakarta.servlet,jakarta.servlet.descriptor,jakarta.servlet.http,javax.management,javax.naming,org.apache.catalina,org.apache.catalina.connector,org.apache.catalina.deploy,org.apache.catalina.mapper,org.apache.catalina.startup,org.apache.catalina.util,org.apache.coyote,org.apache.juli.logging,org.apache.naming,org.apache.tomcat,org.apache.tomcat.util.descriptor.web,org.apache.tomcat.util.http,org.apache.tomcat.util.http.fileupload,org.apache.tomcat.util.res,org.apache.tomcat.util.threads\";version=\"10.1.18\",org.apache.catalina.deploy;uses:=\"org.apache.catalina,org.apache.catalina.util,org.apache.tomcat.util.descriptor.web\";version=\"10.1.18\",org.apache.catalina.filters;uses:=\"jakarta.servlet,jakarta.servlet.http,org.apache.juli.logging,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.loader;uses:=\"org.apache.catalina,org.apache.catalina.util,org.apache.juli,org.apache.tomcat,org.apache.tomcat.util.res,org.apache.tomcat.util.security\";version=\"10.1.18\",org.apache.catalina.manager;uses:=\"jakarta.servlet,jakarta.servlet.http,javax.management,javax.naming,org.apache.catalina,org.apache.catalina.util,org.apache.tomcat.util.modeler,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.manager.host;uses:=\"jakarta.servlet,jakarta.servlet.http,org.apache.catalina,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.manager.util;uses:=\"jakarta.servlet.http,org.apache.catalina\";version=\"10.1.18\",org.apache.catalina.mapper;uses:=\"jakarta.servlet.http,org.apache.catalina,org.apache.catalina.util,org.apache.tomcat.util.buf\";version=\"10.1.18\",org.apache.catalina.mbeans;uses:=\"javax.management,javax.naming,org.apache.catalina,org.apache.catalina.connector,org.apache.catalina.core,org.apache.tomcat.util.descriptor.web,org.apache.tomcat.util.modeler,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.realm;uses:=\"javax.management,javax.naming,javax.naming.directory,javax.net.ssl,javax.security.auth,javax.security.auth.callback,javax.security.auth.login,javax.security.auth.spi,org.apache.catalina,org.apache.catalina.connector,org.apache.catalina.util,org.apache.juli.logging,org.apache.tomcat.util.collections,org.apache.tomcat.util.descriptor.web,org.apache.tomcat.util.digester,org.apache.tomcat.util.res,org.ietf.jgss\";version=\"10.1.18\",org.apache.catalina.security;uses:=\"jakarta.servlet,org.apache.catalina\";version=\"10.1.18\",org.apache.catalina.servlets;uses:=\"jakarta.servlet,jakarta.servlet.http,javax.xml.parsers,javax.xml.transform,org.apache.catalina,org.apache.tomcat.util.http,org.apache.tomcat.util.http.parser,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.session;uses:=\"jakarta.servlet,jakarta.servlet.http,javax.sql,org.apache.catalina,org.apache.catalina.util,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.startup;uses:=\"jakarta.annotation,jakarta.servlet,jakarta.servlet.descriptor,javax.management,org.apache.catalina,org.apache.catalina.connector,org.apache.catalina.core,org.apache.catalina.deploy,org.apache.catalina.util,org.apache.juli.logging,org.apache.tomcat,org.apache.tomcat.util.bcel.classfile,org.apache.tomcat.util.descriptor.web,org.apache.tomcat.util.digester,org.apache.tomcat.util.file,org.apache.tomcat.util.http,org.apache.tomcat.util.res,org.xml.sax\";version=\"10.1.18\",org.apache.catalina.users;uses:=\"javax.naming,javax.naming.spi,javax.sql,org.apache.catalina\";version=\"10.1.18\",org.apache.catalina.util;uses:=\"jakarta.servlet.http,javax.management,org.apache.catalina,org.apache.juli.logging,org.apache.tomcat.util.descriptor.web,org.w3c.dom\";version=\"10.1.18\",org.apache.catalina.valves;uses:=\"jakarta.servlet,org.apache.catalina,org.apache.catalina.connector,org.apache.catalina.util,org.apache.juli.logging,org.apache.tomcat.util.descriptor.web,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.valves.rewrite;uses:=\"jakarta.servlet,org.apache.catalina,org.apache.catalina.connector,org.apache.catalina.valves,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.webresources;uses:=\"org.apache.catalina,org.apache.catalina.util,org.apache.juli.logging,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.webresources.war;version=\"10.1.18\",org.apache.coyote;uses:=\"jakarta.servlet,jakarta.servlet.http,javax.management,org.apache.coyote.http11,org.apache.coyote.http11.upgrade,org.apache.juli.logging,org.apache.tomcat,org.apache.tomcat.util.buf,org.apache.tomcat.util.collections,org.apache.tomcat.util.http,org.apache.tomcat.util.log,org.apache.tomcat.util.modeler,org.apache.tomcat.util.net\";version=\"10.1.18\",org.apache.coyote.ajp;uses:=\"jakarta.servlet,org.apache.coyote,org.apache.juli.logging,org.apache.tomcat.util.buf,org.apache.tomcat.util.net,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.coyote.http11;uses:=\"jakarta.servlet,javax.management,org.apache.coyote,org.apache.coyote.http11.upgrade,org.apache.juli.logging,org.apache.tomcat.util.buf,org.apache.tomcat.util.http.parser,org.apache.tomcat.util.net,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.coyote.http11.filters;uses:=\"org.apache.coyote,org.apache.coyote.http11,org.apache.juli.logging,org.apache.tomcat.util.buf,org.apache.tomcat.util.net\";version=\"10.1.18\",org.apache.coyote.http11.upgrade;uses:=\"jakarta.servlet,jakarta.servlet.http,org.apache.coyote,org.apache.juli.logging,org.apache.tomcat.util.modeler,org.apache.tomcat.util.net\";version=\"10.1.18\",org.apache.coyote.http2;uses:=\"jakarta.servlet,jakarta.servlet.http,org.apache.coyote,org.apache.coyote.http11,org.apache.coyote.http11.upgrade,org.apache.tomcat.util.http.parser,org.apache.tomcat.util.net,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.juli;version=\"10.1.18\",org.apache.juli.logging;version=\"10.1.18\",org.apache.naming;uses:=\"javax.naming\";version=\"10.1.18\",org.apache.naming.factory;uses:=\"javax.naming,javax.naming.spi,javax.sql,org.apache.naming\";version=\"10.1.18\",org.apache.naming.java;uses:=\"javax.naming,javax.naming.spi\";version=\"10.1.18\",org.apache.tomcat;uses:=\"jakarta.servlet,javax.naming\";version=\"10.1.18\",org.apache.tomcat.jni;version=\"10.1.18\",org.apache.tomcat.util;uses:=\"org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.tomcat.util.bcel.classfile;version=\"10.1.18\",org.apache.tomcat.util.buf;uses:=\"org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.tomcat.util.codec.binary;uses:=\"org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.tomcat.util.collections;version=\"10.1.18\",org.apache.tomcat.util.compat;version=\"10.1.18\",org.apache.tomcat.util.descriptor;uses:=\"org.apache.juli.logging,org.apache.tomcat.util.digester,org.xml.sax,org.xml.sax.ext\";version=\"10.1.18\",org.apache.tomcat.util.descriptor.tagplugin;uses:=\"jakarta.servlet,org.xml.sax\";version=\"10.1.18\",org.apache.tomcat.util.descriptor.web;uses:=\"jakarta.servlet,jakarta.servlet.descriptor,org.apache.juli.logging,org.apache.tomcat,org.apache.tomcat.util.digester,org.apache.tomcat.util.res,org.xml.sax\";version=\"10.1.18\",org.apache.tomcat.util.digester;uses:=\"javax.xml.parsers,org.apache.juli.logging,org.apache.tomcat.util,org.apache.tomcat.util.res,org.xml.sax,org.xml.sax.ext\";version=\"10.1.18\",org.apache.tomcat.util.file;version=\"10.1.18\",org.apache.tomcat.util.http;uses:=\"jakarta.servlet.http,org.apache.tomcat.util.buf\";version=\"10.1.18\",org.apache.tomcat.util.http.fileupload;uses:=\"org.apache.tomcat.util.http.fileupload.impl,org.apache.tomcat.util.http.fileupload.util\";version=\"10.1.18\",org.apache.tomcat.util.http.fileupload.disk;uses:=\"org.apache.tomcat.util.http.fileupload\";version=\"10.1.18\",org.apache.tomcat.util.http.fileupload.impl;uses:=\"org.apache.tomcat.util.http.fileupload\";version=\"10.1.18\",org.apache.tomcat.util.http.fileupload.servlet;uses:=\"jakarta.servlet.http,org.apache.tomcat.util.http.fileupload\";version=\"10.1.18\",org.apache.tomcat.util.http.fileupload.util;uses:=\"org.apache.tomcat.util.http.fileupload\";version=\"10.1.18\",org.apache.tomcat.util.http.parser;uses:=\"org.apache.tomcat.util.buf,org.apache.tomcat.util.http\";version=\"10.1.18\",org.apache.tomcat.util.log;uses:=\"org.apache.juli.logging\";version=\"10.1.18\",org.apache.tomcat.util.modeler;uses:=\"javax.management,javax.management.modelmbean\";version=\"10.1.18\",org.apache.tomcat.util.modeler.modules;uses:=\"javax.management,org.apache.tomcat.util.modeler,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.tomcat.util.net;uses:=\"jakarta.servlet,javax.management,javax.net.ssl,org.apache.juli.logging,org.apache.tomcat.util.collections,org.apache.tomcat.util.net.openssl,org.apache.tomcat.util.net.openssl.ciphers,org.apache.tomcat.util.res,org.apache.tomcat.util.threads\";version=\"10.1.18\",org.apache.tomcat.util.net.openssl;uses:=\"javax.net.ssl,org.apache.juli.logging,org.apache.tomcat.util.net\";version=\"10.1.18\",org.apache.tomcat.util.net.openssl.ciphers;version=\"10.1.18\",org.apache.tomcat.util.res;version=\"10.1.18\",org.apache.tomcat.util.scan;uses:=\"jakarta.servlet,org.apache.tomcat\";version=\"10.1.18\",org.apache.tomcat.util.security;version=\"10.1.18\",org.apache.tomcat.util.threads;uses:=\"org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.catalina.ssi;version=\"10.1.18\"" + }, + { + "key": "Implementation-Title", + "value": "Apache Tomcat" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "10.1.18" + }, + { + "key": "Import-Package", + "value": "jakarta.annotation,jakarta.annotation.security,jakarta.ejb,jakarta.mail,jakarta.mail.internet,jakarta.persistence,jakarta.security.auth.message;version=\"[3.0,4)\",jakarta.security.auth.message.callback;version=\"[3.0,4)\",jakarta.security.auth.message.config;version=\"[3.0,4)\",jakarta.security.auth.message.module;version=\"[3.0,4)\",jakarta.servlet;version=\"[6.0,7)\",jakarta.servlet.annotation;version=\"[6.0,7)\",jakarta.servlet.descriptor;version=\"[6.0,7)\",jakarta.servlet.http;version=\"[6.0,7)\",jakarta.xml.ws,java.beans,java.io,java.lang,java.lang.annotation,java.lang.instrument,java.lang.invoke,java.lang.management,java.lang.module,java.lang.ref,java.lang.reflect,java.math,java.net,java.nio,java.nio.channels,java.nio.charset,java.nio.file,java.nio.file.attribute,java.rmi,java.security,java.security.cert,java.security.spec,java.sql,java.text,java.time,java.time.chrono,java.time.format,java.time.temporal,java.util,java.util.concurrent,java.util.concurrent.atomic,java.util.concurrent.locks,java.util.function,java.util.jar,java.util.logging,java.util.regex,java.util.stream,java.util.zip,javax.crypto,javax.crypto.spec,javax.imageio,javax.management,javax.management.loading,javax.management.modelmbean,javax.management.openmbean,javax.naming,javax.naming.directory,javax.naming.ldap,javax.naming.spi,javax.net.ssl,javax.security.auth,javax.security.auth.callback,javax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.sql,javax.wsdl,javax.wsdl.extensions,javax.wsdl.extensions.soap,javax.wsdl.factory,javax.wsdl.xml,javax.xml.namespace,javax.xml.parsers,javax.xml.rpc,javax.xml.rpc.handler,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.stream,org.apache.catalina,org.apache.catalina.authenticator,org.apache.catalina.authenticator.jaspic,org.apache.catalina.connector,org.apache.catalina.core,org.apache.catalina.deploy,org.apache.catalina.filters,org.apache.catalina.loader,org.apache.catalina.manager.util,org.apache.catalina.mapper,org.apache.catalina.mbeans,org.apache.catalina.realm,org.apache.catalina.security,org.apache.catalina.session,org.apache.catalina.startup,org.apache.catalina.util,org.apache.catalina.webresources,org.apache.catalina.webresources.war,org.apache.coyote,org.apache.coyote.ajp,org.apache.coyote.http11,org.apache.coyote.http11.filters,org.apache.coyote.http11.upgrade,org.apache.juli,org.apache.juli.logging,org.apache.naming,org.apache.naming.factory,org.apache.tomcat,org.apache.tomcat.jakartaee,org.apache.tomcat.jni,org.apache.tomcat.util,org.apache.tomcat.util.buf,org.apache.tomcat.util.codec.binary,org.apache.tomcat.util.collections,org.apache.tomcat.util.compat,org.apache.tomcat.util.descriptor,org.apache.tomcat.util.descriptor.web,org.apache.tomcat.util.digester,org.apache.tomcat.util.file,org.apache.tomcat.util.http,org.apache.tomcat.util.http.fileupload.disk,org.apache.tomcat.util.http.fileupload.impl,org.apache.tomcat.util.http.fileupload.servlet,org.apache.tomcat.util.http.fileupload.util,org.apache.tomcat.util.http.parser,org.apache.tomcat.util.log,org.apache.tomcat.util.modeler,org.apache.tomcat.util.modeler.modules,org.apache.tomcat.util.net.openssl.ciphers,org.apache.tomcat.util.res,org.apache.tomcat.util.scan,org.apache.tomcat.util.security,org.apache.tomcat.util.threads,org.ietf.jgss,org.w3c.dom,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers" + }, + { + "key": "Private-Package", + "value": "org.apache.naming.factory.webservices,org.apache.tomcat.util.bcel,org.apache.tomcat.util.http.fileupload.util.mime,org.apache.tomcat.util.json,org.apache.tomcat.util.net.jsse" + }, + { + "key": "Provide-Capability", + "value": "osgi.contract;osgi.contract=JavaJASPIC;version:Version=\"3.0\";uses:=\"jakarta.security.auth.message,jakarta.security.auth.message.callback,jakarta.security.auth.message.config,jakarta.security.auth.message.module\",osgi.contract;osgi.contract=JavaServlet;version:Version=\"6.0\";uses:=\"jakarta.servlet,jakarta.servlet.annotation,jakarta.servlet.descriptor,jakarta.servlet.http,jakarta.servlet.resources\"" + }, + { + "key": "Require-Capability", + "value": "osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))\",osgi.serviceloader;filter:=\"(osgi.serviceloader=org.apache.juli.logging.Log)\";osgi.serviceloader=\"org.apache.juli.logging.Log\",osgi.contract;osgi.contract=JakartaAnnotations;filter:=\"(&(osgi.contract=JakartaAnnotations)(version=2.1.0))\",osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=11))\"" + }, + { + "key": "Specification-Title", + "value": "Apache Tomcat" + }, + { + "key": "Specification-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Specification-Version", + "value": "10.1" + }, + { + "key": "X-Compile-Source-JDK", + "value": "11" + }, + { + "key": "X-Compile-Target-JDK", + "value": "11" + } + ], + "sections": [ + [ + { + "key": "Name", + "value": "jakarta/security/auth/message/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.security.auth.message" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "3.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Authentication SPI for Containers" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "3.0" + } + ], + [ + { + "key": "Name", + "value": "jakarta/security/auth/message/callback/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.security.auth.message" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "3.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Authentication SPI for Containers" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "3.0" + } + ], + [ + { + "key": "Name", + "value": "jakarta/security/auth/message/config/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.security.auth.message" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "3.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Authentication SPI for Containers" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "3.0" + } + ], + [ + { + "key": "Name", + "value": "jakarta/security/auth/message/module/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.security.auth.message" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "3.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Authentication SPI for Containers" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "3.0" + } + ], + [ + { + "key": "Name", + "value": "jakarta/servlet/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.servlet" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "6.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Servlet" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "6.0" + } + ], + [ + { + "key": "Name", + "value": "jakarta/servlet/annotation/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.servlet" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "6.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Servlet" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "6.0" + } + ], + [ + { + "key": "Name", + "value": "jakarta/servlet/descriptor/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.servlet" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "6.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Servlet" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "6.0" + } + ], + [ + { + "key": "Name", + "value": "jakarta/servlet/http/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.servlet" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "6.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Servlet" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "6.0" + } + ], + [ + { + "key": "Name", + "value": "jakarta/servlet/resources/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.servlet" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "6.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Servlet" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "6.0" + } + ] + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "bff6c34649d1dd7b509e819794d73ba795947dcf" + } + ] + } + }, + { + "id": "7a59d22722f7701b", + "name": "tomcat-embed-el", + "version": "10.1.18", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-el-10.1.18.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-el-10.1.18.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:apache:tomcat-embed-el:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:tomcat_embed_el:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:tomcat:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:embed:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.apache.tomcat.embed/tomcat-embed-el@10.1.18", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-el-10.1.18.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-License", + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "tomcat-embed-jasper-el" + }, + { + "key": "Bundle-SymbolicName", + "value": "org.apache.tomcat-embed-jasper-el" + }, + { + "key": "Bundle-Version", + "value": "10.1.18" + }, + { + "key": "Export-Package", + "value": "jakarta.el;version=\"5.0\",org.apache.el;uses:=\"jakarta.el,org.apache.el.parser\";version=\"10.1.18\",org.apache.el.lang;uses:=\"jakarta.el,org.apache.el.parser\";version=\"10.1.18\",org.apache.el.parser;uses:=\"jakarta.el,org.apache.el.lang\";version=\"10.1.18\"" + }, + { + "key": "Implementation-Title", + "value": "Apache Tomcat" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "10.1.18" + }, + { + "key": "Import-Package", + "value": "jakarta.el;version=\"[5.0,6)\",java.beans,java.io,java.lang,java.lang.annotation,java.lang.invoke,java.lang.ref,java.lang.reflect,java.math,java.security,java.text,java.util,java.util.concurrent,java.util.concurrent.locks,java.util.function" + }, + { + "key": "Private-Package", + "value": "org.apache.el.stream,org.apache.el.util" + }, + { + "key": "Provide-Capability", + "value": "osgi.contract;osgi.contract=JakartaExpressionLanguage;version:Version=\"5.0\";uses:=\"jakarta.el\",osgi.service;objectClass:List=\"jakarta.el.ExpressionFactory\";effective:=active,osgi.serviceloader;osgi.serviceloader=\"jakarta.el.ExpressionFactory\";register:=\"org.apache.el.ExpressionFactoryImpl\"" + }, + { + "key": "Require-Capability", + "value": "osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))\",osgi.serviceloader;filter:=\"(osgi.serviceloader=jakarta.el.ExpressionFactory)\";osgi.serviceloader=\"jakarta.el.ExpressionFactory\",osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\",osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.registrar)(version>=1.0.0)(!(version>=2.0.0)))\"" + }, + { + "key": "Specification-Title", + "value": "Apache Tomcat" + }, + { + "key": "Specification-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Specification-Version", + "value": "10.1" + }, + { + "key": "X-Compile-Source-JDK", + "value": "11" + }, + { + "key": "X-Compile-Target-JDK", + "value": "11" + } + ], + "sections": [ + [ + { + "key": "Name", + "value": "jakarta/el/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.annotation" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "5.0" + }, + { + "key": "Specification-Title", + "value": "Jakarta Expression Language" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "5.0" + } + ] + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "b2c4dc05abd363c63b245523bb071727aa2f1046" + } + ] + } + }, + { + "id": "6c04f8ee22f9157e", + "name": "tomcat-embed-websocket", + "version": "10.1.18", + "type": "java-archive", + "foundBy": "java-archive-cataloger", + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-websocket-10.1.18.jar", + "annotations": { + "evidence": "primary" + } + } + ], + "licenses": [ + { + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt", + "spdxExpression": "", + "type": "declared", + "urls": [], + "locations": [ + { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "accessPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-websocket-10.1.18.jar", + "annotations": { + "evidence": "primary" + } + } + ] + } + ], + "language": "java", + "cpes": [ + { + "cpe": "cpe:2.3:a:apache:tomcat-embed-websocket:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:tomcat_embed_websocket:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:tomcat:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + }, + { + "cpe": "cpe:2.3:a:apache:embed:10.1.18:*:*:*:*:*:*:*", + "source": "syft-generated" + } + ], + "purl": "pkg:maven/org.apache.tomcat.embed/tomcat-embed-websocket@10.1.18", + "metadataType": "java-archive", + "metadata": { + "virtualPath": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar:BOOT-INF/lib/tomcat-embed-websocket-10.1.18.jar", + "manifest": { + "main": [ + { + "key": "Manifest-Version", + "value": "1.0" + }, + { + "key": "Bundle-License", + "value": "https://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "key": "Bundle-ManifestVersion", + "value": "2" + }, + { + "key": "Bundle-Name", + "value": "tomcat-embed-websocket" + }, + { + "key": "Bundle-SymbolicName", + "value": "org.apache.tomcat-embed-websocket" + }, + { + "key": "Bundle-Version", + "value": "10.1.18" + }, + { + "key": "Export-Package", + "value": "jakarta.websocket;version=\"2.1\";uses:=\"javax.net.ssl\",jakarta.websocket.server;version=\"2.1\";uses:=\"jakarta.websocket\",org.apache.tomcat.websocket;uses:=\"jakarta.websocket,jakarta.websocket.server,javax.net.ssl,org.apache.juli.logging,org.apache.tomcat,org.apache.tomcat.util.res\";version=\"10.1.18\",org.apache.tomcat.websocket.server;uses:=\"jakarta.servlet,jakarta.servlet.annotation,jakarta.servlet.http,jakarta.websocket,jakarta.websocket.server,org.apache.coyote.http11.upgrade,org.apache.juli.logging,org.apache.tomcat,org.apache.tomcat.util.net,org.apache.tomcat.websocket\";version=\"10.1.18\"" + }, + { + "key": "Implementation-Title", + "value": "Apache Tomcat" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "10.1.18" + }, + { + "key": "Import-Package", + "value": "jakarta.servlet,jakarta.servlet.annotation,jakarta.servlet.http,jakarta.websocket;version=\"[2.1,3)\",jakarta.websocket.server;version=\"[2.1,3)\",java.io,java.lang,java.lang.annotation,java.lang.invoke,java.lang.reflect,java.net,java.nio,java.nio.channels,java.nio.charset,java.security,java.util,java.util.concurrent,java.util.concurrent.atomic,java.util.concurrent.locks,java.util.function,java.util.regex,java.util.zip,javax.naming,javax.net.ssl,org.apache.coyote.http11.upgrade;version=\"[10.1,11)\",org.apache.juli.logging;version=\"[10.1,11)\",org.apache.tomcat;version=\"[10.1,11)\",org.apache.tomcat.util;version=\"[10.1,11)\",org.apache.tomcat.util.buf;version=\"[10.1,11)\",org.apache.tomcat.util.codec.binary;version=\"[10.1,11)\",org.apache.tomcat.util.collections;version=\"[10.1,11)\",org.apache.tomcat.util.net;version=\"[10.1,11)\",org.apache.tomcat.util.res;version=\"[10.1,11)\",org.apache.tomcat.util.security;version=\"[10.1,11)\",org.apache.tomcat.util.threads;version=\"[10.1,11)\"" + }, + { + "key": "Private-Package", + "value": "org.apache.tomcat.websocket.pojo" + }, + { + "key": "Provide-Capability", + "value": "osgi.contract;osgi.contract=JavaWebSockets;version:Version=\"2.1\";uses:=\"jakarta.websocket,jakarta.websocket.server\",osgi.service;objectClass:List=\"jakarta.websocket.ContainerProvider\";effective:=active,osgi.service;objectClass:List=\"jakarta.websocket.server.ServerEndpointConfig$Configurator\";effective:=active,osgi.serviceloader;osgi.serviceloader=\"jakarta.websocket.ContainerProvider\";register:=\"org.apache.tomcat.websocket.WsContainerProvider\",osgi.serviceloader;osgi.serviceloader=\"jakarta.websocket.server.ServerEndpointConfig$Configurator\";register:=\"org.apache.tomcat.websocket.server.DefaultServerEndpointConfigurator\"" + }, + { + "key": "Require-Capability", + "value": "osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))\",osgi.serviceloader;filter:=\"(osgi.serviceloader=jakarta.websocket.ContainerProvider)\";osgi.serviceloader=\"jakarta.websocket.ContainerProvider\",osgi.serviceloader;filter:=\"(osgi.serviceloader=jakarta.websocket.server.ServerEndpointConfig$Configurator)\";osgi.serviceloader=\"jakarta.websocket.server.ServerEndpointConfig$Configurator\",osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\",osgi.extender;filter:=\"(&(osgi.extender=osgi.serviceloader.registrar)(version>=1.0.0)(!(version>=2.0.0)))\",osgi.contract;osgi.contract=JavaServlet;filter:=\"(&(osgi.contract=JavaServlet)(version=6.0.0))\"" + }, + { + "key": "Specification-Title", + "value": "Apache Tomcat" + }, + { + "key": "Specification-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Specification-Version", + "value": "10.1" + }, + { + "key": "X-Compile-Source-JDK", + "value": "11" + }, + { + "key": "X-Compile-Target-JDK", + "value": "11" + } + ], + "sections": [ + [ + { + "key": "Name", + "value": "jakarta/websocket/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.websocket" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "2.1" + }, + { + "key": "Specification-Title", + "value": "Jakarta WebSocket" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "2.1" + } + ], + [ + { + "key": "Name", + "value": "jakarta/websocket/server/" + }, + { + "key": "Implementation-Title", + "value": "jakarta.websocket" + }, + { + "key": "Implementation-Vendor", + "value": "Apache Software Foundation" + }, + { + "key": "Implementation-Version", + "value": "2.1" + }, + { + "key": "Specification-Title", + "value": "Jakarta WebSocket" + }, + { + "key": "Specification-Vendor", + "value": "Eclipse Foundation" + }, + { + "key": "Specification-Version", + "value": "2.1" + } + ] + ] + }, + "digest": [ + { + "algorithm": "sha1", + "value": "83a3bc6898f2ceed2357ba231a5e83dc2016d454" + } + ] + } + } + ], + "artifactRelationships": [ + { + "parent": "0408f25059f495c5", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "1347581c05f302c0", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "173ea637a5756944", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "1e7758a78bbc15ee", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "26b8a84479010ca8", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "2c7953c2c68ec3bc", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "3748310e1aac44ea", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "3c0d8567351e2ae4", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "3d5d71e0e85398af", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "44752cfa6770756d", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "519fe54307d2d43d", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "546794e924e39088", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "598311f4a5b2a501", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "6c04f8ee22f9157e", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "77a5bf527533d628", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "7a59d22722f7701b", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "8069f3f866b2e657", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "846731ed2e85561c", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "860f45be6a175d16", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "93ed082a147d9796", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "940aed7082581b67", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "9ad3756f611d1ed2", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "a11948291446c2f5", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "a753aca6ee68c738", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "adc63cefcede34fc", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "b40bdc90eb8832a3", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "b8eb893518786bb8", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "bb7e773a923726bb", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "c1e7975b6f55f7e8", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "c404b33d3a8ce0d8", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "c46f369578c77c43", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "0408f25059f495c5", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "1347581c05f302c0", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "173ea637a5756944", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "1e7758a78bbc15ee", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "26b8a84479010ca8", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "2c7953c2c68ec3bc", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "3748310e1aac44ea", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "3c0d8567351e2ae4", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "3d5d71e0e85398af", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "44752cfa6770756d", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "519fe54307d2d43d", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "546794e924e39088", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "598311f4a5b2a501", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "6c04f8ee22f9157e", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "77a5bf527533d628", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "7a59d22722f7701b", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "8069f3f866b2e657", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "846731ed2e85561c", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "860f45be6a175d16", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "93ed082a147d9796", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "940aed7082581b67", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "9ad3756f611d1ed2", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "a11948291446c2f5", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "a753aca6ee68c738", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "adc63cefcede34fc", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "b40bdc90eb8832a3", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "b8eb893518786bb8", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "bb7e773a923726bb", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "c1e7975b6f55f7e8", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "c404b33d3a8ce0d8", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "c46f369578c77c43", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "d91fe3ae6bb15cad", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "f4585c65c0a5b26a", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "f4ea2c844b65a026", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "f5bca9d628ab321f", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "f83d629168e25cce", + "type": "contains" + }, + { + "parent": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "child": "f9418986cc24a153", + "type": "contains" + }, + { + "parent": "d91fe3ae6bb15cad", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "f4585c65c0a5b26a", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "f4ea2c844b65a026", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "f5bca9d628ab321f", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "f83d629168e25cce", + "child": "af7261c65fbd5345", + "type": "evident-by" + }, + { + "parent": "f9418986cc24a153", + "child": "af7261c65fbd5345", + "type": "evident-by" + } + ], + "files": [ + { + "id": "af7261c65fbd5345", + "location": { + "path": "/sbom-test-gradle-0.0.1-SNAPSHOT.jar" + } + } + ], + "source": { + "id": "d2ff433e51158ef9a80dae682491d6500e9070bb143038bc0756d49fda3ad416", + "name": "sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "version": "sha256:f1802eb27e84114cfd7213ec83534a4b3219da6c4b2dcc827e0130b69ffa63b9", + "type": "file", + "metadata": { + "path": "sbom-test-gradle-0.0.1-SNAPSHOT.jar", + "digests": [ + { + "algorithm": "sha256", + "value": "f1802eb27e84114cfd7213ec83534a4b3219da6c4b2dcc827e0130b69ffa63b9" + } + ], + "mimeType": "application/jar" + } + }, + "distro": {}, + "descriptor": { + "name": "syft", + "version": "0.105.0", + "configuration": { + "catalogers": { + "requested": { + "default": [ + "directory" + ] + }, + "used": [ + "alpm-db-cataloger", + "apk-db-cataloger", + "binary-cataloger", + "cocoapods-cataloger", + "conan-cataloger", + "dart-pubspec-lock-cataloger", + "dotnet-deps-cataloger", + "dotnet-portable-executable-cataloger", + "dpkg-db-cataloger", + "elixir-mix-lock-cataloger", + "erlang-otp-application-cataloger", + "erlang-rebar-lock-cataloger", + "github-action-workflow-usage-cataloger", + "github-actions-usage-cataloger", + "go-module-binary-cataloger", + "go-module-file-cataloger", + "graalvm-native-image-cataloger", + "haskell-cataloger", + "java-archive-cataloger", + "java-gradle-lockfile-cataloger", + "java-pom-cataloger", + "javascript-lock-cataloger", + "linux-kernel-cataloger", + "nix-store-cataloger", + "php-composer-lock-cataloger", + "portage-cataloger", + "python-installed-package-cataloger", + "python-package-cataloger", + "rpm-archive-cataloger", + "rpm-db-cataloger", + "ruby-gemfile-cataloger", + "ruby-gemspec-cataloger", + "rust-cargo-lock-cataloger", + "swift-package-manager-cataloger", + "wordpress-plugins-cataloger" + ] + }, + "data-generation": { + "generate-cpes": true + }, + "files": { + "content": { + "globs": null, + "skip-files-above-size": 0 + }, + "hashers": [ + "sha-1", + "sha-256" + ], + "selection": "owned-by-package" + }, + "packages": { + "binary": [ + "python-binary", + "python-binary-lib", + "pypy-binary-lib", + "go-binary", + "julia-binary", + "helm", + "redis-binary", + "java-binary-openjdk", + "java-binary-ibm", + "java-binary-oracle", + "nodejs-binary", + "go-binary-hint", + "busybox-binary", + "haproxy-binary", + "perl-binary", + "php-cli-binary", + "php-fpm-binary", + "php-apache-binary", + "php-composer-binary", + "httpd-binary", + "memcached-binary", + "traefik-binary", + "postgresql-binary", + "mysql-binary", + "mysql-binary", + "mysql-binary", + "xtrabackup-binary", + "mariadb-binary", + "rust-standard-library-linux", + "rust-standard-library-macos", + "ruby-binary", + "erlang-binary", + "consul-binary", + "nginx-binary", + "bash-binary", + "openssl-binary", + "gcc-binary", + "wordpress-cli-binary" + ], + "golang": { + "local-mod-cache-dir": "/home/user/go/pkg/mod", + "main-module-version": { + "from-build-settings": true, + "from-contents": true, + "from-ld-flags": true + }, + "proxies": [ + "https://proxy.golang.org", + "direct" + ], + "search-local-mod-cache-licenses": false, + "search-remote-licenses": false + }, + "java-archive": { + "include-indexed-archives": true, + "include-unindexed-archives": false, + "maven-base-url": "https://repo1.maven.org/maven2", + "max-parent-recursive-depth": 5, + "use-network": false + }, + "javascript": { + "npm-base-url": "https://registry.npmjs.org", + "search-remote-licenses": false + }, + "linux-kernel": { + "catalog-modules": true + }, + "python": { + "guess-unpinned-requirements": false + } + }, + "relationships": { + "exclude-binary-packages-with-file-ownership-overlap": true, + "package-file-ownership": true, + "package-file-ownership-overlap": true + }, + "search": { + "scope": "squashed" + } + } + }, + "schema": { + "version": "16.0.4", + "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-16.0.4.json" + } +} diff --git a/spring-boot-project/spring-boot-actuator/build.gradle b/spring-boot-project/spring-boot-actuator/build.gradle index a1711c066fa0..1757289a000e 100644 --- a/spring-boot-project/spring-boot-actuator/build.gradle +++ b/spring-boot-project/spring-boot-actuator/build.gradle @@ -16,9 +16,9 @@ plugins { id "java-library" + id "java-test-fixtures" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.optional-dependencies" - id "org.springframework.boot.docker-test" id "org.springframework.boot.deployed" } @@ -27,26 +27,15 @@ description = "Spring Boot Actuator" dependencies { api(project(":spring-boot-project:spring-boot")) - dockerTestImplementation(project(":spring-boot-project:spring-boot-autoconfigure")) - dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) - dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) - dockerTestImplementation("com.redis:testcontainers-redis") - dockerTestImplementation("org.assertj:assertj-core") - dockerTestImplementation("org.junit.jupiter:junit-jupiter") - dockerTestImplementation("org.springframework:spring-test") - dockerTestImplementation("org.testcontainers:junit-jupiter") - dockerTestImplementation("org.testcontainers:mongodb") - dockerTestImplementation("org.testcontainers:neo4j") - dockerTestImplementation("org.testcontainers:testcontainers") - - optional("org.apache.cassandra:java-driver-core") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-http-converter")) + optional(project(":spring-boot-project:spring-boot-jsonb")) + optional(project(":spring-boot-project:spring-boot-validation")) + optional(project(":spring-boot-project:spring-boot-web-server")) optional("com.fasterxml.jackson.core:jackson-databind") optional("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") optional("com.github.ben-manes.caffeine:caffeine") - optional("com.hazelcast:hazelcast") - optional("com.hazelcast:hazelcast-spring") + optional("com.google.code.findbugs:jsr305") optional("com.zaxxer:HikariCP") optional("io.lettuce:lettuce-core") optional("io.micrometer:micrometer-observation") @@ -56,77 +45,38 @@ dependencies { optional("io.micrometer:micrometer-registry-prometheus-simpleclient") optional("io.prometheus:prometheus-metrics-exposition-formats") optional("io.prometheus:prometheus-metrics-exporter-pushgateway") - optional("io.r2dbc:r2dbc-pool") - optional("io.r2dbc:r2dbc-spi") - optional("io.undertow:undertow-servlet") + optional("jakarta.servlet:jakarta.servlet-api") optional("javax.cache:cache-api") - optional("jakarta.jms:jakarta.jms-api") - optional("org.apache.tomcat.embed:tomcat-embed-core") optional("org.aspectj:aspectjweaver") - optional("org.cache2k:cache2k-micrometer") - optional("org.cache2k:cache2k-spring") optional("org.eclipse.angus:angus-mail") - optional("org.eclipse.jetty:jetty-server") { - exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api") - } - optional("org.elasticsearch.client:elasticsearch-rest-client") - optional("org.flywaydb:flyway-core") - optional("org.glassfish.jersey.core:jersey-server") - optional("org.glassfish.jersey.containers:jersey-container-servlet-core") optional("org.hibernate.validator:hibernate-validator") optional("org.influxdb:influxdb-java") - optional("org.liquibase:liquibase-core") { - exclude(group: "javax.xml.bind", module: "jaxb-api") - } - optional("org.mongodb:mongodb-driver-reactivestreams") - optional("org.mongodb:mongodb-driver-sync") - optional("org.neo4j.driver:neo4j-java-driver") - optional("org.quartz-scheduler:quartz") + optional("org.springframework:spring-context-support") optional("org.springframework:spring-jdbc") optional("org.springframework:spring-messaging") - optional("org.springframework:spring-webflux") - optional("org.springframework:spring-web") - optional("org.springframework:spring-webmvc") optional("org.springframework.graphql:spring-graphql") - optional("org.springframework.amqp:spring-rabbit") - optional("org.springframework.data:spring-data-cassandra") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } - optional("org.springframework.data:spring-data-couchbase") - optional("org.springframework.data:spring-data-elasticsearch") - optional("org.springframework.data:spring-data-ldap") - optional("org.springframework.data:spring-data-mongodb") - optional("org.springframework.data:spring-data-redis") - optional("org.springframework.data:spring-data-rest-webmvc") - optional("org.springframework.integration:spring-integration-core") optional("org.springframework.security:spring-security-core") optional("org.springframework.security:spring-security-web") - optional("org.springframework.session:spring-session-core") + + testFixturesApi("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") + testFixturesImplementation("org.junit.jupiter:junit-jupiter-api") + testFixturesImplementation("org.springframework:spring-test") + testFixturesImplementation("org.springframework:spring-webflux") testImplementation(project(":spring-boot-project:spring-boot-autoconfigure")) + testImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-jsonb")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("org.assertj:assertj-core") - testImplementation("com.jayway.jsonpath:json-path") testImplementation("io.micrometer:micrometer-observation-test") testImplementation("io.projectreactor:reactor-test") - testImplementation("io.r2dbc:r2dbc-h2") testImplementation("net.minidev:json-smart") testImplementation("org.apache.logging.log4j:log4j-to-slf4j") - testImplementation("org.awaitility:awaitility") - testImplementation("org.glassfish.jersey.media:jersey-media-json-jackson") - testImplementation("org.hamcrest:hamcrest") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.skyscreamer:jsonassert") - testImplementation("org.springframework:spring-test") - testImplementation("com.squareup.okhttp3:mockwebserver") + testRuntimeOnly(project(":spring-boot-project:spring-boot-http-codec")) testRuntimeOnly("ch.qos.logback:logback-classic") testRuntimeOnly("io.projectreactor.netty:reactor-netty-http") testRuntimeOnly("jakarta.xml.bind:jakarta.xml.bind-api") testRuntimeOnly("org.apache.tomcat.embed:tomcat-embed-el") - testRuntimeOnly("org.glassfish.jersey.ext:jersey-spring6") testRuntimeOnly("org.hsqldb:hsqldb") } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/amqp/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/amqp/package-info.java deleted file mode 100644 index 156d7fc445f2..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/amqp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for AMQP and RabbitMQ. - */ -package org.springframework.boot.actuate.amqp; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicator.java index 8472ae50144b..a0660708b549 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicator.java @@ -21,12 +21,12 @@ import java.util.Map; import java.util.function.Consumer; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.availability.ApplicationAvailability; import org.springframework.boot.availability.AvailabilityState; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.util.Assert; /** @@ -76,7 +76,7 @@ private void assertAllEnumsMapped(Class stateTy } @Override - protected void doHealthCheck(Builder builder) throws Exception { + protected void doHealthCheck(Health.Builder builder) throws Exception { AvailabilityState state = getState(this.applicationAvailability); Status status = this.statusMappings.get(state); if (status == null) { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicator.java index 7bbb463c1d9d..1b099ff244bc 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicator.java @@ -16,11 +16,11 @@ package org.springframework.boot.actuate.availability; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.availability.ApplicationAvailability; import org.springframework.boot.availability.AvailabilityState; import org.springframework.boot.availability.LivenessState; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; /** * A {@link HealthIndicator} that checks the {@link LivenessState} of the application. diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicator.java index 4e5ef1c879d6..0d3b53f88b38 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicator.java @@ -16,11 +16,11 @@ package org.springframework.boot.actuate.availability; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.availability.ApplicationAvailability; import org.springframework.boot.availability.AvailabilityState; import org.springframework.boot.availability.ReadinessState; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; /** * A {@link HealthIndicator} that checks the {@link ReadinessState} of the application. diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/package-info.java deleted file mode 100644 index 990d611c66ff..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for caches. - */ -package org.springframework.boot.actuate.cache; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/package-info.java deleted file mode 100644 index b0ddc76c746a..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Cassandra. - */ -package org.springframework.boot.actuate.cassandra; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/package-info.java deleted file mode 100644 index fa870d137a9f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Couchbase. - */ -package org.springframework.boot.actuate.couchbase; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/elasticsearch/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/elasticsearch/package-info.java deleted file mode 100644 index 022472a2aaf8..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/elasticsearch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Elasticsearch dependent on Spring Data. - */ -package org.springframework.boot.actuate.data.elasticsearch; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/package-info.java deleted file mode 100644 index 459db58b7e6f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Mongo dependent on Spring Data. - */ -package org.springframework.boot.actuate.data.mongo; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/package-info.java deleted file mode 100644 index d4b0298342a3..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Redis dependent on Spring Data. - */ -package org.springframework.boot.actuate.data.redis; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/package-info.java deleted file mode 100644 index 6e1b4978da75..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Elasticsearch. - */ -package org.springframework.boot.actuate.elasticsearch; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AbstractExposableEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AbstractExposableEndpoint.java index 423a9bbd217b..9461e50eae97 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AbstractExposableEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/AbstractExposableEndpoint.java @@ -36,19 +36,6 @@ public abstract class AbstractExposableEndpoint implements private final List operations; - /** - * Create a new {@link AbstractExposableEndpoint} instance. - * @param id the endpoint id - * @param enabledByDefault if the endpoint is enabled by default - * @param operations the endpoint operations - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #AbstractExposableEndpoint(EndpointId, Access, Collection)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public AbstractExposableEndpoint(EndpointId id, boolean enabledByDefault, Collection operations) { - this(id, (enabledByDefault) ? Access.UNRESTRICTED : Access.READ_ONLY, operations); - } - /** * Create a new {@link AbstractExposableEndpoint} instance. * @param id the endpoint id @@ -69,13 +56,6 @@ public EndpointId getEndpointId() { return this.id; } - @Override - @SuppressWarnings("removal") - @Deprecated(since = "3.4.0", forRemoval = true) - public boolean isEnableByDefault() { - return this.defaultAccess != Access.NONE; - } - @Override public Access getDefaultAccess() { return this.defaultAccess; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ExposableEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ExposableEndpoint.java index 22e4c8e7a32e..a9d08a36050b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ExposableEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ExposableEndpoint.java @@ -34,15 +34,6 @@ public interface ExposableEndpoint { */ EndpointId getEndpointId(); - /** - * Returns if the endpoint is enabled by default. - * @return if the endpoint is enabled by default - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #getDefaultAccess()} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - boolean isEnableByDefault(); - /** * Returns the access to the endpoint that is permitted by default. * @return access that is permitted by default diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/AbstractDiscoveredEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/AbstractDiscoveredEndpoint.java index ef0113ddd393..e9d5227a12dd 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/AbstractDiscoveredEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/AbstractDiscoveredEndpoint.java @@ -41,23 +41,6 @@ public abstract class AbstractDiscoveredEndpoint extends Ab private final Object endpointBean; - /** - * Create a new {@link AbstractDiscoveredEndpoint} instance. - * @param discoverer the discoverer that discovered the endpoint - * @param endpointBean the primary source bean - * @param id the ID of the endpoint - * @param enabledByDefault if the endpoint is enabled by default - * @param operations the endpoint operations - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #AbstractDiscoveredEndpoint(EndpointDiscoverer, Object, EndpointId, Access, Collection)} - */ - @SuppressWarnings("removal") - @Deprecated(since = "3.4.0", forRemoval = true) - public AbstractDiscoveredEndpoint(EndpointDiscoverer discoverer, Object endpointBean, EndpointId id, - boolean enabledByDefault, Collection operations) { - this(discoverer, endpointBean, id, (enabledByDefault) ? Access.UNRESTRICTED : Access.READ_ONLY, operations); - } - /** * Create a new {@link AbstractDiscoveredEndpoint} instance. * @param discoverer the discoverer that discovered the endpoint diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.java index e9463b52f4b7..d3fe8369971b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.java @@ -63,14 +63,6 @@ */ String id() default ""; - /** - * If the endpoint should be enabled or disabled by default. - * @return {@code true} if the endpoint is enabled by default - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #defaultAccess()} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - boolean enableByDefault() default true; - /** * Level of access to the endpoint that is permitted by default. * @return the default level of access diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscoverer.java index 0b579c2deb9a..1b101136a9fb 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscoverer.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscoverer.java @@ -84,21 +84,6 @@ public abstract class EndpointDiscoverer, O exten private volatile Collection endpoints; - /** - * Create a new {@link EndpointDiscoverer} instance. - * @param applicationContext the source application context - * @param parameterValueMapper the parameter value mapper - * @param invokerAdvisors invoker advisors to apply - * @param endpointFilters endpoint filters to apply - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #EndpointDiscoverer(ApplicationContext, ParameterValueMapper, Collection, Collection, Collection)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public EndpointDiscoverer(ApplicationContext applicationContext, ParameterValueMapper parameterValueMapper, - Collection invokerAdvisors, Collection> endpointFilters) { - this(applicationContext, parameterValueMapper, invokerAdvisors, endpointFilters, Collections.emptyList()); - } - /** * Create a new {@link EndpointDiscoverer} instance. * @param applicationContext the source application context @@ -381,21 +366,6 @@ protected Class getEndpointType() { return (Class) ResolvableType.forClass(EndpointDiscoverer.class, getClass()).resolveGeneric(0); } - /** - * Factory method called to create the {@link ExposableEndpoint endpoint}. - * @param endpointBean the source endpoint bean - * @param id the ID of the endpoint - * @param enabledByDefault if the endpoint is enabled by default - * @param operations the endpoint operations - * @return a created endpoint (a {@link DiscoveredEndpoint} is recommended) - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #createEndpoint(Object, EndpointId, Access, Collection)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - protected E createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault, Collection operations) { - return createEndpoint(endpointBean, id, (enabledByDefault) ? Access.UNRESTRICTED : Access.NONE, operations); - } - /** * Factory method called to create the {@link ExposableEndpoint endpoint}. * @param endpointBean the source endpoint bean @@ -498,8 +468,7 @@ private static class EndpointBean { this.beanType = beanType; this.beanSupplier = beanSupplier; this.id = EndpointId.of(environment, id); - boolean enabledByDefault = annotation.getBoolean("enableByDefault"); - this.defaultAccess = enabledByDefault ? annotation.getEnum("defaultAccess", Access.class) : Access.NONE; + this.defaultAccess = annotation.getEnum("defaultAccess", Access.class); this.filter = getFilter(beanType); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoke/reflect/OperationMethod.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoke/reflect/OperationMethod.java index fb4c01fa8472..564f69b7d3ff 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoke/reflect/OperationMethod.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoke/reflect/OperationMethod.java @@ -49,7 +49,7 @@ public class OperationMethod { * @param method the source method * @param operationType the operation type * @deprecated since 4.0.0 for removal in 4.2.0 in favor of - * {@link #OperationMethod(Method, OperationType, Predicate)}p + * {@link #OperationMethod(Method, OperationType, Predicate)} */ @Deprecated(since = "4.0.0", forRemoval = true) public OperationMethod(Method method, OperationType operationType) { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jackson/EndpointObjectMapper.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jackson/EndpointObjectMapper.java index b1b698c94b1b..91c11a9fb1a2 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jackson/EndpointObjectMapper.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jackson/EndpointObjectMapper.java @@ -16,13 +16,15 @@ package org.springframework.boot.actuate.endpoint.jackson; +import java.util.Set; + import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.actuate.endpoint.OperationResponseBody; /** * Interface used to supply the {@link ObjectMapper} that should be used when serializing - * {@link OperationResponseBody} endpoint results. + * endpoint results. * * @author Phillip Webb * @since 3.0.0 @@ -30,6 +32,11 @@ */ public interface EndpointObjectMapper { + /** + * The default supported types. + */ + Set> DEFAULT_SUPPORTED_TYPES = Set.of(OperationResponseBody.class); + /** * Return the {@link ObjectMapper} that should be used to serialize * {@link OperationResponseBody} endpoint results. @@ -37,4 +44,13 @@ public interface EndpointObjectMapper { */ ObjectMapper get(); + /** + * Return the types that this endpoint mapper supports. + * @return the supported types + * @since 4.0.0 + */ + default Set> getSupportedTypes() { + return DEFAULT_SUPPORTED_TYPES; + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpoint.java index 125fb41abe8d..641504f42648 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpoint.java @@ -48,15 +48,6 @@ @AliasFor(annotation = Endpoint.class) String id() default ""; - /** - * If the endpoint should be enabled or disabled by default. - * @return {@code true} if the endpoint is enabled by default - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - */ - @Deprecated(since = "3.4.0", forRemoval = true) - @AliasFor(annotation = Endpoint.class) - boolean enableByDefault() default true; - /** * Level of access to the endpoint that is permitted by default. * @return the default level of access diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscoverer.java index cfb412933308..46121328c78d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscoverer.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscoverer.java @@ -17,7 +17,6 @@ package org.springframework.boot.actuate.endpoint.jmx.annotation; import java.util.Collection; -import java.util.Collections; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; @@ -48,22 +47,6 @@ public class JmxEndpointDiscoverer extends EndpointDiscoverer implements JmxEndpointsSupplier { - /** - * Create a new {@link JmxEndpointDiscoverer} instance. - * @param applicationContext the source application context - * @param parameterValueMapper the parameter value mapper - * @param invokerAdvisors invoker advisors to apply - * @param endpointFilters endpoint filters to apply - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #JmxEndpointDiscoverer(ApplicationContext, ParameterValueMapper, Collection, Collection, Collection)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public JmxEndpointDiscoverer(ApplicationContext applicationContext, ParameterValueMapper parameterValueMapper, - Collection invokerAdvisors, - Collection> endpointFilters) { - this(applicationContext, parameterValueMapper, invokerAdvisors, endpointFilters, Collections.emptyList()); - } - /** * Create a new {@link JmxEndpointDiscoverer} instance. * @param applicationContext the source application context diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpoint.java index 00ed1319fc2d..1fb8f884804d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpoint.java @@ -65,13 +65,6 @@ @AliasFor(annotation = Endpoint.class) String id(); - /** - * If the endpoint should be enabled or disabled by default. - * @return {@code true} if the endpoint is enabled by default - */ - @AliasFor(annotation = Endpoint.class) - boolean enableByDefault() default true; - /** * Level of access to the endpoint that is permitted by default. * @return the default level of access diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/RestControllerEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/RestControllerEndpoint.java index fba8aa5ed98f..10c234ba2a8f 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/RestControllerEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/RestControllerEndpoint.java @@ -67,13 +67,6 @@ @AliasFor(annotation = Endpoint.class) String id(); - /** - * If the endpoint should be enabled or disabled by default. - * @return {@code true} if the endpoint is enabled by default - */ - @AliasFor(annotation = Endpoint.class) - boolean enableByDefault() default true; - /** * Level of access to the endpoint that is permitted by default. * @return the default level of access diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpoint.java index e320bc6f0ca0..529ddea0267d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpoint.java @@ -58,13 +58,6 @@ @AliasFor(annotation = Endpoint.class) String id(); - /** - * If the endpoint should be enabled or disabled by default. - * @return {@code true} if the endpoint is enabled by default - */ - @AliasFor(annotation = Endpoint.class) - boolean enableByDefault() default true; - /** * Level of access to the endpoint that is permitted by default. * @return the default level of access diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpoint.java index 77fe2a610c89..8d820ccf1d83 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpoint.java @@ -48,15 +48,6 @@ @AliasFor(annotation = Endpoint.class) String id(); - /** - * If the endpoint should be enabled or disabled by default. - * @return {@code true} if the endpoint is enabled by default - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #defaultAccess()} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - @AliasFor(annotation = Endpoint.class) - boolean enableByDefault() default true; - /** * Level of access to the endpoint that is permitted by default. * @return the default level of access diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscoverer.java index fa4954671f8f..4029fc39e5fa 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscoverer.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscoverer.java @@ -59,26 +59,6 @@ public class WebEndpointDiscoverer extends EndpointDiscoverer endpointPathMappers, - Collection invokerAdvisors, - Collection> filters) { - this(applicationContext, parameterValueMapper, endpointMediaTypes, endpointPathMappers, Collections.emptyList(), - invokerAdvisors, filters, Collections.emptyList()); - } - /** * Create a new {@link WebEndpointDiscoverer} instance. * @param applicationContext the source application context diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/package-info.java deleted file mode 100644 index 272e4590b933..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Jersey support for actuator endpoints. - */ -package org.springframework.boot.actuate.endpoint.web.jersey; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMapping.java deleted file mode 100644 index c5a70bcab96f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMapping.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.reactive; - -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import org.springframework.boot.actuate.endpoint.Access; -import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.reactive.HandlerMapping; -import org.springframework.web.reactive.result.method.RequestMappingInfo; -import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; -import org.springframework.web.util.pattern.PathPattern; - -/** - * {@link HandlerMapping} that exposes - * {@link org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint @ControllerEndpoint} - * and - * {@link org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint @RestControllerEndpoint} - * annotated endpoints over Spring WebFlux. - * - * @author Phillip Webb - * @since 2.0.0 - * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support - */ -@Deprecated(since = "3.3.5", forRemoval = true) -@SuppressWarnings("removal") -public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMapping { - - private static final Set READ_ONLY_ACCESS_REQUEST_METHODS = EnumSet.of(RequestMethod.GET, - RequestMethod.HEAD); - - private final EndpointMapping endpointMapping; - - private final CorsConfiguration corsConfiguration; - - private final Map handlers; - - private final EndpointAccessResolver accessResolver; - - /** - * Create a new {@link ControllerEndpointHandlerMapping} instance providing mappings - * for the specified endpoints. - * @param endpointMapping the base mapping for all endpoints - * @param endpoints the web endpoints - * @param corsConfiguration the CORS configuration for the endpoints or {@code null} - */ - public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping, - Collection endpoints, CorsConfiguration corsConfiguration) { - this(endpointMapping, endpoints, corsConfiguration, (endpointId, defaultAccess) -> Access.NONE); - } - - /** - * Create a new {@link ControllerEndpointHandlerMapping} instance providing mappings - * for the specified endpoints. - * @param endpointMapping the base mapping for all endpoints - * @param endpoints the web endpoints - * @param corsConfiguration the CORS configuration for the endpoints or {@code null} - * @param endpointAccessResolver resolver for endpoint access - */ - public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping, - Collection endpoints, CorsConfiguration corsConfiguration, - EndpointAccessResolver endpointAccessResolver) { - Assert.notNull(endpointMapping, "'endpointMapping' must not be null"); - Assert.notNull(endpoints, "'endpoints' must not be null"); - this.endpointMapping = endpointMapping; - this.handlers = getHandlers(endpoints); - this.corsConfiguration = corsConfiguration; - this.accessResolver = endpointAccessResolver; - setOrder(-100); - } - - private Map getHandlers(Collection endpoints) { - Map handlers = new LinkedHashMap<>(); - endpoints.forEach((endpoint) -> handlers.put(endpoint.getController(), endpoint)); - return Collections.unmodifiableMap(handlers); - } - - @Override - protected void initHandlerMethods() { - this.handlers.keySet().forEach(this::detectHandlerMethods); - } - - @Override - protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { - ExposableControllerEndpoint endpoint = this.handlers.get(handler); - Access access = this.accessResolver.accessFor(endpoint.getEndpointId(), endpoint.getDefaultAccess()); - if (access == Access.NONE) { - return; - } - if (access == Access.READ_ONLY) { - mapping = withReadOnlyAccess(access, mapping); - if (CollectionUtils.isEmpty(mapping.getMethodsCondition().getMethods())) { - return; - } - } - mapping = withEndpointMappedPatterns(endpoint, mapping); - super.registerHandlerMethod(handler, method, mapping); - } - - private RequestMappingInfo withReadOnlyAccess(Access access, RequestMappingInfo mapping) { - Set methods = new HashSet<>(mapping.getMethodsCondition().getMethods()); - if (methods.isEmpty()) { - methods.addAll(READ_ONLY_ACCESS_REQUEST_METHODS); - } - else { - methods.retainAll(READ_ONLY_ACCESS_REQUEST_METHODS); - } - return mapping.mutate().methods(methods.toArray(new RequestMethod[0])).build(); - } - - private RequestMappingInfo withEndpointMappedPatterns(ExposableControllerEndpoint endpoint, - RequestMappingInfo mapping) { - Set patterns = mapping.getPatternsCondition().getPatterns(); - if (patterns.isEmpty()) { - patterns = Collections.singleton(getPathPatternParser().parse("")); - } - String[] endpointMappedPatterns = patterns.stream() - .map((pattern) -> getEndpointMappedPattern(endpoint, pattern)) - .toArray(String[]::new); - return mapping.mutate().paths(endpointMappedPatterns).build(); - } - - private String getEndpointMappedPattern(ExposableControllerEndpoint endpoint, PathPattern pattern) { - return this.endpointMapping.createSubPath(endpoint.getRootPath() + pattern); - } - - @Override - protected boolean hasCorsConfigurationSource(Object handler) { - return this.corsConfiguration != null; - } - - @Override - protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mapping) { - return this.corsConfiguration; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/package-info.java deleted file mode 100644 index ad66cc336ccc..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring WebFlux support for actuator endpoints. - */ -package org.springframework.boot.actuate.endpoint.web.reactive; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMapping.java deleted file mode 100644 index 0bc763a0c4b8..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMapping.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.servlet; - -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import org.springframework.boot.actuate.endpoint.Access; -import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.servlet.HandlerMapping; -import org.springframework.web.servlet.mvc.method.RequestMappingInfo; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import org.springframework.web.util.pattern.PathPattern; - -/** - * {@link HandlerMapping} that exposes - * {@link org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint @ControllerEndpoint} - * and - * {@link org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint @RestControllerEndpoint} - * annotated endpoints over Spring MVC. - * - * @author Phillip Webb - * @since 2.0.0 - * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support - */ -@Deprecated(since = "3.3.5", forRemoval = true) -@SuppressWarnings("removal") -public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMapping { - - private static final Set READ_ONLY_ACCESS_REQUEST_METHODS = EnumSet.of(RequestMethod.GET, - RequestMethod.HEAD); - - private final EndpointMapping endpointMapping; - - private final CorsConfiguration corsConfiguration; - - private final Map handlers; - - private final EndpointAccessResolver accessResolver; - - /** - * Create a new {@link ControllerEndpointHandlerMapping} instance providing mappings - * for the specified endpoints. - * @param endpointMapping the base mapping for all endpoints - * @param endpoints the web endpoints - * @param corsConfiguration the CORS configuration for the endpoints or {@code null} - */ - public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping, - Collection endpoints, CorsConfiguration corsConfiguration) { - this(endpointMapping, endpoints, corsConfiguration, (endpointId, defaultAccess) -> Access.NONE); - } - - /** - * Create a new {@link ControllerEndpointHandlerMapping} instance providing mappings - * for the specified endpoints. - * @param endpointMapping the base mapping for all endpoints - * @param endpoints the web endpoints - * @param corsConfiguration the CORS configuration for the endpoints or {@code null} - * @param endpointAccessResolver resolver for endpoint access - */ - public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping, - Collection endpoints, CorsConfiguration corsConfiguration, - EndpointAccessResolver endpointAccessResolver) { - Assert.notNull(endpointMapping, "'endpointMapping' must not be null"); - Assert.notNull(endpoints, "'endpoints' must not be null"); - this.endpointMapping = endpointMapping; - this.handlers = getHandlers(endpoints); - this.corsConfiguration = corsConfiguration; - this.accessResolver = endpointAccessResolver; - setOrder(-100); - } - - private Map getHandlers(Collection endpoints) { - Map handlers = new LinkedHashMap<>(); - endpoints.forEach((endpoint) -> handlers.put(endpoint.getController(), endpoint)); - return Collections.unmodifiableMap(handlers); - } - - @Override - protected void initHandlerMethods() { - this.handlers.keySet().forEach(this::detectHandlerMethods); - } - - @Override - protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { - ExposableControllerEndpoint endpoint = this.handlers.get(handler); - Access access = this.accessResolver.accessFor(endpoint.getEndpointId(), endpoint.getDefaultAccess()); - if (access == Access.NONE) { - return; - } - if (access == Access.READ_ONLY) { - mapping = withReadOnlyAccess(access, mapping); - if (CollectionUtils.isEmpty(mapping.getMethodsCondition().getMethods())) { - return; - } - } - mapping = withEndpointMappedPatterns(endpoint, mapping); - super.registerHandlerMethod(handler, method, mapping); - } - - private RequestMappingInfo withReadOnlyAccess(Access access, RequestMappingInfo mapping) { - Set methods = mapping.getMethodsCondition().getMethods(); - Set modifiedMethods = new HashSet<>(methods); - if (modifiedMethods.isEmpty()) { - modifiedMethods.addAll(READ_ONLY_ACCESS_REQUEST_METHODS); - } - else { - modifiedMethods.retainAll(READ_ONLY_ACCESS_REQUEST_METHODS); - } - return mapping.mutate().methods(modifiedMethods.toArray(new RequestMethod[0])).build(); - } - - private RequestMappingInfo withEndpointMappedPatterns(ExposableControllerEndpoint endpoint, - RequestMappingInfo mapping) { - Set patterns = mapping.getPathPatternsCondition().getPatterns(); - if (patterns.isEmpty()) { - patterns = Collections.singleton(getPatternParser().parse("")); - } - String[] endpointMappedPatterns = patterns.stream() - .map((pattern) -> getEndpointMappedPattern(endpoint, pattern)) - .toArray(String[]::new); - return mapping.mutate().paths(endpointMappedPatterns).build(); - } - - private String getEndpointMappedPattern(ExposableControllerEndpoint endpoint, PathPattern pattern) { - return this.endpointMapping.createSubPath(endpoint.getRootPath() + pattern); - } - - @Override - protected boolean hasCorsConfigurationSource(Object handler) { - return this.corsConfiguration != null; - } - - @Override - protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mapping) { - return this.corsConfiguration; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/package-info.java deleted file mode 100644 index d18f12f72215..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring MVC support for actuator endpoints. - */ -package org.springframework.boot.actuate.endpoint.web.servlet; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/flyway/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/flyway/package-info.java deleted file mode 100644 index 879dc9e5c235..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/flyway/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Flyway. - */ -package org.springframework.boot.actuate.flyway; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/package-info.java deleted file mode 100644 index a2c785b0afeb..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Hazelcast. - */ -package org.springframework.boot.actuate.hazelcast; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealth.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealth.java deleted file mode 100644 index bbfb6c9a82e5..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealth.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Map; -import java.util.TreeMap; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; - -import org.springframework.boot.actuate.endpoint.ApiVersion; -import org.springframework.util.Assert; - -/** - * A {@link HealthComponent} that is composed of other {@link HealthComponent} instances. - * Used to provide a unified view of related components. For example, a database health - * indicator may be a composite containing the {@link Health} of each datasource - * connection. - * - * @author Phillip Webb - * @since 2.2.0 - */ -public class CompositeHealth extends HealthComponent { - - private final Status status; - - private final Map components; - - private final Map details; - - CompositeHealth(ApiVersion apiVersion, Status status, Map components) { - Assert.notNull(status, "'status' must not be null"); - this.status = status; - this.components = (apiVersion != ApiVersion.V3) ? null : sort(components); - this.details = (apiVersion != ApiVersion.V2) ? null : sort(components); - } - - private Map sort(Map components) { - return (components != null) ? new TreeMap<>(components) : components; - } - - @Override - public Status getStatus() { - return this.status; - } - - @JsonInclude(Include.NON_EMPTY) - public Map getComponents() { - return this.components; - } - - @JsonInclude(Include.NON_EMPTY) - @JsonProperty - public Map getDetails() { - return this.details; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributorMapAdapter.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributorMapAdapter.java deleted file mode 100644 index 6f02061f7718..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributorMapAdapter.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Map; -import java.util.function.Function; - -/** - * {@link CompositeHealthContributor} backed by a map with values adapted as necessary. - * - * @param the value type - * @author Phillip Webb - */ -class CompositeHealthContributorMapAdapter extends NamedContributorsMapAdapter - implements CompositeHealthContributor { - - CompositeHealthContributorMapAdapter(Map map, Function valueAdapter) { - super(map, valueAdapter); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributorReactiveAdapter.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributorReactiveAdapter.java deleted file mode 100644 index 18956ee063e7..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributorReactiveAdapter.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Iterator; - -import org.springframework.util.Assert; - -/** - * Adapts a {@link CompositeHealthContributor} to a - * {@link CompositeReactiveHealthContributor} so that it can be safely invoked in a - * reactive environment. - * - * @author Phillip Webb - * @see ReactiveHealthContributor#adapt(HealthContributor) - */ -class CompositeHealthContributorReactiveAdapter implements CompositeReactiveHealthContributor { - - private final CompositeHealthContributor delegate; - - CompositeHealthContributorReactiveAdapter(CompositeHealthContributor delegate) { - Assert.notNull(delegate, "'delegate' must not be null"); - this.delegate = delegate; - } - - @Override - public Iterator> iterator() { - Iterator> iterator = this.delegate.iterator(); - return new Iterator<>() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public NamedContributor next() { - NamedContributor namedContributor = iterator.next(); - return NamedContributor.of(namedContributor.getName(), - ReactiveHealthContributor.adapt(namedContributor.getContributor())); - } - - }; - } - - @Override - public ReactiveHealthContributor getContributor(String name) { - HealthContributor contributor = this.delegate.getContributor(name); - return (contributor != null) ? ReactiveHealthContributor.adapt(contributor) : null; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributor.java deleted file mode 100644 index d79b74af7be1..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributor.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Map; -import java.util.function.Function; - -/** - * A {@link ReactiveHealthContributor} that is composed of other - * {@link ReactiveHealthContributor} instances. - * - * @author Phillip Webb - * @since 2.2.0 - * @see CompositeHealth - * @see CompositeHealthContributor - */ -public interface CompositeReactiveHealthContributor - extends ReactiveHealthContributor, NamedContributors { - - /** - * Factory method that will create a {@link CompositeReactiveHealthContributor} from - * the specified map. - * @param map the source map - * @return a composite health contributor instance - */ - static CompositeReactiveHealthContributor fromMap(Map map) { - return fromMap(map, Function.identity()); - } - - /** - * Factory method that will create a {@link CompositeReactiveHealthContributor} from - * the specified map. - * @param the value type - * @param map the source map - * @param valueAdapter function used to adapt the map value - * @return a composite health contributor instance - */ - static CompositeReactiveHealthContributor fromMap(Map map, - Function valueAdapter) { - return new CompositeReactiveHealthContributorMapAdapter<>(map, valueAdapter); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributorMapAdapter.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributorMapAdapter.java deleted file mode 100644 index 4c6034676203..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributorMapAdapter.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Map; -import java.util.function.Function; - -/** - * {@link CompositeReactiveHealthContributor} backed by a map with values adapted as - * necessary. - * - * @param the value type - * @author Phillip Webb - */ -class CompositeReactiveHealthContributorMapAdapter extends NamedContributorsMapAdapter - implements CompositeReactiveHealthContributor { - - CompositeReactiveHealthContributorMapAdapter(Map map, - Function valueAdapter) { - super(map, valueAdapter); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ContributorRegistry.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ContributorRegistry.java deleted file mode 100644 index af2efbe4d97e..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ContributorRegistry.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -/** - * A mutable registry of health endpoint contributors (either {@link HealthContributor} or - * {@link ReactiveHealthContributor}). - * - * @param the contributor type - * @author Phillip Webb - * @author Andy Wilkinson - * @author Vedran Pavic - * @author Stephane Nicoll - * @since 2.2.0 - * @see NamedContributors - */ -public interface ContributorRegistry extends NamedContributors { - - /** - * Register a contributor with the given {@code name}. - * @param name the name of the contributor - * @param contributor the contributor to register - * @throws IllegalStateException if the contributor cannot be registered with the - * given {@code name}. - */ - void registerContributor(String name, C contributor); - - /** - * Unregister a previously registered contributor. - * @param name the name of the contributor to unregister - * @return the unregistered indicator, or {@code null} if no indicator was found in - * the registry for the given {@code name}. - */ - C unregisterContributor(String name); - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultContributorRegistry.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultContributorRegistry.java deleted file mode 100644 index 9bff84dd6db6..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultContributorRegistry.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.function.Function; - -import org.springframework.util.Assert; - -/** - * Default {@link ContributorRegistry} implementation. - * - * @param the health contributor type - * @author Phillip Webb - * @see DefaultHealthContributorRegistry - * @see DefaultReactiveHealthContributorRegistry - */ -class DefaultContributorRegistry implements ContributorRegistry { - - private final Function nameFactory; - - private final Object monitor = new Object(); - - private volatile Map contributors; - - DefaultContributorRegistry() { - this(Collections.emptyMap()); - } - - DefaultContributorRegistry(Map contributors) { - this(contributors, HealthContributorNameFactory.INSTANCE); - } - - DefaultContributorRegistry(Map contributors, Function nameFactory) { - Assert.notNull(contributors, "'contributors' must not be null"); - Assert.notNull(nameFactory, "'nameFactory' must not be null"); - this.nameFactory = nameFactory; - Map namedContributors = new LinkedHashMap<>(); - contributors.forEach((name, contributor) -> namedContributors.put(nameFactory.apply(name), contributor)); - this.contributors = Collections.unmodifiableMap(namedContributors); - } - - @Override - public void registerContributor(String name, C contributor) { - Assert.notNull(name, "'name' must not be null"); - Assert.notNull(contributor, "'contributor' must not be null"); - String adaptedName = this.nameFactory.apply(name); - synchronized (this.monitor) { - Assert.state(!this.contributors.containsKey(adaptedName), - () -> "A contributor named \"" + adaptedName + "\" has already been registered"); - Map contributors = new LinkedHashMap<>(this.contributors); - contributors.put(adaptedName, contributor); - this.contributors = Collections.unmodifiableMap(contributors); - } - } - - @Override - public C unregisterContributor(String name) { - Assert.notNull(name, "'name' must not be null"); - String adaptedName = this.nameFactory.apply(name); - synchronized (this.monitor) { - C unregistered = this.contributors.get(adaptedName); - if (unregistered != null) { - Map contributors = new LinkedHashMap<>(this.contributors); - contributors.remove(adaptedName); - this.contributors = Collections.unmodifiableMap(contributors); - } - return unregistered; - } - } - - @Override - public C getContributor(String name) { - return this.contributors.get(name); - } - - @Override - public Iterator> iterator() { - Iterator> iterator = this.contributors.entrySet().iterator(); - return new Iterator<>() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public NamedContributor next() { - Entry entry = iterator.next(); - return NamedContributor.of(entry.getKey(), entry.getValue()); - } - - }; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultHealthContributorRegistry.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultHealthContributorRegistry.java deleted file mode 100644 index fa09a8b13272..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultHealthContributorRegistry.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Map; -import java.util.function.Function; - -/** - * Default {@link HealthContributorRegistry} implementation. - * - * @author Phillip Webb - * @since 2.2.0 - */ -public class DefaultHealthContributorRegistry extends DefaultContributorRegistry - implements HealthContributorRegistry { - - public DefaultHealthContributorRegistry() { - } - - public DefaultHealthContributorRegistry(Map contributors) { - super(contributors); - } - - public DefaultHealthContributorRegistry(Map contributors, - Function nameFactory) { - super(contributors, nameFactory); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultReactiveHealthContributorRegistry.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultReactiveHealthContributorRegistry.java deleted file mode 100644 index 469c784a2152..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/DefaultReactiveHealthContributorRegistry.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Map; -import java.util.function.Function; - -/** - * Default {@link ReactiveHealthContributorRegistry} implementation. - * - * @author Phillip Webb - * @since 2.0.0 - */ -public class DefaultReactiveHealthContributorRegistry extends DefaultContributorRegistry - implements ReactiveHealthContributorRegistry { - - public DefaultReactiveHealthContributorRegistry() { - } - - public DefaultReactiveHealthContributorRegistry(Map contributors) { - super(contributors); - } - - public DefaultReactiveHealthContributorRegistry(Map contributors, - Function nameFactory) { - super(contributors, nameFactory); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthComponent.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthComponent.java deleted file mode 100644 index bd3b3ca766c9..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthComponent.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import com.fasterxml.jackson.annotation.JsonUnwrapped; - -import org.springframework.boot.actuate.endpoint.OperationResponseBody; - -/** - * A component that contributes data to results returned from the {@link HealthEndpoint}. - * - * @author Phillip Webb - * @since 2.2.0 - * @see Health - * @see CompositeHealth - */ -public abstract class HealthComponent implements OperationResponseBody { - - HealthComponent() { - } - - /** - * Return the status of the component. - * @return the component status - */ - @JsonUnwrapped - public abstract Status getStatus(); - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributor.java deleted file mode 100644 index d65e1586d1a5..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributor.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -/** - * Tagging interface for classes that contribute to {@link HealthComponent health - * components} to the results returned from the {@link HealthEndpoint}. A contributor must - * be either a {@link HealthIndicator} or a {@link CompositeHealthContributor}. - * - * @author Phillip Webb - * @since 2.2.0 - * @see HealthIndicator - * @see CompositeHealthContributor - */ -public interface HealthContributor { - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributorNameFactory.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributorNameFactory.java deleted file mode 100644 index aba7b67733bf..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributorNameFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Locale; -import java.util.function.Function; - -/** - * Generate a sensible health indicator name based on its bean name. - * - * @author Stephane Nicoll - * @author Phillip Webb - * @since 2.0.0 - */ -public class HealthContributorNameFactory implements Function { - - private static final String[] SUFFIXES = { "healthindicator", "healthcontributor" }; - - /** - * A shared singleton {@link HealthContributorNameFactory} instance. - */ - public static final HealthContributorNameFactory INSTANCE = new HealthContributorNameFactory(); - - @Override - public String apply(String name) { - for (String suffix : SUFFIXES) { - if (name != null && name.toLowerCase(Locale.ENGLISH).endsWith(suffix)) { - return name.substring(0, name.length() - suffix.length()); - } - } - return name; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributorRegistry.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributorRegistry.java deleted file mode 100644 index 0773dd3d7433..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributorRegistry.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -/** - * {@link ContributorRegistry} for {@link HealthContributor HealthContributors}. - * - * @author Phillip Webb - * @since 2.2.0 - */ -public interface HealthContributorRegistry extends ContributorRegistry { - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpoint.java index bede8fb8d378..bfb6a49be044 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpoint.java @@ -27,6 +27,8 @@ import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.annotation.Selector.Match; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.registry.HealthContributorRegistry; /** * {@link Endpoint @Endpoint} to expose application health information. @@ -39,7 +41,7 @@ * @since 2.0.0 */ @Endpoint(id = "health") -public class HealthEndpoint extends HealthEndpointSupport { +public class HealthEndpoint extends HealthEndpointSupport { /** * Health endpoint id. @@ -54,37 +56,33 @@ public class HealthEndpoint extends HealthEndpointSupport result = getHealth(apiVersion, null, SecurityContext.NONE, true, path); + private ContributedHealth health(ApiVersion apiVersion, String... path) { + HealthResult result = getHealth(apiVersion, null, SecurityContext.NONE, true, path); return (result != null) ? result.getHealth() : null; } @Override - protected HealthComponent getHealth(HealthContributor contributor, boolean includeDetails) { - return ((HealthIndicator) contributor).getHealth(includeDetails); - } - - @Override - protected HealthComponent aggregateContributions(ApiVersion apiVersion, Map contributions, - StatusAggregator statusAggregator, boolean showComponents, Set groupNames) { + protected ContributedHealth aggregateContributions(ApiVersion apiVersion, + Map contributions, StatusAggregator statusAggregator, boolean showComponents, + Set groupNames) { return getCompositeHealth(apiVersion, contributions, statusAggregator, showComponents, groupNames); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointContributor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointContributor.java new file mode 100644 index 000000000000..3541d17441b9 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointContributor.java @@ -0,0 +1,139 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.health; + +import java.util.Iterator; + +import reactor.core.publisher.Mono; + +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthContributors; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributors; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; + +/** + * Allows {@link HealthEndpointSupport} to access blocking or reactive contributors and + * registries in a uniform way. + * + * @param the contributed health component type + * @author Phillip Webb + */ +interface HealthEndpointContributor extends Iterable> { + + /** + * Return if this contributor is a composite and may have children. + * @return if the contributor is a composite + */ + boolean isComposite(); + + /** + * Get the child with the given name. Must only be called if {@link #isComposite()} + * returns {@code true}. + * @param name the child name + * @return the child or {@code null} + */ + HealthEndpointContributor getChild(String name); + + /** + * Get the health. Must only be called if {@link #isComposite()} returns + * {@code false}. + * @param includeDetails if details are to be included. + * @return the health + */ + T getHealth(boolean includeDetails); + + /** + * A child consisting of a name and a contributor. + * + * @param the contributed health component type + * @param name the child name + * @param contributor the contributor + */ + record Child(String name, HealthEndpointContributor contributor) { + + } + + /** + * {@link HealthEndpointContributor} to adapt the blocking {@link HealthContributor} + * and {@link HealthContributors} types. + * + * @param contributor the underlying contributor + */ + record Blocking(Object contributor) implements HealthEndpointContributor { + + @Override + public boolean isComposite() { + return contributor() instanceof HealthContributors; + } + + @Override + public HealthEndpointContributor getChild(String name) { + HealthContributor child = ((HealthContributors) contributor()).getContributor(name); + return (child != null) ? new Blocking(child) : null; + } + + @Override + public Iterator> iterator() { + return ((HealthContributors) contributor()).stream() + .map((entry) -> new Child<>(entry.name(), new Blocking(entry.contributor()))) + .iterator(); + } + + @Override + public ContributedHealth getHealth(boolean includeDetails) { + return ((HealthIndicator) contributor()).getHealth(includeDetails); + } + + } + + /** + * {@link HealthEndpointContributor} to adapt the reactive + * {@link ReactiveHealthContributor} and {@link ReactiveHealthContributors} types. + * + * @param contributor the underlying contributor + */ + record Reactive(Object contributor) implements HealthEndpointContributor> { + + @Override + public boolean isComposite() { + return contributor() instanceof ReactiveHealthContributors; + } + + @Override + public HealthEndpointContributor> getChild(String name) { + ReactiveHealthContributor child = ((ReactiveHealthContributors) contributor()).getContributor(name); + return (child != null) ? new Reactive(child) : null; + } + + @Override + public Iterator>> iterator() { + return ((ReactiveHealthContributors) contributor()).stream() + .map((entry) -> new Child<>(entry.name(), new Reactive(entry.contributor()))) + .iterator(); + } + + @Override + public Mono getHealth(boolean includeDetails) { + return ((ReactiveHealthIndicator) this.contributor).getHealth(includeDetails); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointGroup.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointGroup.java index eba86844db4f..bd9b176ec2ae 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointGroup.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointGroup.java @@ -17,6 +17,9 @@ package org.springframework.boot.actuate.health; import org.springframework.boot.actuate.endpoint.SecurityContext; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributor; /** * A logical grouping of {@link HealthContributor health contributors} that can be exposed diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointSupport.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointSupport.java index 82477575d6f5..a8b59db31565 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointSupport.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointSupport.java @@ -30,6 +30,10 @@ import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.convert.DurationStyle; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.core.log.LogMessage; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -37,18 +41,17 @@ /** * Base class for health endpoints and health endpoint extensions. * - * @param the contributor type * @param the contributed health component type * @author Phillip Webb * @author Scott Frederick */ -abstract class HealthEndpointSupport { +abstract class HealthEndpointSupport { private static final Log logger = LogFactory.getLog(HealthEndpointSupport.class); static final Health DEFAULT_HEALTH = Health.up().build(); - private final ContributorRegistry registry; + private final HealthEndpointContributor root; private final HealthEndpointGroups groups; @@ -56,16 +59,16 @@ abstract class HealthEndpointSupport { /** * Create a new {@link HealthEndpointSupport} instance. - * @param registry the health contributor registry + * @param root the root contributor * @param groups the health endpoint groups * @param slowIndicatorLoggingThreshold duration after which slow health indicator * logging should occur */ - HealthEndpointSupport(ContributorRegistry registry, HealthEndpointGroups groups, + HealthEndpointSupport(HealthEndpointContributor root, HealthEndpointGroups groups, Duration slowIndicatorLoggingThreshold) { - Assert.notNull(registry, "'registry' must not be null"); + Assert.notNull(root, "'root' must not be null"); Assert.notNull(groups, "'groups' must not be null"); - this.registry = registry; + this.root = root; this.groups = groups; this.slowIndicatorLoggingThreshold = slowIndicatorLoggingThreshold; } @@ -101,7 +104,7 @@ private HealthResult getHealth(ApiVersion apiVersion, HealthEndpointGroup gro if (!showComponents && !isRoot) { return null; } - Object contributor = getContributor(path, pathOffset); + HealthEndpointContributor contributor = getContributor(path, pathOffset); if (contributor == null) { return null; } @@ -112,13 +115,13 @@ private HealthResult getHealth(ApiVersion apiVersion, HealthEndpointGroup gro } @SuppressWarnings("unchecked") - private Object getContributor(String[] path, int pathOffset) { - Object contributor = this.registry; + private HealthEndpointContributor getContributor(String[] path, int pathOffset) { + HealthEndpointContributor contributor = this.root; while (pathOffset < path.length) { - if (!(contributor instanceof NamedContributors)) { + if (!contributor.isComposite()) { return null; } - contributor = ((NamedContributors) contributor).getContributor(path[pathOffset]); + contributor = contributor.getChild(path[pathOffset]); pathOffset++; } return contributor; @@ -135,28 +138,29 @@ private String getName(String[] path, int pathOffset) { } @SuppressWarnings("unchecked") - private T getContribution(ApiVersion apiVersion, HealthEndpointGroup group, String name, Object contributor, - boolean showComponents, boolean showDetails, Set groupNames) { - if (contributor instanceof NamedContributors) { - return getAggregateContribution(apiVersion, group, name, (NamedContributors) contributor, showComponents, - showDetails, groupNames); + private T getContribution(ApiVersion apiVersion, HealthEndpointGroup group, String name, + HealthEndpointContributor contributor, boolean showComponents, boolean showDetails, + Set groupNames) { + if (contributor.isComposite()) { + return getAggregateContribution(apiVersion, group, name, contributor, showComponents, showDetails, + groupNames); } if (contributor != null && (name.isEmpty() || group.isMember(name))) { - return getLoggedHealth((C) contributor, name, showDetails); + return getLoggedHealth(contributor, name, showDetails); } return null; } private T getAggregateContribution(ApiVersion apiVersion, HealthEndpointGroup group, String name, - NamedContributors namedContributors, boolean showComponents, boolean showDetails, + HealthEndpointContributor contributor, boolean showComponents, boolean showDetails, Set groupNames) { String prefix = (StringUtils.hasText(name)) ? name + "/" : ""; Map contributions = new LinkedHashMap<>(); - for (NamedContributor child : namedContributors) { - T contribution = getContribution(apiVersion, group, prefix + child.getName(), child.getContributor(), + for (HealthEndpointContributor.Child child : contributor) { + T contribution = getContribution(apiVersion, group, prefix + child.name(), child.contributor(), showComponents, showDetails, null); if (contribution != null) { - contributions.put(child.getName(), contribution); + contributions.put(child.name(), contribution); } } if (contributions.isEmpty()) { @@ -166,10 +170,10 @@ private T getAggregateContribution(ApiVersion apiVersion, HealthEndpointGroup gr groupNames); } - private T getLoggedHealth(C contributor, String name, boolean showDetails) { + private T getLoggedHealth(HealthEndpointContributor contributor, String name, boolean showDetails) { Instant start = Instant.now(); try { - return getHealth(contributor, showDetails); + return contributor.getHealth(showDetails); } finally { if (logger.isWarnEnabled() && this.slowIndicatorLoggingThreshold != null) { @@ -185,23 +189,18 @@ private T getLoggedHealth(C contributor, String name, boolean showDetails) { } } - protected abstract T getHealth(C contributor, boolean includeDetails); - protected abstract T aggregateContributions(ApiVersion apiVersion, Map contributions, StatusAggregator statusAggregator, boolean showComponents, Set groupNames); - protected final CompositeHealth getCompositeHealth(ApiVersion apiVersion, Map components, + protected final CompositeHealth getCompositeHealth(ApiVersion apiVersion, Map components, StatusAggregator statusAggregator, boolean showComponents, Set groupNames) { Status status = statusAggregator .getAggregateStatus(components.values().stream().map(this::getStatus).collect(Collectors.toSet())); - Map instances = showComponents ? components : null; - if (groupNames != null) { - return new SystemHealth(apiVersion, status, instances, groupNames); - } - return new CompositeHealth(apiVersion, status, instances); + Map instances = showComponents ? components : null; + return new SystemHealth(status, instances, groupNames, apiVersion); } - private Status getStatus(HealthComponent component) { + private Status getStatus(ContributedHealth component) { return (component != null) ? component.getStatus() : Status.UNKNOWN; } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java index 0214692fb10b..5205d33f99ac 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java @@ -29,6 +29,8 @@ import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.registry.HealthContributorRegistry; import org.springframework.context.annotation.ImportRuntimeHints; /** @@ -46,7 +48,7 @@ */ @EndpointWebExtension(endpoint = HealthEndpoint.class) @ImportRuntimeHints(HealthEndpointWebExtensionRuntimeHints.class) -public class HealthEndpointWebExtension extends HealthEndpointSupport { +public class HealthEndpointWebExtension extends HealthEndpointSupport { private static final String[] NO_PATH = {}; @@ -56,47 +58,43 @@ public class HealthEndpointWebExtension extends HealthEndpointSupport health(ApiVersion apiVersion, WebServerNamespace serverNamespace, + public WebEndpointResponse health(ApiVersion apiVersion, WebServerNamespace serverNamespace, SecurityContext securityContext) { return health(apiVersion, serverNamespace, securityContext, false, NO_PATH); } @ReadOperation - public WebEndpointResponse health(ApiVersion apiVersion, WebServerNamespace serverNamespace, + public WebEndpointResponse health(ApiVersion apiVersion, WebServerNamespace serverNamespace, SecurityContext securityContext, @Selector(match = Match.ALL_REMAINING) String... path) { return health(apiVersion, serverNamespace, securityContext, false, path); } - public WebEndpointResponse health(ApiVersion apiVersion, WebServerNamespace serverNamespace, + public WebEndpointResponse health(ApiVersion apiVersion, WebServerNamespace serverNamespace, SecurityContext securityContext, boolean showAll, String... path) { - HealthResult result = getHealth(apiVersion, serverNamespace, securityContext, showAll, path); + HealthResult result = getHealth(apiVersion, serverNamespace, securityContext, showAll, path); if (result == null) { return (Arrays.equals(path, NO_PATH)) ? new WebEndpointResponse<>(DEFAULT_HEALTH, WebEndpointResponse.STATUS_OK) : new WebEndpointResponse<>(WebEndpointResponse.STATUS_NOT_FOUND); } - HealthComponent health = result.getHealth(); + ContributedHealth health = result.getHealth(); HealthEndpointGroup group = result.getGroup(); int statusCode = group.getHttpCodeStatusMapper().getStatusCode(health.getStatus()); return new WebEndpointResponse<>(health, statusCode); } @Override - protected HealthComponent getHealth(HealthContributor contributor, boolean includeDetails) { - return ((HealthIndicator) contributor).getHealth(includeDetails); - } - - @Override - protected HealthComponent aggregateContributions(ApiVersion apiVersion, Map contributions, - StatusAggregator statusAggregator, boolean showComponents, Set groupNames) { + protected ContributedHealth aggregateContributions(ApiVersion apiVersion, + Map contributions, StatusAggregator statusAggregator, boolean showComponents, + Set groupNames) { return getCompositeHealth(apiVersion, contributions, statusAggregator, showComponents, groupNames); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHints.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHints.java index dca55a047fd2..9fa243d1a8d0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHints.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHints.java @@ -19,6 +19,8 @@ import org.springframework.aot.hint.BindingReflectionHintsRegistrar; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.Health; /** * {@link RuntimeHintsRegistrar} used by {@link HealthEndpointWebExtension} and diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HttpCodeStatusMapper.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HttpCodeStatusMapper.java index 53af03e03cb9..22e85966a4e9 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HttpCodeStatusMapper.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HttpCodeStatusMapper.java @@ -16,6 +16,8 @@ package org.springframework.boot.actuate.health; +import org.springframework.boot.health.contributor.Status; + /** * Strategy used to map a {@link Status health status} to an HTTP status code. * diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributor.java deleted file mode 100644 index 3acb5b9192b0..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import org.springframework.util.Assert; - -/** - * A single named health endpoint contributors (either {@link HealthContributor} or - * {@link ReactiveHealthContributor}). - * - * @param the contributor type - * @author Phillip Webb - * @since 2.0.0 - * @see NamedContributors - */ -public interface NamedContributor { - - /** - * Returns the name of the contributor. - * @return the contributor name - */ - String getName(); - - /** - * Returns the contributor instance. - * @return the contributor instance - */ - C getContributor(); - - static NamedContributor of(String name, C contributor) { - Assert.notNull(name, "'name' must not be null"); - Assert.notNull(contributor, "'contributor' must not be null"); - return new NamedContributor<>() { - - @Override - public String getName() { - return name; - } - - @Override - public C getContributor() { - return contributor; - } - - }; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributors.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributors.java deleted file mode 100644 index bc945df5c9ef..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributors.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -/** - * A collection of named health endpoint contributors (either {@link HealthContributor} or - * {@link ReactiveHealthContributor}). - * - * @param the contributor type - * @author Phillip Webb - * @since 2.0.0 - * @see NamedContributor - */ -public interface NamedContributors extends Iterable> { - - /** - * Return the contributor with the given name. - * @param name the name of the contributor - * @return a contributor instance or {@code null} - */ - C getContributor(String name); - - /** - * Return a stream of the {@link NamedContributor named contributors}. - * @return the stream of named contributors - */ - default Stream> stream() { - return StreamSupport.stream(spliterator(), false); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributorsMapAdapter.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributorsMapAdapter.java deleted file mode 100644 index 2b0a6c149b4a..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/NamedContributorsMapAdapter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.function.Function; - -import org.springframework.util.Assert; - -/** - * {@link NamedContributors} backed by a map with values adapted as necessary. - * - * @param the value type - * @param the contributor type - * @author Phillip Webb - * @author Guirong Hu - * @see CompositeHealthContributorMapAdapter - * @see CompositeReactiveHealthContributorMapAdapter - */ -abstract class NamedContributorsMapAdapter implements NamedContributors { - - private final Map map; - - NamedContributorsMapAdapter(Map map, Function valueAdapter) { - Assert.notNull(map, "'map' must not be null"); - Assert.notNull(valueAdapter, "'valueAdapter' must not be null"); - map.keySet().forEach(this::validateMapKey); - this.map = Collections.unmodifiableMap(map.entrySet().stream().collect(LinkedHashMap::new, (result, entry) -> { - String key = entry.getKey(); - C value = adaptMapValue(entry.getValue(), valueAdapter); - result.put(key, value); - }, Map::putAll)); - - } - - private void validateMapKey(String value) { - Assert.notNull(value, "'map' must not contain null keys"); - Assert.isTrue(!value.contains("/"), "'map' keys must not contain a '/'"); - } - - private C adaptMapValue(V value, Function valueAdapter) { - C contributor = (value != null) ? valueAdapter.apply(value) : null; - Assert.notNull(contributor, "'map' must not contain null values"); - return contributor; - } - - @Override - public Iterator> iterator() { - Iterator> iterator = this.map.entrySet().iterator(); - return new Iterator<>() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public NamedContributor next() { - Entry entry = iterator.next(); - return NamedContributor.of(entry.getKey(), entry.getValue()); - } - - }; - } - - @Override - public C getContributor(String name) { - return this.map.get(name); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthContributor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthContributor.java deleted file mode 100644 index 84e1331ef0cd..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthContributor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import org.springframework.util.Assert; - -/** - * Tagging interface for classes that contribute to {@link HealthComponent health - * components} to the results returned from the {@link HealthEndpoint}. A contributor must - * be either a {@link ReactiveHealthIndicator} or a - * {@link CompositeReactiveHealthContributor}. - * - * @author Phillip Webb - * @since 2.2.0 - * @see ReactiveHealthIndicator - * @see CompositeReactiveHealthContributor - */ -public interface ReactiveHealthContributor { - - static ReactiveHealthContributor adapt(HealthContributor healthContributor) { - Assert.notNull(healthContributor, "'healthContributor' must not be null"); - if (healthContributor instanceof HealthIndicator healthIndicator) { - return new HealthIndicatorReactiveAdapter(healthIndicator); - } - if (healthContributor instanceof CompositeHealthContributor compositeHealthContributor) { - return new CompositeHealthContributorReactiveAdapter(compositeHealthContributor); - } - throw new IllegalStateException("Unknown HealthContributor type"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthContributorRegistry.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthContributorRegistry.java deleted file mode 100644 index 06ae7b5fda20..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthContributorRegistry.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -/** - * {@link ContributorRegistry} for {@link ReactiveHealthContributor - * ReactiveHealthContributors}. - * - * @author Phillip Webb - * @since 2.2.0 - */ -public interface ReactiveHealthContributorRegistry extends ContributorRegistry { - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtension.java index 34d480192c00..25722a3bc14e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtension.java @@ -32,6 +32,8 @@ import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.registry.ReactiveHealthContributorRegistry; import org.springframework.context.annotation.ImportRuntimeHints; /** @@ -45,8 +47,7 @@ */ @EndpointWebExtension(endpoint = HealthEndpoint.class) @ImportRuntimeHints(HealthEndpointWebExtensionRuntimeHints.class) -public class ReactiveHealthEndpointWebExtension - extends HealthEndpointSupport> { +public class ReactiveHealthEndpointWebExtension extends HealthEndpointSupport> { private static final String[] NO_PATH = {}; @@ -56,29 +57,29 @@ public class ReactiveHealthEndpointWebExtension * @param groups the health endpoint groups * @param slowIndicatorLoggingThreshold duration after which slow health indicator * logging should occur - * @since 2.6.9 + * @since 4.0.0 */ public ReactiveHealthEndpointWebExtension(ReactiveHealthContributorRegistry registry, HealthEndpointGroups groups, Duration slowIndicatorLoggingThreshold) { - super(registry, groups, slowIndicatorLoggingThreshold); + super(new HealthEndpointContributor.Reactive(registry), groups, slowIndicatorLoggingThreshold); } @ReadOperation - public Mono> health(ApiVersion apiVersion, + public Mono> health(ApiVersion apiVersion, WebServerNamespace serverNamespace, SecurityContext securityContext) { return health(apiVersion, serverNamespace, securityContext, false, NO_PATH); } @ReadOperation - public Mono> health(ApiVersion apiVersion, + public Mono> health(ApiVersion apiVersion, WebServerNamespace serverNamespace, SecurityContext securityContext, @Selector(match = Match.ALL_REMAINING) String... path) { return health(apiVersion, serverNamespace, securityContext, false, path); } - public Mono> health(ApiVersion apiVersion, + public Mono> health(ApiVersion apiVersion, WebServerNamespace serverNamespace, SecurityContext securityContext, boolean showAll, String... path) { - HealthResult> result = getHealth(apiVersion, serverNamespace, securityContext, + HealthResult> result = getHealth(apiVersion, serverNamespace, securityContext, showAll, path); if (result == null) { return (Arrays.equals(path, NO_PATH)) @@ -93,13 +94,8 @@ public Mono> health(ApiVersion ap } @Override - protected Mono getHealth(ReactiveHealthContributor contributor, boolean includeDetails) { - return ((ReactiveHealthIndicator) contributor).getHealth(includeDetails); - } - - @Override - protected Mono aggregateContributions(ApiVersion apiVersion, - Map> contributions, StatusAggregator statusAggregator, + protected Mono aggregateContributions(ApiVersion apiVersion, + Map> contributions, StatusAggregator statusAggregator, boolean showComponents, Set groupNames) { return Flux.fromIterable(contributions.entrySet()) .flatMap(NamedHealthComponent::create) @@ -109,30 +105,30 @@ protected Mono aggregateContributions(ApiVersion apiV } /** - * A named {@link HealthComponent}. + * A named {@link ContributedHealth}. */ private static final class NamedHealthComponent { private final String name; - private final HealthComponent health; + private final ContributedHealth health; private NamedHealthComponent(Object... pair) { this.name = (String) pair[0]; - this.health = (HealthComponent) pair[1]; + this.health = (ContributedHealth) pair[1]; } String getName() { return this.name; } - HealthComponent getHealth() { + ContributedHealth getHealth() { return this.health; } - static Mono create(Map.Entry> entry) { + static Mono create(Map.Entry> entry) { Mono name = Mono.just(entry.getKey()); - Mono health = entry.getValue(); + Mono health = entry.getValue(); return Mono.zip(NamedHealthComponent::new, name, health); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthIndicator.java deleted file mode 100644 index f1410a7f2d19..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthIndicator.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import reactor.core.publisher.Mono; - -/** - * Strategy interface used to contribute {@link Health} to the results returned from the - * reactive variant of the {@link HealthEndpoint}. - *

- * This is non-blocking contract that is meant to be used in a reactive application. See - * {@link HealthIndicator} for the traditional contract. - * - * @author Stephane Nicoll - * @since 2.0.0 - * @see HealthIndicator - */ -@FunctionalInterface -public interface ReactiveHealthIndicator extends ReactiveHealthContributor { - - /** - * Provide the indicator of health. - * @param includeDetails if details should be included or removed - * @return a {@link Mono} that provides the {@link Health} - * @since 2.2.0 - */ - default Mono getHealth(boolean includeDetails) { - Mono health = health(); - return includeDetails ? health : health.map(Health::withoutDetails); - } - - /** - * Provide the indicator of health. - * @return a {@link Mono} that provides the {@link Health} - */ - Mono health(); - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleHttpCodeStatusMapper.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleHttpCodeStatusMapper.java index ed2ad52c3639..db29e4211e01 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleHttpCodeStatusMapper.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleHttpCodeStatusMapper.java @@ -22,6 +22,7 @@ import java.util.Map; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; +import org.springframework.boot.health.contributor.Status; import org.springframework.util.CollectionUtils; /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleStatusAggregator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleStatusAggregator.java index 1ef94c296203..a864d15eb335 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleStatusAggregator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleStatusAggregator.java @@ -24,6 +24,7 @@ import java.util.Set; import java.util.stream.Stream; +import org.springframework.boot.health.contributor.Status; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/StatusAggregator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/StatusAggregator.java index 91eaf63b4fd7..f22e3543c099 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/StatusAggregator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/StatusAggregator.java @@ -20,6 +20,9 @@ import java.util.LinkedHashSet; import java.util.Set; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; + /** * Strategy used to aggregate {@link Status} instances. *

diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SystemHealth.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SystemHealth.java index 6d79915cfc38..bc50d96c45cf 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SystemHealth.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SystemHealth.java @@ -22,23 +22,41 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.boot.actuate.endpoint.ApiVersion; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Status; /** - * A {@link HealthComponent} that represents the overall system health and the available + * A {@link CompositeHealth} that represents the overall system health and the available * groups. * * @author Phillip Webb - * @since 2.2.0 + * @since 4.0.0 */ public final class SystemHealth extends CompositeHealth { + private final ApiVersion apiVersion; + private final Set groups; - SystemHealth(ApiVersion apiVersion, Status status, Map instances, Set groups) { - super(apiVersion, status, instances); + SystemHealth(Status status, Map components, Set groups, ApiVersion apiVersion) { + super(status, components); this.groups = (groups != null) ? new TreeSet<>(groups) : null; + this.apiVersion = apiVersion; + } + + @Override + public Map getComponents() { + return (this.apiVersion == ApiVersion.V3) ? super.getComponents() : null; + } + + @JsonProperty + @JsonInclude(Include.NON_EMPTY) + public Map getDetails() { + return (this.apiVersion == ApiVersion.V2) ? super.getComponents() : null; } @JsonInclude(Include.NON_EMPTY) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/integration/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/integration/package-info.java deleted file mode 100644 index 3dbfcbdc026f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/integration/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Spring Integration. - */ -package org.springframework.boot.actuate.integration; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/package-info.java deleted file mode 100644 index fedb6f2b59d5..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for JDBC. - */ -package org.springframework.boot.actuate.jdbc; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jms/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jms/package-info.java deleted file mode 100644 index 74f61703a31c..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jms/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for JMS. - */ -package org.springframework.boot.actuate.jms; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ldap/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ldap/package-info.java deleted file mode 100644 index 678e0cb51286..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ldap/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for LDAP. - */ -package org.springframework.boot.actuate.ldap; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/liquibase/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/liquibase/package-info.java deleted file mode 100644 index 145b998a3972..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/liquibase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Liquibase. - */ -package org.springframework.boot.actuate.liquibase; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/package-info.java deleted file mode 100644 index 1c98e36b715a..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for JavaMail. - */ -package org.springframework.boot.actuate.mail; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/package-info.java deleted file mode 100644 index 0af97df81aa6..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for RabbitMQ Java Client metrics. - */ -package org.springframework.boot.actuate.metrics.amqp; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/annotation/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/annotation/package-info.java deleted file mode 100644 index dc8435384cc0..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/annotation/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support classes for handler method metrics. - */ -package org.springframework.boot.actuate.metrics.annotation; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/package-info.java deleted file mode 100644 index f8a57d72b458..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for cache metrics. - */ -package org.springframework.boot.actuate.metrics.cache; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/package-info.java deleted file mode 100644 index 9c2618483db2..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Spring Data Repository metrics. - */ -package org.springframework.boot.actuate.metrics.data; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/http/Outcome.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/http/Outcome.java deleted file mode 100644 index f0edc47fb7b0..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/http/Outcome.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.metrics.http; - -import io.micrometer.core.instrument.Tag; - -/** - * The outcome of an HTTP request. - * - * @author Andy Wilkinson - * @since 2.2.0 - */ -public enum Outcome { - - /** - * Outcome of the request was informational. - */ - INFORMATIONAL, - - /** - * Outcome of the request was success. - */ - SUCCESS, - - /** - * Outcome of the request was redirection. - */ - REDIRECTION, - - /** - * Outcome of the request was client error. - */ - CLIENT_ERROR, - - /** - * Outcome of the request was server error. - */ - SERVER_ERROR, - - /** - * Outcome of the request was unknown. - */ - UNKNOWN; - - private final Tag tag; - - Outcome() { - this.tag = Tag.of("outcome", name()); - } - - /** - * Returns the {@code Outcome} as a {@link Tag} named {@code outcome}. - * @return the {@code outcome} {@code Tag} - */ - public Tag asTag() { - return this.tag; - } - - /** - * Return the {@code Outcome} for the given HTTP {@code status} code. - * @param status the HTTP status code - * @return the matching Outcome - */ - public static Outcome forStatus(int status) { - if (status >= 100 && status < 200) { - return INFORMATIONAL; - } - else if (status >= 200 && status < 300) { - return SUCCESS; - } - else if (status >= 300 && status < 400) { - return REDIRECTION; - } - else if (status >= 400 && status < 500) { - return CLIENT_ERROR; - } - else if (status >= 500 && status < 600) { - return SERVER_ERROR; - } - return UNKNOWN; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/http/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/http/package-info.java deleted file mode 100644 index 9dd9cf7b1f84..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/http/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support classes for HTTP-related metrics. - */ -package org.springframework.boot.actuate.metrics.http; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jdbc/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jdbc/package-info.java deleted file mode 100644 index 9dd5e4f8f20c..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jdbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for JDBC metrics. - */ -package org.springframework.boot.actuate.metrics.jdbc; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/package-info.java deleted file mode 100644 index 9222151ea162..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Core actuator support for metrics. - */ -package org.springframework.boot.actuate.metrics; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/r2dbc/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/r2dbc/package-info.java deleted file mode 100644 index 8759696ee56e..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/r2dbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for R2DBC metrics. - */ -package org.springframework.boot.actuate.metrics.r2dbc; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/package-info.java deleted file mode 100644 index 7a0289d5d692..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for startup metrics. - */ -package org.springframework.boot.actuate.metrics.startup; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/package-info.java deleted file mode 100644 index 9bee8eefdeba..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for system metrics. - */ -package org.springframework.boot.actuate.metrics.system; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/package-info.java deleted file mode 100644 index d279138ecc3f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for web client metrics. - */ -package org.springframework.boot.actuate.metrics.web.client; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/package-info.java deleted file mode 100644 index c9125a15c6e5..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Jetty metrics. - */ -package org.springframework.boot.actuate.metrics.web.jetty; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/package-info.java deleted file mode 100644 index 549eb39f8ebb..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for {@link org.springframework.web.reactive.function.client.WebClient} - * metrics. - */ -package org.springframework.boot.actuate.metrics.web.reactive.client; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/package-info.java deleted file mode 100644 index 6c53a7f2cd78..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Tomcat metrics. - */ -package org.springframework.boot.actuate.metrics.web.tomcat; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/package-info.java deleted file mode 100644 index a447f3db88bd..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Neo4j. - */ -package org.springframework.boot.actuate.neo4j; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/package-info.java deleted file mode 100644 index b783e26169a9..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Quartz Scheduler. - */ -package org.springframework.boot.actuate.quartz; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/r2dbc/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/r2dbc/package-info.java deleted file mode 100644 index 5b39a4a6d9ba..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/r2dbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for R2DBC. - */ -package org.springframework.boot.actuate.r2dbc; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/package-info.java deleted file mode 100644 index 52cb90b8e145..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator support for Spring Session. - */ -package org.springframework.boot.actuate.session; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ssl/SslHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ssl/SslHealthIndicator.java index 7c8a0ee62499..e2c4ec6a17bc 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ssl/SslHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ssl/SslHealthIndicator.java @@ -22,10 +22,10 @@ import java.util.List; import java.util.stream.Stream; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.info.SslInfo; import org.springframework.boot.info.SslInfo.BundleInfo; import org.springframework.boot.info.SslInfo.CertificateChainInfo; @@ -54,7 +54,7 @@ public SslHealthIndicator(SslInfo sslInfo, Duration expiryThreshold) { } @Override - protected void doHealthCheck(Builder builder) throws Exception { + protected void doHealthCheck(Health.Builder builder) throws Exception { List validCertificateChains = new ArrayList<>(); List invalidCertificateChains = new ArrayList<>(); List expiringCerificateChains = new ArrayList<>(); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicator.java index 2699a12004d2..7a2494ad3fad 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicator.java @@ -21,10 +21,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.core.log.LogMessage; import org.springframework.util.unit.DataSize; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/package-info.java deleted file mode 100644 index aec0ab116512..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator HTTP exchanges support for reactive servers. - * - * @see org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository - */ -package org.springframework.boot.actuate.web.exchanges.reactive; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/package-info.java deleted file mode 100644 index e1020dd754bf..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator HTTP exchanges support for servlet servers. - * - * @see org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository - */ -package org.springframework.boot.actuate.web.exchanges.servlet; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/HandlerFunctionDescription.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/HandlerFunctionDescription.java deleted file mode 100644 index 9e10d12948cb..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/HandlerFunctionDescription.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.web.mappings.reactive; - -import org.springframework.web.reactive.function.server.HandlerFunction; - -/** - * Description of a {@link HandlerFunction}. - * - * @author Andy Wilkinson - * @since 2.0.0 - */ -public class HandlerFunctionDescription { - - private final String className; - - HandlerFunctionDescription(HandlerFunction handlerFunction) { - this.className = getHandlerFunctionClassName(handlerFunction); - } - - private static String getHandlerFunctionClassName(HandlerFunction handlerFunction) { - Class functionClass = handlerFunction.getClass(); - String canonicalName = functionClass.getCanonicalName(); - return (canonicalName != null) ? canonicalName : functionClass.getName(); - } - - public String getClassName() { - return this.className; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/RequestMappingConditionsDescription.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/RequestMappingConditionsDescription.java deleted file mode 100644 index 1b8960ad5b11..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/RequestMappingConditionsDescription.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.web.mappings.reactive; - -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.reactive.result.condition.MediaTypeExpression; -import org.springframework.web.reactive.result.condition.NameValueExpression; -import org.springframework.web.reactive.result.method.RequestMappingInfo; -import org.springframework.web.util.pattern.PathPattern; - -/** - * Description of the conditions of a {@link RequestMappingInfo}. - * - * @author Andy Wilkinson - * @since 2.0.0 - */ -public class RequestMappingConditionsDescription { - - private final List consumes; - - private final List headers; - - private final Set methods; - - private final List params; - - private final Set patterns; - - private final List produces; - - RequestMappingConditionsDescription(RequestMappingInfo requestMapping) { - this.consumes = requestMapping.getConsumesCondition() - .getExpressions() - .stream() - .map(MediaTypeExpressionDescription::new) - .toList(); - this.headers = requestMapping.getHeadersCondition() - .getExpressions() - .stream() - .map(NameValueExpressionDescription::new) - .toList(); - this.methods = requestMapping.getMethodsCondition().getMethods(); - this.params = requestMapping.getParamsCondition() - .getExpressions() - .stream() - .map(NameValueExpressionDescription::new) - .toList(); - this.patterns = requestMapping.getPatternsCondition() - .getPatterns() - .stream() - .map(PathPattern::getPatternString) - .collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet)); - this.produces = requestMapping.getProducesCondition() - .getExpressions() - .stream() - .map(MediaTypeExpressionDescription::new) - .toList(); - } - - public List getConsumes() { - return this.consumes; - } - - public List getHeaders() { - return this.headers; - } - - public Set getMethods() { - return this.methods; - } - - public List getParams() { - return this.params; - } - - public Set getPatterns() { - return this.patterns; - } - - public List getProduces() { - return this.produces; - } - - /** - * A description of a {@link MediaTypeExpression} in a request mapping condition. - */ - public static class MediaTypeExpressionDescription { - - private final String mediaType; - - private final boolean negated; - - MediaTypeExpressionDescription(MediaTypeExpression expression) { - this.mediaType = expression.getMediaType().toString(); - this.negated = expression.isNegated(); - } - - public String getMediaType() { - return this.mediaType; - } - - public boolean isNegated() { - return this.negated; - } - - } - - /** - * A description of a {@link NameValueExpression} in a request mapping condition. - */ - public static class NameValueExpressionDescription { - - private final String name; - - private final Object value; - - private final boolean negated; - - NameValueExpressionDescription(NameValueExpression expression) { - this.name = expression.getName(); - this.value = expression.getValue(); - this.negated = expression.isNegated(); - } - - public String getName() { - return this.name; - } - - public Object getValue() { - return this.value; - } - - public boolean isNegated() { - return this.negated; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/package-info.java deleted file mode 100644 index a0891c48346c..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator reactive request mappings support. - */ -package org.springframework.boot.actuate.web.mappings.reactive; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/HandlerFunctionDescription.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/HandlerFunctionDescription.java deleted file mode 100644 index 1bb21d5f85ee..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/HandlerFunctionDescription.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.web.mappings.servlet; - -import org.springframework.web.servlet.function.HandlerFunction; - -/** - * Description of a {@link HandlerFunction}. - * - * @author Xiong Tang - * @since 3.5.0 - */ -public class HandlerFunctionDescription { - - private final String className; - - HandlerFunctionDescription(HandlerFunction handlerFunction) { - this.className = getHandlerFunctionClassName(handlerFunction); - } - - private static String getHandlerFunctionClassName(HandlerFunction handlerFunction) { - Class functionClass = handlerFunction.getClass(); - String canonicalName = functionClass.getCanonicalName(); - return (canonicalName != null) ? canonicalName : functionClass.getName(); - } - - public String getClassName() { - return this.className; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/RequestMappingConditionsDescription.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/RequestMappingConditionsDescription.java deleted file mode 100644 index c01b50aae1bf..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/RequestMappingConditionsDescription.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.web.mappings.servlet; - -import java.util.List; -import java.util.Set; - -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.mvc.condition.MediaTypeExpression; -import org.springframework.web.servlet.mvc.condition.NameValueExpression; -import org.springframework.web.servlet.mvc.method.RequestMappingInfo; - -/** - * Description of the conditions of a {@link RequestMappingInfo}. - * - * @author Andy Wilkinson - * @since 2.0.0 - */ -public class RequestMappingConditionsDescription { - - private final List consumes; - - private final List headers; - - private final Set methods; - - private final List params; - - private final Set patterns; - - private final List produces; - - RequestMappingConditionsDescription(RequestMappingInfo requestMapping) { - this.consumes = requestMapping.getConsumesCondition() - .getExpressions() - .stream() - .map(MediaTypeExpressionDescription::new) - .toList(); - this.headers = requestMapping.getHeadersCondition() - .getExpressions() - .stream() - .map(NameValueExpressionDescription::new) - .toList(); - this.methods = requestMapping.getMethodsCondition().getMethods(); - this.params = requestMapping.getParamsCondition() - .getExpressions() - .stream() - .map(NameValueExpressionDescription::new) - .toList(); - this.patterns = extractPathPatterns(requestMapping); - this.produces = requestMapping.getProducesCondition() - .getExpressions() - .stream() - .map(MediaTypeExpressionDescription::new) - .toList(); - } - - @SuppressWarnings({ "removal", "deprecation" }) - private Set extractPathPatterns(RequestMappingInfo requestMapping) { - org.springframework.web.servlet.mvc.condition.PatternsRequestCondition patternsCondition = requestMapping - .getPatternsCondition(); - return (patternsCondition != null) ? patternsCondition.getPatterns() - : requestMapping.getPathPatternsCondition().getPatternValues(); - } - - public List getConsumes() { - return this.consumes; - } - - public List getHeaders() { - return this.headers; - } - - public Set getMethods() { - return this.methods; - } - - public List getParams() { - return this.params; - } - - public Set getPatterns() { - return this.patterns; - } - - public List getProduces() { - return this.produces; - } - - /** - * A description of a {@link MediaTypeExpression} in a request mapping condition. - */ - public static class MediaTypeExpressionDescription { - - private final String mediaType; - - private final boolean negated; - - MediaTypeExpressionDescription(MediaTypeExpression expression) { - this.mediaType = expression.getMediaType().toString(); - this.negated = expression.isNegated(); - } - - public String getMediaType() { - return this.mediaType; - } - - public boolean isNegated() { - return this.negated; - } - - } - - /** - * A description of a {@link NameValueExpression} in a request mapping condition. - */ - public static class NameValueExpressionDescription { - - private final String name; - - private final Object value; - - private final boolean negated; - - NameValueExpressionDescription(NameValueExpression expression) { - this.name = expression.getName(); - this.value = expression.getValue(); - this.negated = expression.isNegated(); - } - - public String getName() { - return this.name; - } - - public Object getValue() { - return this.value; - } - - public boolean isNegated() { - return this.negated; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/package-info.java deleted file mode 100644 index 4e4234edf57e..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Actuator servlet request mappings support. - */ -package org.springframework.boot.actuate.web.mappings.servlet; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicatorTests.java index e6b63f311c24..f902702d30e4 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicatorTests.java @@ -21,10 +21,10 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.availability.ApplicationAvailability; import org.springframework.boot.availability.AvailabilityState; import org.springframework.boot.availability.LivenessState; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicatorTests.java index 4f936f21f4af..ac83a47ef882 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicatorTests.java @@ -19,9 +19,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.availability.ApplicationAvailability; import org.springframework.boot.availability.LivenessState; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicatorTests.java index c0a4615d7522..69ab89b15008 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicatorTests.java @@ -19,9 +19,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.availability.ApplicationAvailability; import org.springframework.boot.availability.ReadinessState; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscovererTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscovererTests.java index b8f97d667fc9..6f1af1749274 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscovererTests.java @@ -562,13 +562,6 @@ protected TestExposableEndpoint createEndpoint(Object endpointBean, EndpointId i return new TestExposableEndpoint(this, endpointBean, id, defaultAccess, operations); } - @Override - @SuppressWarnings("removal") - protected TestExposableEndpoint createEndpoint(Object endpointBean, EndpointId id, boolean enabledByDefault, - Collection operations) { - return new TestExposableEndpoint(this, endpointBean, id, enabledByDefault, operations); - } - @Override protected TestOperation createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod, OperationInvoker invoker) { @@ -603,13 +596,6 @@ protected SpecializedExposableEndpoint createEndpoint(Object endpointBean, Endpo return new SpecializedExposableEndpoint(this, endpointBean, id, defaultAccess, operations); } - @Override - @SuppressWarnings("removal") - protected SpecializedExposableEndpoint createEndpoint(Object endpointBean, EndpointId id, - boolean enabledByDefault, Collection operations) { - return new SpecializedExposableEndpoint(this, endpointBean, id, enabledByDefault, operations); - } - @Override protected SpecializedOperation createOperation(EndpointId endpointId, DiscoveredOperationMethod operationMethod, OperationInvoker invoker) { @@ -631,12 +617,6 @@ static class TestExposableEndpoint extends AbstractDiscoveredEndpoint discoverer, Object endpointBean, EndpointId id, - boolean enabledByDefault, Collection operations) { - super(discoverer, endpointBean, id, enabledByDefault, operations); - } - } static class SpecializedExposableEndpoint extends AbstractDiscoveredEndpoint { @@ -647,12 +627,6 @@ static class SpecializedExposableEndpoint extends AbstractDiscoveredEndpoint discoverer, Object endpointBean, EndpointId id, - boolean enabledByDefault, Collection operations) { - super(discoverer, endpointBean, id, enabledByDefault, operations); - } - } static class TestOperation extends AbstractDiscoveredOperation { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/TestExposableJmxEndpoint.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/TestExposableJmxEndpoint.java index 9883b068a60e..e6a45c5c5537 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/TestExposableJmxEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/TestExposableJmxEndpoint.java @@ -44,12 +44,6 @@ public EndpointId getEndpointId() { return EndpointId.of("test"); } - @Override - @SuppressWarnings("removal") - public boolean isEnableByDefault() { - return true; - } - @Override public Collection getOperations() { return this.operations; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointLinksResolverTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointLinksResolverTests.java index f0fb6dede42e..7eaf0edeb983 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointLinksResolverTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/EndpointLinksResolverTests.java @@ -63,7 +63,6 @@ void resolvedLinksContainsALinkForEachWebEndpointOperation() { operations.add(operationWithPath("/alpha/{name}", "alpha-name")); ExposableWebEndpoint endpoint = mock(ExposableWebEndpoint.class); given(endpoint.getEndpointId()).willReturn(EndpointId.of("alpha")); - given(endpoint.isEnableByDefault()).willReturn(true); given(endpoint.getOperations()).willReturn(operations); String requestUrl = "https://api.example.com/actuator"; Map links = new EndpointLinksResolver(Collections.singletonList(endpoint)) @@ -80,7 +79,6 @@ void resolvedLinksContainsALinkForEachWebEndpointOperation() { void resolvedLinksContainsALinkForServletEndpoint() { ExposableServletEndpoint servletEndpoint = mock(ExposableServletEndpoint.class); given(servletEndpoint.getEndpointId()).willReturn(EndpointId.of("alpha")); - given(servletEndpoint.isEnableByDefault()).willReturn(true); given(servletEndpoint.getRootPath()).willReturn("alpha"); String requestUrl = "https://api.example.com/actuator"; Map links = new EndpointLinksResolver(Collections.singletonList(servletEndpoint)) @@ -94,7 +92,6 @@ void resolvedLinksContainsALinkForServletEndpoint() { void resolvedLinksContainsALinkForControllerEndpoint() { ExposableControllerEndpoint controllerEndpoint = mock(ExposableControllerEndpoint.class); given(controllerEndpoint.getEndpointId()).willReturn(EndpointId.of("alpha")); - given(controllerEndpoint.isEnableByDefault()).willReturn(true); given(controllerEndpoint.getRootPath()).willReturn("alpha"); String requestUrl = "https://api.example.com/actuator"; Map links = new EndpointLinksResolver(Collections.singletonList(controllerEndpoint)) diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java index b486e63ec228..6e65ab796905 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java @@ -25,7 +25,6 @@ import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.PathMapper; -import org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,17 +42,8 @@ class BaseConfiguration { @Bean - AbstractWebEndpointIntegrationTests.EndpointDelegate endpointDelegate() { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader instanceof TomcatEmbeddedWebappClassLoader) { - Thread.currentThread().setContextClassLoader(classLoader.getParent()); - } - try { - return mock(AbstractWebEndpointIntegrationTests.EndpointDelegate.class); - } - finally { - Thread.currentThread().setContextClassLoader(classLoader); - } + EndpointDelegate endpointDelegate() { + return mock(EndpointDelegate.class); } @Bean @@ -77,4 +67,14 @@ static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer return new PropertySourcesPlaceholderConfigurer(); } + interface EndpointDelegate { + + void write(); + + void write(String foo, String bar); + + void delete(); + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java index eafa33843e45..dcdec9d7130b 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java @@ -31,10 +31,10 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.validation.annotation.Validated; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java index b2a6584f9499..fc26782affbd 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java @@ -39,10 +39,10 @@ import org.springframework.boot.actuate.endpoint.web.EndpointServlet; import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.validation.annotation.Validated; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java deleted file mode 100644 index d029bba55d21..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.jersey; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; - -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.ws.rs.ext.ContextResolver; -import org.glassfish.jersey.jackson.JacksonFeature; -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.model.Resource; -import org.glassfish.jersey.servlet.ServletContainer; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; -import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests; -import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpStatus; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.util.StringUtils; -import org.springframework.web.filter.OncePerRequestFilter; - -/** - * Integration tests for web endpoints exposed using Jersey. - * - * @author Andy Wilkinson - * @see JerseyEndpointResourceFactory - */ -class JerseyWebEndpointIntegrationTests - extends AbstractWebEndpointIntegrationTests { - - JerseyWebEndpointIntegrationTests() { - super(JerseyWebEndpointIntegrationTests::createApplicationContext, - JerseyWebEndpointIntegrationTests::applyAuthenticatedConfiguration); - } - - private static AnnotationConfigServletWebServerApplicationContext createApplicationContext() { - AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); - context.register(JerseyConfiguration.class); - return context; - } - - private static void applyAuthenticatedConfiguration(AnnotationConfigServletWebServerApplicationContext context) { - context.register(AuthenticatedConfiguration.class); - } - - @Override - protected int getPort(AnnotationConfigServletWebServerApplicationContext context) { - return context.getWebServer().getPort(); - } - - @Override - protected void validateErrorBody(WebTestClient.BodyContentSpec body, HttpStatus status, String path, - String message) { - // Jersey doesn't support the general error page handling - } - - @Override - @Test - @Disabled("Jersey does not distinguish between /example and /example/") - protected void operationWithTrailingSlashShouldNotMatch() { - } - - @Configuration(proxyBeanMethods = false) - static class JerseyConfiguration { - - @Bean - TomcatServletWebServerFactory tomcat() { - return new TomcatServletWebServerFactory(0); - } - - @Bean - ServletRegistrationBean servletContainer(ResourceConfig resourceConfig) { - return new ServletRegistrationBean<>(new ServletContainer(resourceConfig), "/*"); - } - - @Bean - ResourceConfig resourceConfig(Environment environment, WebEndpointDiscoverer endpointDiscoverer, - EndpointMediaTypes endpointMediaTypes) { - ResourceConfig resourceConfig = new ResourceConfig(); - String endpointPath = environment.getProperty("endpointPath"); - Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( - new EndpointMapping(endpointPath), endpointDiscoverer.getEndpoints(), endpointMediaTypes, - new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath)); - resourceConfig.registerResources(new HashSet<>(resources)); - resourceConfig.register(JacksonFeature.class); - resourceConfig.register(new ObjectMapperContextResolver(new ObjectMapper()), ContextResolver.class); - return resourceConfig; - } - - } - - @Configuration(proxyBeanMethods = false) - static class AuthenticatedConfiguration { - - @Bean - Filter securityFilter() { - return new OncePerRequestFilter() { - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, - FilterChain filterChain) throws ServletException, IOException { - SecurityContext context = SecurityContextHolder.createEmptyContext(); - context.setAuthentication(new UsernamePasswordAuthenticationToken("Alice", "secret", - Arrays.asList(new SimpleGrantedAuthority("ROLE_ACTUATOR")))); - SecurityContextHolder.setContext(context); - try { - filterChain.doFilter(new SecurityContextHolderAwareRequestWrapper(request, "ROLE_"), response); - } - finally { - SecurityContextHolder.clearContext(); - } - } - - }; - } - - } - - private static final class ObjectMapperContextResolver implements ContextResolver { - - private final ObjectMapper objectMapper; - - private ObjectMapperContextResolver(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - } - - @Override - public ObjectMapper getContext(Class type) { - return this.objectMapper; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java deleted file mode 100644 index dd3405d9c508..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingIntegrationTests.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.reactive; - -import java.net.URI; -import java.time.Duration; -import java.util.Collections; -import java.util.Map; -import java.util.function.Consumer; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.endpoint.Access; -import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointDiscoverer; -import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier; -import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.server.adapter.WebHttpHandlerBuilder; -import org.springframework.web.util.DefaultUriBuilderFactory; - -/** - * Integration tests for {@link ControllerEndpointHandlerMapping}. - * - * @author Phillip Webb - * @author Stephane Nicoll - * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.3.5", forRemoval = true) -class ControllerEndpointHandlerMappingIntegrationTests { - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withUserConfiguration(EndpointConfiguration.class, ExampleWebFluxEndpoint.class); - - @Test - void getMapping() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() - .uri("/actuator/example/one") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) - .expectBody(String.class) - .isEqualTo("One"))); - } - - @Test - void getWithUnacceptableContentType() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() - .uri("/actuator/example/one") - .accept(MediaType.APPLICATION_JSON) - .exchange() - .expectStatus() - .isEqualTo(HttpStatus.NOT_ACCEPTABLE))); - } - - @Test - void postMapping() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.post() - .uri("/actuator/example/two") - .bodyValue(Collections.singletonMap("id", "test")) - .exchange() - .expectStatus() - .isCreated() - .expectHeader() - .valueEquals(HttpHeaders.LOCATION, "/example/test"))); - } - - @Test - void postMappingWithReadOnlyAccessRespondsWith404() { - this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") - .run(withWebTestClient((webTestClient) -> webTestClient.post() - .uri("/actuator/example/two") - .bodyValue(Collections.singletonMap("id", "test")) - .exchange() - .expectStatus() - .isNotFound())); - } - - @Test - void getToRequestMapping() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() - .uri("/actuator/example/three") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) - .expectBody(String.class) - .isEqualTo("Three"))); - } - - @Test - void getToRequestMappingWithReadOnlyAccess() { - this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") - .run(withWebTestClient((webTestClient) -> webTestClient.get() - .uri("/actuator/example/three") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) - .expectBody(String.class) - .isEqualTo("Three"))); - } - - @Test - void postToRequestMapping() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.post() - .uri("/actuator/example/three") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) - .expectBody(String.class) - .isEqualTo("Three"))); - } - - @Test - void postToRequestMappingWithReadOnlyAccessRespondsWith405() { - this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") - .run(withWebTestClient((webTestClient) -> webTestClient.post() - .uri("/actuator/example/three") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isEqualTo(HttpStatus.METHOD_NOT_ALLOWED))); - } - - private ContextConsumer withWebTestClient( - Consumer webClient) { - return (context) -> { - int port = ((AnnotationConfigReactiveWebServerApplicationContext) context.getSourceApplicationContext()) - .getWebServer() - .getPort(); - WebTestClient webTestClient = createWebTestClient(port); - webClient.accept(webTestClient); - }; - } - - private WebTestClient createWebTestClient(int port) { - DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://localhost:" + port); - uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE); - return WebTestClient.bindToServer() - .uriBuilderFactory(uriBuilderFactory) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - WebFluxAutoConfiguration.class }) - static class EndpointConfiguration { - - @Bean - NettyReactiveWebServerFactory netty() { - return new NettyReactiveWebServerFactory(0); - } - - @Bean - HttpHandler httpHandler(ApplicationContext applicationContext) { - return WebHttpHandlerBuilder.applicationContext(applicationContext).build(); - } - - @Bean - ControllerEndpointDiscoverer webEndpointDiscoverer(ApplicationContext applicationContext) { - return new ControllerEndpointDiscoverer(applicationContext, null, Collections.emptyList()); - } - - @Bean - ControllerEndpointHandlerMapping webEndpointHandlerMapping(ControllerEndpointsSupplier endpointsSupplier, - EndpointAccessResolver endpointAccessResolver) { - return new ControllerEndpointHandlerMapping(new EndpointMapping("actuator"), - endpointsSupplier.getEndpoints(), null, endpointAccessResolver); - } - - @Bean - EndpointAccessResolver endpointAccessResolver(Environment environment) { - return (id, defaultAccess) -> environment.getProperty("endpoint-access", Access.class, Access.UNRESTRICTED); - } - - } - - @RestControllerEndpoint(id = "example") - static class ExampleWebFluxEndpoint { - - @GetMapping(path = "one", produces = MediaType.TEXT_PLAIN_VALUE) - String one() { - return "One"; - } - - @PostMapping("/two") - ResponseEntity two(@RequestBody Map content) { - return ResponseEntity.created(URI.create("/example/" + content.get("id"))).build(); - } - - @RequestMapping(path = "/three", produces = MediaType.TEXT_PLAIN_VALUE) - String three() { - return "Three"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingTests.java deleted file mode 100644 index d6c12f1287e7..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMappingTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.reactive; - -import java.time.Duration; -import java.util.Arrays; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.endpoint.Access; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; -import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint; -import org.springframework.context.support.StaticApplicationContext; -import org.springframework.http.HttpMethod; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.web.server.MockServerWebExchange; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.server.MethodNotAllowedException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ControllerEndpointHandlerMapping}. - * - * @author Phillip Webb - * @author Stephane Nicoll - * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support - */ -@Deprecated(since = "3.3.5", forRemoval = true) -@SuppressWarnings("removal") -class ControllerEndpointHandlerMappingTests { - - private final StaticApplicationContext context = new StaticApplicationContext(); - - @Test - void mappingWithNoPrefix() { - ExposableControllerEndpoint first = firstEndpoint(); - ExposableControllerEndpoint second = secondEndpoint(); - ControllerEndpointHandlerMapping mapping = createMapping("", first, second); - assertThat(getHandler(mapping, HttpMethod.GET, "/first")).isEqualTo(handlerOf(first.getController(), "get")); - assertThat(getHandler(mapping, HttpMethod.POST, "/second")) - .isEqualTo(handlerOf(second.getController(), "save")); - assertThat(getHandler(mapping, HttpMethod.GET, "/third")).isNull(); - } - - @Test - void mappingWithPrefix() { - ExposableControllerEndpoint first = firstEndpoint(); - ExposableControllerEndpoint second = secondEndpoint(); - ControllerEndpointHandlerMapping mapping = createMapping("actuator", first, second); - assertThat(getHandler(mapping, HttpMethod.GET, "/actuator/first")) - .isEqualTo(handlerOf(first.getController(), "get")); - assertThat(getHandler(mapping, HttpMethod.POST, "/actuator/second")) - .isEqualTo(handlerOf(second.getController(), "save")); - assertThat(getHandler(mapping, HttpMethod.GET, "/first")).isNull(); - assertThat(getHandler(mapping, HttpMethod.GET, "/second")).isNull(); - } - - @Test - void mappingWithNoPath() { - ExposableControllerEndpoint pathless = pathlessEndpoint(); - ControllerEndpointHandlerMapping mapping = createMapping("actuator", pathless); - assertThat(getHandler(mapping, HttpMethod.GET, "/actuator/pathless")) - .isEqualTo(handlerOf(pathless.getController(), "get")); - assertThat(getHandler(mapping, HttpMethod.GET, "/pathless")).isNull(); - assertThat(getHandler(mapping, HttpMethod.GET, "/")).isNull(); - } - - @Test - void mappingNarrowedToMethod() { - ExposableControllerEndpoint first = firstEndpoint(); - ControllerEndpointHandlerMapping mapping = createMapping("actuator", first); - assertThatExceptionOfType(MethodNotAllowedException.class) - .isThrownBy(() -> getHandler(mapping, HttpMethod.POST, "/actuator/first")); - } - - private Object getHandler(ControllerEndpointHandlerMapping mapping, HttpMethod method, String requestURI) { - return mapping.getHandler(exchange(method, requestURI)).block(Duration.ofSeconds(30)); - } - - private ControllerEndpointHandlerMapping createMapping(String prefix, ExposableControllerEndpoint... endpoints) { - ControllerEndpointHandlerMapping mapping = new ControllerEndpointHandlerMapping(new EndpointMapping(prefix), - Arrays.asList(endpoints), null, (endpointId, defaultAccess) -> Access.UNRESTRICTED); - mapping.setApplicationContext(this.context); - mapping.afterPropertiesSet(); - return mapping; - } - - private HandlerMethod handlerOf(Object source, String methodName) { - return new HandlerMethod(source, ReflectionUtils.findMethod(source.getClass(), methodName)); - } - - private MockServerWebExchange exchange(HttpMethod method, String requestURI) { - return MockServerWebExchange.from(MockServerHttpRequest.method(method, requestURI).build()); - } - - private ExposableControllerEndpoint firstEndpoint() { - return mockEndpoint(EndpointId.of("first"), new FirstTestMvcEndpoint()); - } - - private ExposableControllerEndpoint secondEndpoint() { - return mockEndpoint(EndpointId.of("second"), new SecondTestMvcEndpoint()); - } - - private ExposableControllerEndpoint pathlessEndpoint() { - return mockEndpoint(EndpointId.of("pathless"), new PathlessControllerEndpoint()); - } - - private ExposableControllerEndpoint mockEndpoint(EndpointId id, Object controller) { - ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class); - given(endpoint.getEndpointId()).willReturn(id); - given(endpoint.getController()).willReturn(controller); - given(endpoint.getRootPath()).willReturn(id.toString()); - return endpoint; - } - - @ControllerEndpoint(id = "first") - static class FirstTestMvcEndpoint { - - @GetMapping("/") - String get() { - return "test"; - } - - } - - @ControllerEndpoint(id = "second") - static class SecondTestMvcEndpoint { - - @PostMapping("/") - void save() { - - } - - } - - @ControllerEndpoint(id = "pathless") - static class PathlessControllerEndpoint { - - @GetMapping - String get() { - return "test"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java deleted file mode 100644 index 512449fc6bae..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointIntegrationTests.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.reactive; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; -import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests; -import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.ReactiveSecurityContextHolder; -import org.springframework.util.StringUtils; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.reactive.config.EnableWebFlux; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.adapter.WebHttpHandlerBuilder; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for web endpoints exposed using WebFlux. - * - * @author Andy Wilkinson - * @see WebFluxEndpointHandlerMapping - */ -class WebFluxEndpointIntegrationTests - extends AbstractWebEndpointIntegrationTests { - - WebFluxEndpointIntegrationTests() { - super(WebFluxEndpointIntegrationTests::createApplicationContext, - WebFluxEndpointIntegrationTests::applyAuthenticatedConfiguration); - - } - - private static AnnotationConfigReactiveWebServerApplicationContext createApplicationContext() { - AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext(); - context.register(ReactiveConfiguration.class); - return context; - } - - private static void applyAuthenticatedConfiguration(AnnotationConfigReactiveWebServerApplicationContext context) { - context.register(AuthenticatedConfiguration.class); - } - - @Test - void responseToOptionsRequestIncludesCorsHeaders() { - load(TestEndpointConfiguration.class, - (client) -> client.options() - .uri("/test") - .accept(MediaType.APPLICATION_JSON) - .header("Access-Control-Request-Method", "POST") - .header("Origin", "https://example.com") - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .valueEquals("Access-Control-Allow-Origin", "https://example.com") - .expectHeader() - .valueEquals("Access-Control-Allow-Methods", "GET,POST")); - } - - @Test - void readOperationsThatReturnAResourceSupportRangeRequests() { - load(ResourceEndpointConfiguration.class, (client) -> { - byte[] responseBody = client.get() - .uri("/resource") - .header("Range", "bytes=0-3") - .exchange() - .expectStatus() - .isEqualTo(HttpStatus.PARTIAL_CONTENT) - .expectHeader() - .contentType(MediaType.APPLICATION_OCTET_STREAM) - .returnResult(byte[].class) - .getResponseBodyContent(); - assertThat(responseBody).containsExactly(0, 1, 2, 3); - }); - } - - @Override - protected int getPort(AnnotationConfigReactiveWebServerApplicationContext context) { - return context.getBean(ReactiveConfiguration.class).port; - } - - @Configuration(proxyBeanMethods = false) - @EnableWebFlux - @ImportAutoConfiguration(ErrorWebFluxAutoConfiguration.class) - static class ReactiveConfiguration { - - private int port; - - @Bean - NettyReactiveWebServerFactory netty() { - return new NettyReactiveWebServerFactory(0); - } - - @Bean - HttpHandler httpHandler(ApplicationContext applicationContext) { - return WebHttpHandlerBuilder.applicationContext(applicationContext).build(); - } - - @Bean - WebFluxEndpointHandlerMapping webEndpointHandlerMapping(Environment environment, - WebEndpointDiscoverer endpointDiscoverer, EndpointMediaTypes endpointMediaTypes) { - CorsConfiguration corsConfiguration = new CorsConfiguration(); - corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com")); - corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST")); - String endpointPath = environment.getProperty("endpointPath"); - return new WebFluxEndpointHandlerMapping(new EndpointMapping(endpointPath), - endpointDiscoverer.getEndpoints(), endpointMediaTypes, corsConfiguration, - new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath)); - } - - @Bean - ApplicationListener serverInitializedListener() { - return (event) -> this.port = event.getWebServer().getPort(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class AuthenticatedConfiguration { - - @Bean - WebFilter webFilter() { - return (exchange, chain) -> chain.filter(exchange) - .contextWrite(ReactiveSecurityContextHolder.withAuthentication(new UsernamePasswordAuthenticationToken( - "Alice", "secret", Arrays.asList(new SimpleGrantedAuthority("ROLE_ACTUATOR"))))); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingIntegrationTests.java deleted file mode 100644 index a45edbe39fc8..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingIntegrationTests.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.servlet; - -import java.net.URI; -import java.time.Duration; -import java.util.Collections; -import java.util.Map; -import java.util.function.Consumer; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.endpoint.Access; -import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointDiscoverer; -import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier; -import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.util.DefaultUriBuilderFactory; - -/** - * Integration tests for {@link ControllerEndpointHandlerMapping}. - * - * @author Phillip Webb - * @author Stephane Nicoll - * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support - */ -@Deprecated(since = "3.3.5", forRemoval = true) -@SuppressWarnings("removal") -class ControllerEndpointHandlerMappingIntegrationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withUserConfiguration(EndpointConfiguration.class, ExampleMvcEndpoint.class); - - @Test - void getMapping() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() - .uri("/actuator/example/one") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) - .expectBody(String.class) - .isEqualTo("One"))); - } - - @Test - void getWithUnacceptableContentType() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() - .uri("/actuator/example/one") - .accept(MediaType.APPLICATION_JSON) - .exchange() - .expectStatus() - .isEqualTo(HttpStatus.NOT_ACCEPTABLE))); - } - - @Test - void postMapping() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.post() - .uri("/actuator/example/two") - .bodyValue(Collections.singletonMap("id", "test")) - .exchange() - .expectStatus() - .isCreated() - .expectHeader() - .valueEquals(HttpHeaders.LOCATION, "/example/test"))); - } - - @Test - void postMappingWithReadOnlyAccessRespondsWith404() { - this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") - .run(withWebTestClient((webTestClient) -> webTestClient.post() - .uri("/actuator/example/two") - .bodyValue(Collections.singletonMap("id", "test")) - .exchange() - .expectStatus() - .isNotFound())); - } - - @Test - void getToRequestMapping() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.get() - .uri("/actuator/example/three") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) - .expectBody(String.class) - .isEqualTo("Three"))); - } - - @Test - void getToRequestMappingWithReadOnlyAccess() { - this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") - .run(withWebTestClient((webTestClient) -> webTestClient.get() - .uri("/actuator/example/three") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) - .expectBody(String.class) - .isEqualTo("Three"))); - } - - @Test - void postToRequestMapping() { - this.contextRunner.run(withWebTestClient((webTestClient) -> webTestClient.post() - .uri("/actuator/example/three") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isOk() - .expectHeader() - .contentTypeCompatibleWith(MediaType.TEXT_PLAIN) - .expectBody(String.class) - .isEqualTo("Three"))); - } - - @Test - void postToRequestMappingWithReadOnlyAccessRespondsWith405() { - this.contextRunner.withPropertyValues("endpoint-access=READ_ONLY") - .run(withWebTestClient((webTestClient) -> webTestClient.post() - .uri("/actuator/example/three") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isEqualTo(HttpStatus.METHOD_NOT_ALLOWED))); - } - - private ContextConsumer withWebTestClient(Consumer webClient) { - return (context) -> { - int port = ((AnnotationConfigServletWebServerApplicationContext) context.getSourceApplicationContext()) - .getWebServer() - .getPort(); - WebTestClient webTestClient = createWebTestClient(port); - webClient.accept(webTestClient); - }; - } - - private WebTestClient createWebTestClient(int port) { - DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://localhost:" + port); - uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE); - return WebTestClient.bindToServer() - .uriBuilderFactory(uriBuilderFactory) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class }) - static class EndpointConfiguration { - - @Bean - TomcatServletWebServerFactory tomcat() { - return new TomcatServletWebServerFactory(0); - } - - @Bean - ControllerEndpointDiscoverer webEndpointDiscoverer(ApplicationContext applicationContext) { - return new ControllerEndpointDiscoverer(applicationContext, null, Collections.emptyList()); - } - - @Bean - ControllerEndpointHandlerMapping webEndpointHandlerMapping(ControllerEndpointsSupplier endpointsSupplier, - EndpointAccessResolver endpointAccessResolver) { - return new ControllerEndpointHandlerMapping(new EndpointMapping("actuator"), - endpointsSupplier.getEndpoints(), null, endpointAccessResolver); - } - - @Bean - EndpointAccessResolver endpointAccessResolver(Environment environment) { - return (id, defaultAccess) -> environment.getProperty("endpoint-access", Access.class, Access.UNRESTRICTED); - } - - } - - @RestControllerEndpoint(id = "example") - static class ExampleMvcEndpoint { - - @GetMapping(path = "one", produces = MediaType.TEXT_PLAIN_VALUE) - String one() { - return "One"; - } - - @PostMapping("/two") - ResponseEntity two(@RequestBody Map content) { - return ResponseEntity.created(URI.create("/example/" + content.get("id"))).build(); - } - - @RequestMapping(path = "/three", produces = MediaType.TEXT_PLAIN_VALUE) - String three() { - return "Three"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingTests.java deleted file mode 100644 index 424c119a4053..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/ControllerEndpointHandlerMappingTests.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.servlet; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.endpoint.Access; -import org.springframework.boot.actuate.endpoint.EndpointId; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; -import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint; -import org.springframework.context.support.StaticApplicationContext; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.method.HandlerMethod; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ControllerEndpointHandlerMapping}. - * - * @author Phillip Webb - * @author Stephane Nicoll - * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support - */ -@Deprecated(since = "3.3.5", forRemoval = true) -@SuppressWarnings("removal") -class ControllerEndpointHandlerMappingTests { - - private final StaticApplicationContext context = new StaticApplicationContext(); - - @Test - void mappingWithNoPrefix() throws Exception { - ExposableControllerEndpoint first = firstEndpoint(); - ExposableControllerEndpoint second = secondEndpoint(); - ControllerEndpointHandlerMapping mapping = createMapping("", first, second); - assertThat(mapping.getHandler(request("GET", "/first")).getHandler()) - .isEqualTo(handlerOf(first.getController(), "get")); - assertThat(mapping.getHandler(request("POST", "/second")).getHandler()) - .isEqualTo(handlerOf(second.getController(), "save")); - assertThat(mapping.getHandler(request("GET", "/third"))).isNull(); - } - - @Test - void mappingWithPrefix() throws Exception { - ExposableControllerEndpoint first = firstEndpoint(); - ExposableControllerEndpoint second = secondEndpoint(); - ControllerEndpointHandlerMapping mapping = createMapping("actuator", first, second); - assertThat(mapping.getHandler(request("GET", "/actuator/first")).getHandler()) - .isEqualTo(handlerOf(first.getController(), "get")); - assertThat(mapping.getHandler(request("POST", "/actuator/second")).getHandler()) - .isEqualTo(handlerOf(second.getController(), "save")); - assertThat(mapping.getHandler(request("GET", "/first"))).isNull(); - assertThat(mapping.getHandler(request("GET", "/second"))).isNull(); - } - - @Test - void mappingNarrowedToMethod() { - ExposableControllerEndpoint first = firstEndpoint(); - ControllerEndpointHandlerMapping mapping = createMapping("actuator", first); - assertThatExceptionOfType(HttpRequestMethodNotSupportedException.class) - .isThrownBy(() -> mapping.getHandler(request("POST", "/actuator/first"))); - } - - @Test - void mappingWithNoPath() throws Exception { - ExposableControllerEndpoint pathless = pathlessEndpoint(); - ControllerEndpointHandlerMapping mapping = createMapping("actuator", pathless); - assertThat(mapping.getHandler(request("GET", "/actuator/pathless")).getHandler()) - .isEqualTo(handlerOf(pathless.getController(), "get")); - assertThat(mapping.getHandler(request("GET", "/pathless"))).isNull(); - assertThat(mapping.getHandler(request("GET", "/"))).isNull(); - } - - private ControllerEndpointHandlerMapping createMapping(String prefix, ExposableControllerEndpoint... endpoints) { - ControllerEndpointHandlerMapping mapping = new ControllerEndpointHandlerMapping(new EndpointMapping(prefix), - Arrays.asList(endpoints), null, (endpointId, defaultAccess) -> Access.UNRESTRICTED); - mapping.setApplicationContext(this.context); - mapping.afterPropertiesSet(); - return mapping; - } - - private HandlerMethod handlerOf(Object source, String methodName) { - return new HandlerMethod(source, ReflectionUtils.findMethod(source.getClass(), methodName)); - } - - private MockHttpServletRequest request(String method, String requestURI) { - return new MockHttpServletRequest(method, requestURI); - } - - private ExposableControllerEndpoint firstEndpoint() { - return mockEndpoint(EndpointId.of("first"), new FirstTestMvcEndpoint()); - } - - private ExposableControllerEndpoint secondEndpoint() { - return mockEndpoint(EndpointId.of("second"), new SecondTestMvcEndpoint()); - } - - private ExposableControllerEndpoint pathlessEndpoint() { - return mockEndpoint(EndpointId.of("pathless"), new PathlessControllerEndpoint()); - } - - private ExposableControllerEndpoint mockEndpoint(EndpointId id, Object controller) { - ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class); - given(endpoint.getEndpointId()).willReturn(id); - given(endpoint.getController()).willReturn(controller); - given(endpoint.getRootPath()).willReturn(id.toString()); - return endpoint; - } - - @ControllerEndpoint(id = "first") - static class FirstTestMvcEndpoint { - - @GetMapping("/") - String get() { - return "test"; - } - - } - - @ControllerEndpoint(id = "second") - static class SecondTestMvcEndpoint { - - @PostMapping("/") - void save() { - - } - - } - - @ControllerEndpoint(id = "pathless") - static class PathlessControllerEndpoint { - - @GetMapping - String get() { - return "test"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/PortHolder.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/PortHolder.java deleted file mode 100644 index b0f14241b563..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/PortHolder.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.test; - -public class PortHolder { - - private int port; - - int getPort() { - return this.port; - } - - void setPort(int port) { - this.port = port; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java deleted file mode 100644 index eefa77101a6f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.test; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.model.Resource; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.Extension; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.ParameterContext; -import org.junit.jupiter.api.extension.ParameterResolver; -import org.junit.jupiter.api.extension.TestTemplateInvocationContext; -import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; -import org.junit.platform.commons.util.AnnotationUtils; - -import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; -import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; -import org.springframework.boot.actuate.endpoint.web.EndpointMapping; -import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; -import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; -import org.springframework.boot.actuate.endpoint.web.jersey.JerseyEndpointResourceFactory; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; -import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration; -import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigRegistry; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; -import org.springframework.http.HttpMethod; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.util.ClassUtils; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.server.adapter.WebHttpHandlerBuilder; -import org.springframework.web.util.DefaultUriBuilderFactory; -import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode; - -/** - * {@link TestTemplateInvocationContextProvider} for - * {@link WebEndpointTest @WebEndpointTest}. - * - * @author Andy Wilkinson - */ -class WebEndpointTestInvocationContextProvider implements TestTemplateInvocationContextProvider { - - @Override - public boolean supportsTestTemplate(ExtensionContext context) { - return true; - } - - @Override - public Stream provideTestTemplateInvocationContexts( - ExtensionContext extensionContext) { - WebEndpointTest webEndpointTest = AnnotationUtils - .findAnnotation(extensionContext.getRequiredTestMethod(), WebEndpointTest.class) - .orElseThrow(() -> new IllegalStateException("Unable to find WebEndpointTest annotation on %s" - .formatted(extensionContext.getRequiredTestMethod()))); - return Stream.of(webEndpointTest.infrastructure()).distinct().map(Infrastructure::createInvocationContext); - } - - static ConfigurableApplicationContext createJerseyContext(List> classes) { - AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); - classes.add(JerseyEndpointConfiguration.class); - context.register(ClassUtils.toClassArray(classes)); - context.refresh(); - return context; - } - - static ConfigurableApplicationContext createWebMvcContext(List> classes) { - AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); - classes.add(WebMvcEndpointConfiguration.class); - context.register(ClassUtils.toClassArray(classes)); - context.refresh(); - return context; - } - - static ConfigurableApplicationContext createWebFluxContext(List> classes) { - AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext(); - classes.add(WebFluxEndpointConfiguration.class); - context.register(ClassUtils.toClassArray(classes)); - context.refresh(); - return context; - } - - static class WebEndpointsInvocationContext - implements TestTemplateInvocationContext, BeforeEachCallback, AfterEachCallback, ParameterResolver { - - private static final Duration TIMEOUT = Duration.ofMinutes(5); - - private final String name; - - private final Function>, ConfigurableApplicationContext> contextFactory; - - private ConfigurableApplicationContext context; - - WebEndpointsInvocationContext(String name, - Function>, ConfigurableApplicationContext> contextFactory) { - this.name = name; - this.contextFactory = contextFactory; - } - - @Override - public void beforeEach(ExtensionContext extensionContext) throws Exception { - List> configurationClasses = Stream - .of(extensionContext.getRequiredTestClass().getDeclaredClasses()) - .filter(this::isConfiguration) - .collect(Collectors.toCollection(ArrayList::new)); - this.context = this.contextFactory.apply(configurationClasses); - } - - private boolean isConfiguration(Class candidate) { - return MergedAnnotations.from(candidate, SearchStrategy.TYPE_HIERARCHY).isPresent(Configuration.class); - } - - @Override - public void afterEach(ExtensionContext context) throws Exception { - if (this.context != null) { - this.context.close(); - } - } - - @Override - public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { - Class type = parameterContext.getParameter().getType(); - return type.equals(WebTestClient.class) || type.isAssignableFrom(ConfigurableApplicationContext.class); - } - - @Override - public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { - Class type = parameterContext.getParameter().getType(); - if (type.equals(WebTestClient.class)) { - return createWebTestClient(); - } - else { - return this.context; - } - } - - @Override - public List getAdditionalExtensions() { - return Collections.singletonList(this); - } - - @Override - public String getDisplayName(int invocationIndex) { - return this.name; - } - - private WebTestClient createWebTestClient() { - DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory( - "http://localhost:" + determinePort()); - uriBuilderFactory.setEncodingMode(EncodingMode.NONE); - return WebTestClient.bindToServer() - .uriBuilderFactory(uriBuilderFactory) - .responseTimeout(TIMEOUT) - .codecs((codecs) -> codecs.defaultCodecs().maxInMemorySize(-1)) - .filter((request, next) -> { - if (HttpMethod.GET == request.method()) { - return next.exchange(request).retry(10); - } - return next.exchange(request); - }) - .build(); - } - - private int determinePort() { - if (this.context instanceof AnnotationConfigServletWebServerApplicationContext webServerContext) { - return webServerContext.getWebServer().getPort(); - } - return this.context.getBean(PortHolder.class).getPort(); - } - - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, JerseyAutoConfiguration.class }) - static class JerseyEndpointConfiguration { - - private final ApplicationContext applicationContext; - - JerseyEndpointConfiguration(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } - - @Bean - TomcatServletWebServerFactory tomcat() { - return new TomcatServletWebServerFactory(0); - } - - @Bean - ResourceConfig resourceConfig() { - return new ResourceConfig(); - } - - @Bean - ResourceConfigCustomizer webEndpointRegistrar() { - return this::customize; - } - - private void customize(ResourceConfig config) { - EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; - WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, - new ConversionServiceParameterValueMapper(), endpointMediaTypes, null, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( - new EndpointMapping("/actuator"), discoverer.getEndpoints(), endpointMediaTypes, - new EndpointLinksResolver(discoverer.getEndpoints()), true); - config.registerResources(new HashSet<>(resources)); - } - - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, WebFluxAutoConfiguration.class }) - static class WebFluxEndpointConfiguration implements ApplicationListener { - - private final ApplicationContext applicationContext; - - private final PortHolder portHolder = new PortHolder(); - - WebFluxEndpointConfiguration(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } - - @Bean - NettyReactiveWebServerFactory netty() { - return new NettyReactiveWebServerFactory(0); - } - - @Bean - PortHolder portHolder() { - return this.portHolder; - } - - @Override - public void onApplicationEvent(WebServerInitializedEvent event) { - this.portHolder.setPort(event.getWebServer().getPort()); - } - - @Bean - HttpHandler httpHandler(ApplicationContext applicationContext) { - return WebHttpHandlerBuilder.applicationContext(applicationContext).build(); - } - - @Bean - WebFluxEndpointHandlerMapping webEndpointReactiveHandlerMapping() { - EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; - WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, - new ConversionServiceParameterValueMapper(), endpointMediaTypes, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - return new WebFluxEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), - endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), - true); - } - - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class }) - static class WebMvcEndpointConfiguration { - - private final ApplicationContext applicationContext; - - WebMvcEndpointConfiguration(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } - - @Bean - TomcatServletWebServerFactory tomcat() { - return new TomcatServletWebServerFactory(0); - } - - @Bean - WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping() { - EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; - WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, - new ConversionServiceParameterValueMapper(), endpointMediaTypes, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - return new WebMvcEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), - endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), - true); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthTests.java deleted file mode 100644 index b88046914360..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.endpoint.ApiVersion; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Test for {@link CompositeHealth}. - * - * @author Phillip Webb - */ -class CompositeHealthTests { - - @Test - void createWhenStatusIsNullThrowsException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new CompositeHealth(ApiVersion.V3, null, Collections.emptyMap())) - .withMessage("'status' must not be null"); - } - - @Test - void getStatusReturnsStatus() { - CompositeHealth health = new CompositeHealth(ApiVersion.V3, Status.UP, Collections.emptyMap()); - assertThat(health.getStatus()).isEqualTo(Status.UP); - } - - @Test - void getComponentReturnsComponents() { - Map components = new LinkedHashMap<>(); - components.put("a", Health.up().build()); - CompositeHealth health = new CompositeHealth(ApiVersion.V3, Status.UP, components); - assertThat(health.getComponents()).isEqualTo(components); - } - - @Test - void serializeV3WithJacksonReturnsValidJson() throws Exception { - Map components = new LinkedHashMap<>(); - components.put("db1", Health.up().build()); - components.put("db2", Health.down().withDetail("a", "b").build()); - CompositeHealth health = new CompositeHealth(ApiVersion.V3, Status.UP, components); - ObjectMapper mapper = new ObjectMapper(); - String json = mapper.writeValueAsString(health); - assertThat(json).isEqualTo("{\"status\":\"UP\",\"components\":{\"db1\":{\"status\":\"UP\"}," - + "\"db2\":{\"status\":\"DOWN\",\"details\":{\"a\":\"b\"}}}}"); - } - - @Test - void serializeV2WithJacksonReturnsValidJson() throws Exception { - Map components = new LinkedHashMap<>(); - components.put("db1", Health.up().build()); - components.put("db2", Health.down().withDetail("a", "b").build()); - CompositeHealth health = new CompositeHealth(ApiVersion.V2, Status.UP, components); - ObjectMapper mapper = new ObjectMapper(); - String json = mapper.writeValueAsString(health); - assertThat(json).isEqualTo("{\"status\":\"UP\",\"details\":{\"db1\":{\"status\":\"UP\"}," - + "\"db2\":{\"status\":\"DOWN\",\"details\":{\"a\":\"b\"}}}}"); - } - - @Test // gh-26797 - void serializeV2WithJacksonAndDisabledCanOverrideAccessModifiersReturnsValidJson() throws Exception { - Map components = new LinkedHashMap<>(); - components.put("db1", Health.up().build()); - components.put("db2", Health.down().withDetail("a", "b").build()); - CompositeHealth health = new CompositeHealth(ApiVersion.V2, Status.UP, components); - JsonMapper mapper = JsonMapper.builder().disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS).build(); - String json = mapper.writeValueAsString(health); - assertThat(json).isEqualTo("{\"status\":\"UP\",\"details\":{\"db1\":{\"status\":\"UP\"}," - + "\"db2\":{\"status\":\"DOWN\",\"details\":{\"a\":\"b\"}}}}"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributorTests.java deleted file mode 100644 index ba770391ec8f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeReactiveHealthContributorTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link CompositeReactiveHealthContributor}. - * - * @author Phillip Webb - */ -class CompositeReactiveHealthContributorTests { - - @Test - void fromMapReturnsCompositeReactiveHealthContributorMapAdapter() { - Map map = new LinkedHashMap<>(); - ReactiveHealthIndicator indicator = () -> Mono.just(Health.down().build()); - map.put("test", indicator); - CompositeReactiveHealthContributor composite = CompositeReactiveHealthContributor.fromMap(map); - assertThat(composite).isInstanceOf(CompositeReactiveHealthContributorMapAdapter.class); - NamedContributor namedContributor = composite.iterator().next(); - assertThat(namedContributor.getName()).isEqualTo("test"); - assertThat(namedContributor.getContributor()).isSameAs(indicator); - } - - @Test - void fromMapWithAdapterReturnsCompositeReactiveHealthContributorMapAdapter() { - Map map = new LinkedHashMap<>(); - ReactiveHealthIndicator downIndicator = () -> Mono.just(Health.down().build()); - ReactiveHealthIndicator upIndicator = () -> Mono.just(Health.up().build()); - map.put("test", downIndicator); - CompositeReactiveHealthContributor composite = CompositeReactiveHealthContributor.fromMap(map, - (value) -> upIndicator); - assertThat(composite).isInstanceOf(CompositeReactiveHealthContributorMapAdapter.class); - NamedContributor namedContributor = composite.iterator().next(); - assertThat(namedContributor.getName()).isEqualTo("test"); - assertThat(namedContributor.getContributor()).isSameAs(upIndicator); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/DefaultContributorRegistryTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/DefaultContributorRegistryTests.java deleted file mode 100644 index 59a373915b59..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/DefaultContributorRegistryTests.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Collections; -import java.util.Iterator; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link DefaultContributorRegistry}. - * - * @author Phillip Webb - * @author Vedran Pavic - * @author Stephane Nicoll - */ -abstract class DefaultContributorRegistryTests { - - private final HealthIndicator one = mock(HealthIndicator.class); - - private final HealthIndicator two = mock(HealthIndicator.class); - - private ContributorRegistry registry; - - @BeforeEach - void setUp() { - given(this.one.health()).willReturn(new Health.Builder().unknown().withDetail("1", "1").build()); - given(this.two.health()).willReturn(new Health.Builder().unknown().withDetail("2", "2").build()); - this.registry = new DefaultContributorRegistry<>(); - } - - @Test - void createWhenContributorsIsNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> new DefaultContributorRegistry<>(null)) - .withMessage("Contributors must not be null"); - } - - @Test - void createWhenNameFactoryIsNullThrowsException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new DefaultContributorRegistry<>(Collections.emptyMap(), null)) - .withMessage("NameFactory must not be null"); - } - - @Test - void createUsesHealthIndicatorNameFactoryByDefault() { - this.registry = new DefaultContributorRegistry<>(Collections.singletonMap("oneHealthIndicator", this.one)); - assertThat(this.registry.getContributor("oneHealthIndicator")).isNull(); - assertThat(this.registry.getContributor("one")).isNotNull(); - } - - @Test - void createWithCustomNameFactoryAppliesFunctionToName() { - this.registry = new DefaultContributorRegistry<>(Collections.singletonMap("one", this.one), this::reverse); - assertThat(this.registry.getContributor("one")).isNull(); - assertThat(this.registry.getContributor("eno")).isNotNull(); - } - - @Test - void registerContributorWhenNameIsNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> this.registry.registerContributor(null, this.one)) - .withMessage("Name must not be null"); - } - - @Test - void registerContributorWhenContributorIsNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> this.registry.registerContributor("one", null)) - .withMessage("Contributor must not be null"); - } - - @Test - void registerContributorRegistersContributors() { - this.registry.registerContributor("one", this.one); - this.registry.registerContributor("two", this.two); - assertThat(this.registry).hasSize(2); - assertThat(this.registry.getContributor("one")).isSameAs(this.one); - assertThat(this.registry.getContributor("two")).isSameAs(this.two); - } - - @Test - void registerContributorWhenNameAlreadyUsedThrowsException() { - this.registry.registerContributor("one", this.one); - assertThatIllegalStateException().isThrownBy(() -> this.registry.registerContributor("one", this.two)) - .withMessageContaining("A contributor named \"one\" has already been registered"); - } - - @Test - void registerContributorUsesNameFactory() { - this.registry.registerContributor("oneHealthIndicator", this.one); - assertThat(this.registry.getContributor("oneHealthIndicator")).isNull(); - assertThat(this.registry.getContributor("one")).isNotNull(); - } - - @Test - void unregisterContributorUnregistersContributor() { - this.registry.registerContributor("one", this.one); - this.registry.registerContributor("two", this.two); - assertThat(this.registry).hasSize(2); - HealthIndicator two = this.registry.unregisterContributor("two"); - assertThat(two).isSameAs(this.two); - assertThat(this.registry).hasSize(1); - } - - @Test - void unregisterContributorWhenUnknownReturnsNull() { - this.registry.registerContributor("one", this.one); - assertThat(this.registry).hasSize(1); - HealthIndicator two = this.registry.unregisterContributor("two"); - assertThat(two).isNull(); - assertThat(this.registry).hasSize(1); - } - - @Test - void unregisterContributorUsesNameFactory() { - this.registry.registerContributor("oneHealthIndicator", this.one); - assertThat(this.registry.getContributor("oneHealthIndicator")).isNull(); - assertThat(this.registry.getContributor("one")).isNotNull(); - } - - @Test - void getContributorReturnsContributor() { - this.registry.registerContributor("one", this.one); - assertThat(this.registry.getContributor("one")).isEqualTo(this.one); - } - - @Test - void iteratorIteratesContributors() { - this.registry.registerContributor("one", this.one); - this.registry.registerContributor("two", this.two); - Iterator> iterator = this.registry.iterator(); - NamedContributor first = iterator.next(); - NamedContributor second = iterator.next(); - assertThat(iterator.hasNext()).isFalse(); - assertThat(first.getName()).isEqualTo("one"); - assertThat(first.getContributor()).isEqualTo(this.one); - assertThat(second.getName()).isEqualTo("two"); - assertThat(second.getContributor()).isEqualTo(this.two); - } - - private String reverse(String name) { - return new StringBuilder(name).reverse().toString(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthContributorNameFactoryTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthContributorNameFactoryTests.java deleted file mode 100644 index d94a6ecc6b45..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthContributorNameFactoryTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HealthContributorNameFactory}. - * - * @author Phillip Webb - */ -class HealthContributorNameFactoryTests { - - @Test - void applyWhenNameDoesNotEndWithSuffixReturnsName() { - assertThat(HealthContributorNameFactory.INSTANCE.apply("test")).isEqualTo("test"); - } - - @Test - void applyWhenNameEndsWithSuffixReturnsNewName() { - assertThat(HealthContributorNameFactory.INSTANCE.apply("testHealthIndicator")).isEqualTo("test"); - assertThat(HealthContributorNameFactory.INSTANCE.apply("testHealthContributor")).isEqualTo("test"); - } - - @Test - void applyWhenNameEndsWithSuffixInDifferentReturnsNewName() { - assertThat(HealthContributorNameFactory.INSTANCE.apply("testHEALTHindicator")).isEqualTo("test"); - assertThat(HealthContributorNameFactory.INSTANCE.apply("testHEALTHcontributor")).isEqualTo("test"); - } - - @Test - void applyWhenNameContainsSuffixReturnsName() { - assertThat(HealthContributorNameFactory.INSTANCE.apply("testHealthIndicatorTest")) - .isEqualTo("testHealthIndicatorTest"); - assertThat(HealthContributorNameFactory.INSTANCE.apply("testHealthContributorTest")) - .isEqualTo("testHealthContributorTest"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointSupportTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointSupportTests.java index 800d8dccb98f..fd12864f03eb 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointSupportTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointSupportTests.java @@ -28,23 +28,24 @@ import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.actuate.health.HealthEndpointSupport.HealthResult; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; /** * Base class for {@link HealthEndpointSupport} tests. * - * @param the support type - * @param the registry type + * @param the endpoint support type + * @param the repository type * @param the contributor type * @param the contributed health component type * @author Phillip Webb * @author Madhura Bhave */ -abstract class HealthEndpointSupportTests, R extends ContributorRegistry, C, T> { - - final R registry; +abstract class HealthEndpointSupportTests, R, C, T> { final Health up = Health.up().withDetail("spring", "boot").build(); @@ -54,30 +55,13 @@ abstract class HealthEndpointSupportTests, final TestHealthEndpointGroup allTheAs = new TestHealthEndpointGroup((name) -> name.startsWith("a")); - final HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, - Collections.singletonMap("alltheas", this.allTheAs)); - - HealthEndpointSupportTests() { - this.registry = createRegistry(); - } - - @Test - void createWhenRegistryIsNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> create(null, this.groups)) - .withMessage("'registry' must not be null"); - } - - @Test - void createWhenGroupsIsNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> create(this.registry, null)) - .withMessage("'groups' must not be null"); - } + final HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, Map.of("alltheas", this.allTheAs)); @Test void getHealthWhenPathIsEmptyUsesPrimaryGroup() { - this.registry.registerContributor("test", createContributor(this.up)); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false); + R registry = createRegistry("test", createContributor(this.up)); + E support = create(registry, this.groups); + HealthResult result = support.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false); assertThat(result.getGroup()).isEqualTo(this.primaryGroup); assertThat(getHealth(result)).isNotSameAs(this.up); assertThat(getHealth(result).getStatus()).isEqualTo(Status.UP); @@ -85,19 +69,19 @@ void getHealthWhenPathIsEmptyUsesPrimaryGroup() { @Test void getHealthWhenPathIsNotGroupReturnsResultFromPrimaryGroup() { - this.registry.registerContributor("test", createContributor(this.up)); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "test"); + R registry = createRegistry("test", createContributor(this.up)); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "test"); assertThat(result.getGroup()).isEqualTo(this.primaryGroup); assertThat(getHealth(result)).isEqualTo(this.up); - } @Test void getHealthWhenPathIsGroupReturnsResultFromGroup() { - this.registry.registerContributor("atest", createContributor(this.up)); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "alltheas", "atest"); + R registry = createRegistry("atest", createContributor(this.up)); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "alltheas", + "atest"); assertThat(result.getGroup()).isEqualTo(this.allTheAs); assertThat(getHealth(result)).isEqualTo(this.up); } @@ -105,10 +89,10 @@ void getHealthWhenPathIsGroupReturnsResultFromGroup() { @Test void getHealthWhenAlwaysShowIsFalseAndGroupIsTrueShowsComponents() { C contributor = createContributor(this.up); - C compositeContributor = createCompositeContributor(Collections.singletonMap("spring", contributor)); - this.registry.registerContributor("test", compositeContributor); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "test"); + C compositeContributor = createCompositeContributor(Map.of("spring", contributor)); + R registry = createRegistry("test", compositeContributor); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "test"); CompositeHealth health = (CompositeHealth) getHealth(result); assertThat(health.getComponents()).containsKey("spring"); } @@ -117,9 +101,9 @@ void getHealthWhenAlwaysShowIsFalseAndGroupIsTrueShowsComponents() { void getHealthWhenAlwaysShowIsFalseAndGroupIsFalseCannotAccessComponent() { this.primaryGroup.setShowComponents(false); C contributor = createContributor(this.up); - C compositeContributor = createCompositeContributor(Collections.singletonMap("spring", contributor)); - this.registry.registerContributor("test", compositeContributor); - HealthEndpointSupport endpoint = create(this.registry, this.groups); + C compositeContributor = createCompositeContributor(Map.of("spring", contributor)); + R registry = createRegistry("test", compositeContributor); + HealthEndpointSupport endpoint = create(registry, this.groups); HealthResult rootResult = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false); assertThat(((CompositeHealth) getHealth(rootResult)).getComponents()).isNullOrEmpty(); HealthResult componentResult = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "test"); @@ -130,9 +114,9 @@ void getHealthWhenAlwaysShowIsFalseAndGroupIsFalseCannotAccessComponent() { void getHealthWhenAlwaysShowIsTrueShowsComponents() { this.primaryGroup.setShowComponents(true); C contributor = createContributor(this.up); - C compositeContributor = createCompositeContributor(Collections.singletonMap("spring", contributor)); - this.registry.registerContributor("test", compositeContributor); - HealthEndpointSupport endpoint = create(this.registry, this.groups); + C compositeContributor = createCompositeContributor(Map.of("spring", contributor)); + R registry = createRegistry("test", compositeContributor); + HealthEndpointSupport endpoint = create(registry, this.groups); HealthResult rootResult = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false); assertThat(((CompositeHealth) getHealth(rootResult)).getComponents()).containsKey("test"); HealthResult componentResult = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "test"); @@ -141,17 +125,17 @@ void getHealthWhenAlwaysShowIsTrueShowsComponents() { @Test void getHealthWhenAlwaysShowIsFalseAndGroupIsTrueShowsDetails() { - this.registry.registerContributor("test", createContributor(this.up)); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "test"); + R registry = createRegistry("test", createContributor(this.up)); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "test"); assertThat(((Health) getHealth(result)).getDetails()).containsEntry("spring", "boot"); } @Test void getHealthWhenAlwaysShowIsFalseAndGroupIsFalseShowsNoDetails() { this.primaryGroup.setShowDetails(false); - this.registry.registerContributor("test", createContributor(this.up)); - HealthEndpointSupport endpoint = create(this.registry, this.groups); + R registry = createRegistry("test", createContributor(this.up)); + HealthEndpointSupport endpoint = create(registry, this.groups); HealthResult rootResult = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false); HealthResult componentResult = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "test"); assertThat(((CompositeHealth) getHealth(rootResult)).getStatus()).isEqualTo(Status.UP); @@ -161,9 +145,9 @@ void getHealthWhenAlwaysShowIsFalseAndGroupIsFalseShowsNoDetails() { @Test void getHealthWhenAlwaysShowIsTrueShowsDetails() { this.primaryGroup.setShowDetails(false); - this.registry.registerContributor("test", createContributor(this.up)); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - true, "test"); + R registry = createRegistry("test", createContributor(this.up)); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, true, "test"); assertThat(((Health) getHealth(result)).getDetails()).containsEntry("spring", "boot"); } @@ -172,9 +156,9 @@ void getHealthWhenCompositeReturnsAggregateResult() { Map contributors = new LinkedHashMap<>(); contributors.put("a", createContributor(this.up)); contributors.put("b", createContributor(this.down)); - this.registry.registerContributor("test", createCompositeContributor(contributors)); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false); + R registry = createRegistry("test", createCompositeContributor(contributors)); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false); CompositeHealth root = (CompositeHealth) getHealth(result); CompositeHealth component = (CompositeHealth) root.getComponents().get("test"); assertThat(root.getStatus()).isEqualTo(Status.DOWN); @@ -184,45 +168,46 @@ void getHealthWhenCompositeReturnsAggregateResult() { @Test void getHealthWhenPathDoesNotExistReturnsNull() { - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, + R registry = createRegistry("test", createCompositeContributor(Collections.emptyMap())); + HealthResult result = create(registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "missing"); assertThat(result).isNull(); } @Test void getHealthWhenPathIsEmptyIncludesGroups() { - this.registry.registerContributor("test", createContributor(this.up)); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false); + R registry = createRegistry("test", createContributor(this.up)); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false); assertThat(((SystemHealth) getHealth(result)).getGroups()).containsOnly("alltheas"); } @Test void getHealthWhenPathIsGroupDoesNotIncludesGroups() { - this.registry.registerContributor("atest", createContributor(this.up)); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "alltheas"); - assertThat(getHealth(result)).isNotInstanceOf(SystemHealth.class); + R registry = createRegistry("atest", createContributor(this.up)); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "alltheas"); + SystemHealth systemHealth = (SystemHealth) getHealth(result); + assertThat(systemHealth.getGroups()).isNull(); } @Test void getHealthWithEmptyCompositeReturnsNullResult() { // gh-18687 - this.registry.registerContributor("test", createCompositeContributor(Collections.emptyMap())); - HealthResult result = create(this.registry, this.groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false); + R registry = createRegistry("test", createCompositeContributor(Collections.emptyMap())); + E endpoint = create(registry, this.groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false); assertThat(result).isNull(); } @Test void getHealthWhenGroupContainsCompositeContributorReturnsHealth() { C contributor = createContributor(this.up); - C compositeContributor = createCompositeContributor(Collections.singletonMap("spring", contributor)); - this.registry.registerContributor("test", compositeContributor); + C compositeContributor = createCompositeContributor(Map.of("spring", contributor)); + R registry = createRegistry("test", compositeContributor); TestHealthEndpointGroup testGroup = new TestHealthEndpointGroup((name) -> name.startsWith("test")); - HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, - Collections.singletonMap("testGroup", testGroup)); - HealthResult result = create(this.registry, groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "testGroup"); + HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, Map.of("testGroup", testGroup)); + E endpoint = create(registry, groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "testGroup"); CompositeHealth health = (CompositeHealth) getHealth(result); assertThat(health.getComponents()).containsKey("test"); } @@ -253,13 +238,13 @@ void getHealthForPathWhenGroupContainsComponentOfCompositeContributorReturnsHeal contributors.put("spring-1", createNestedHealthContributor("spring-1")); contributors.put("spring-2", createNestedHealthContributor("spring-2")); C compositeContributor = createCompositeContributor(contributors); - this.registry.registerContributor("test", compositeContributor); + R registry = createRegistry("test", compositeContributor); TestHealthEndpointGroup testGroup = new TestHealthEndpointGroup( (name) -> name.startsWith("test") && !name.equals("test/spring-1/b")); - HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, - Collections.singletonMap("testGroup", testGroup)); - HealthResult result = create(this.registry, groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "testGroup", "test"); + HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, Map.of("testGroup", testGroup)); + E endpoint = create(registry, groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "testGroup", + "test"); CompositeHealth health = (CompositeHealth) getHealth(result); assertThat(health.getComponents()).containsKey("spring-1"); assertThat(health.getComponents()).containsKey("spring-2"); @@ -279,13 +264,13 @@ void getHealthForComponentPathWhenNotPartOfGroup() { contributors.put("spring-1", createNestedHealthContributor("spring-1")); contributors.put("spring-2", createNestedHealthContributor("spring-2")); C compositeContributor = createCompositeContributor(contributors); - this.registry.registerContributor("test", compositeContributor); + R registry = createRegistry("test", compositeContributor); TestHealthEndpointGroup testGroup = new TestHealthEndpointGroup( (name) -> name.startsWith("test") && !name.equals("test/spring-1/b")); - HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, - Collections.singletonMap("testGroup", testGroup)); - HealthResult result = create(this.registry, groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "testGroup", "test", "spring-1", "b"); + HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, Map.of("testGroup", testGroup)); + E endpoint = create(registry, groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "testGroup", + "test", "spring-1", "b"); assertThat(result).isNull(); } @@ -296,12 +281,11 @@ private CompositeHealth getCompositeHealth(Predicate memberPredicate) { contributors.put("spring-1", contributor1); contributors.put("spring-2", contributor2); C compositeContributor = createCompositeContributor(contributors); - this.registry.registerContributor("test", compositeContributor); + R registry = createRegistry("test", compositeContributor); TestHealthEndpointGroup testGroup = new TestHealthEndpointGroup(memberPredicate); - HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, - Collections.singletonMap("testGroup", testGroup)); - HealthResult result = create(this.registry, groups).getHealth(ApiVersion.V3, null, SecurityContext.NONE, - false, "testGroup"); + HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, Map.of("testGroup", testGroup)); + E endpoint = create(registry, groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, null, SecurityContext.NONE, false, "testGroup"); return (CompositeHealth) getHealth(result); } @@ -315,27 +299,27 @@ private C createNestedHealthContributor(String name) { @Test void getHealthWhenGroupHasAdditionalPath() { - this.registry.registerContributor("test", createContributor(this.up)); + R registry = createRegistry("test", createContributor(this.up)); TestHealthEndpointGroup testGroup = new TestHealthEndpointGroup((name) -> name.startsWith("test")); testGroup.setAdditionalPath(AdditionalHealthEndpointPath.from("server:/healthz")); - HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, - Collections.singletonMap("testGroup", testGroup)); - HealthResult result = create(this.registry, groups).getHealth(ApiVersion.V3, WebServerNamespace.SERVER, - SecurityContext.NONE, false, "healthz"); + HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, Map.of("testGroup", testGroup)); + E endpoint = create(registry, groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, WebServerNamespace.SERVER, SecurityContext.NONE, + false, "healthz"); CompositeHealth health = (CompositeHealth) getHealth(result); assertThat(health.getComponents()).containsKey("test"); } @Test void getHealthWhenGroupHasAdditionalPathAndShowComponentsFalse() { - this.registry.registerContributor("test", createContributor(this.up)); + R registry = createRegistry("test", createContributor(this.up)); TestHealthEndpointGroup testGroup = new TestHealthEndpointGroup((name) -> name.startsWith("test")); testGroup.setAdditionalPath(AdditionalHealthEndpointPath.from("server:/healthz")); testGroup.setShowComponents(false); - HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, - Collections.singletonMap("testGroup", testGroup)); - HealthResult result = create(this.registry, groups).getHealth(ApiVersion.V3, WebServerNamespace.SERVER, - SecurityContext.NONE, false, "healthz"); + HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, Map.of("testGroup", testGroup)); + E endpoint = create(registry, groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, WebServerNamespace.SERVER, SecurityContext.NONE, + false, "healthz"); CompositeHealth health = (CompositeHealth) getHealth(result); assertThat(health.getStatus().getCode()).isEqualTo("UP"); assertThat(health.getComponents()).isNull(); @@ -343,29 +327,33 @@ void getHealthWhenGroupHasAdditionalPathAndShowComponentsFalse() { @Test void getComponentHealthWhenGroupHasAdditionalPathAndShowComponentsFalse() { - this.registry.registerContributor("test", createContributor(this.up)); + R registry = createRegistry("test", createContributor(this.up)); TestHealthEndpointGroup testGroup = new TestHealthEndpointGroup((name) -> name.startsWith("test")); testGroup.setAdditionalPath(AdditionalHealthEndpointPath.from("server:/healthz")); testGroup.setShowComponents(false); - HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, - Collections.singletonMap("testGroup", testGroup)); - HealthResult result = create(this.registry, groups).getHealth(ApiVersion.V3, WebServerNamespace.SERVER, - SecurityContext.NONE, false, "healthz", "test"); + HealthEndpointGroups groups = HealthEndpointGroups.of(this.primaryGroup, Map.of("testGroup", testGroup)); + E endpoint = create(registry, groups); + HealthResult result = endpoint.getHealth(ApiVersion.V3, WebServerNamespace.SERVER, SecurityContext.NONE, + false, "healthz", "test"); assertThat(result).isNull(); } - protected final S create(R registry, HealthEndpointGroups groups) { + protected final E create(R registry, HealthEndpointGroups groups) { return create(registry, groups, null); } - protected abstract S create(R registry, HealthEndpointGroups groups, Duration slowIndicatorLoggingThreshold); + protected abstract E create(R registry, HealthEndpointGroups groups, Duration slowIndicatorLoggingThreshold); + + protected final R createRegistry(String name, C contributor) { + return createRegistry(Map.of(name, contributor)); + } - protected abstract R createRegistry(); + protected abstract R createRegistry(Map contributors); protected abstract C createContributor(Health health); protected abstract C createCompositeContributor(Map contributors); - protected abstract HealthComponent getHealth(HealthResult result); + protected abstract ContributedHealth getHealth(HealthResult result); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointTests.java index e545a5ccb52f..099ed8eb5710 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointTests.java @@ -24,6 +24,14 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.actuate.health.HealthEndpointSupport.HealthResult; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; +import org.springframework.boot.health.registry.DefaultHealthContributorRegistry; +import org.springframework.boot.health.registry.HealthContributorRegistry; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; @@ -38,37 +46,37 @@ */ @ExtendWith(OutputCaptureExtension.class) class HealthEndpointTests extends - HealthEndpointSupportTests { + HealthEndpointSupportTests { @Test void healthReturnsSystemHealth() { - this.registry.registerContributor("test", createContributor(this.up)); - HealthComponent health = create(this.registry, this.groups).health(); + HealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + HealthEndpoint endpoint = create(registry, this.groups); + ContributedHealth health = endpoint.health(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health).isInstanceOf(SystemHealth.class); } @Test void healthWithNoContributorReturnsUp() { - assertThat(this.registry).isEmpty(); - HealthComponent health = create(this.registry, - HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap())) - .health(); + HealthContributorRegistry registry = createRegistry(Collections.emptyMap()); + HealthEndpointGroups groups = HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap()); + ContributedHealth health = create(registry, groups).health(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health).isInstanceOf(Health.class); } @Test void healthWhenPathDoesNotExistReturnsNull() { - this.registry.registerContributor("test", createContributor(this.up)); - HealthComponent health = create(this.registry, this.groups).healthForPath("missing"); + HealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + ContributedHealth health = create(registry, this.groups).healthForPath("missing"); assertThat(health).isNull(); } @Test void healthWhenPathExistsReturnsHealth() { - this.registry.registerContributor("test", createContributor(this.up)); - HealthComponent health = create(this.registry, this.groups).healthForPath("test"); + HealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + ContributedHealth health = create(registry, this.groups).healthForPath("test"); assertThat(health).isEqualTo(this.up); } @@ -83,11 +91,10 @@ void healthWhenIndicatorIsSlow(CapturedOutput output) { } return this.up; }; - this.registry.registerContributor("test", indicator); - create(this.registry, this.groups, Duration.ofMillis(10)).health(); + HealthContributorRegistry registry = createRegistry("test", indicator); + create(registry, this.groups, Duration.ofMillis(10)).health(); assertThat(output).contains("Health contributor"); assertThat(output).contains("to respond"); - } @Override @@ -97,8 +104,8 @@ protected HealthEndpoint create(HealthContributorRegistry registry, HealthEndpoi } @Override - protected HealthContributorRegistry createRegistry() { - return new DefaultHealthContributorRegistry(); + protected HealthContributorRegistry createRegistry(Map contributors) { + return new DefaultHealthContributorRegistry(contributors, Collections.emptyList()); } @Override @@ -112,7 +119,7 @@ protected HealthContributor createCompositeContributor(Map result) { + protected ContributedHealth getHealth(HealthResult result) { return result.getHealth(); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java index b975a3b8ce2d..6be6c5cc453c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java @@ -23,6 +23,8 @@ import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.Health; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java index 4df9986571b5..00a339d6db15 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java @@ -27,6 +27,14 @@ import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.actuate.health.HealthEndpointSupport.HealthResult; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; +import org.springframework.boot.health.registry.DefaultHealthContributorRegistry; +import org.springframework.boot.health.registry.HealthContributorRegistry; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -38,14 +46,15 @@ * @author Scott Frederick */ class HealthEndpointWebExtensionTests extends - HealthEndpointSupportTests { + HealthEndpointSupportTests { @Test void healthReturnsSystemHealth() { - this.registry.registerContributor("test", createContributor(this.up)); - WebEndpointResponse response = create(this.registry, this.groups).health(ApiVersion.LATEST, - WebServerNamespace.SERVER, SecurityContext.NONE); - HealthComponent health = response.getBody(); + HealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + HealthEndpointWebExtension endpoint = create(registry, this.groups); + WebEndpointResponse response = endpoint.health(ApiVersion.LATEST, WebServerNamespace.SERVER, + SecurityContext.NONE); + ContributedHealth health = response.getBody(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health).isInstanceOf(SystemHealth.class); assertThat(response.getStatus()).isEqualTo(200); @@ -53,30 +62,33 @@ void healthReturnsSystemHealth() { @Test void healthWithNoContributorReturnsUp() { - assertThat(this.registry).isEmpty(); - WebEndpointResponse response = create(this.registry, - HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap())) - .health(ApiVersion.LATEST, WebServerNamespace.SERVER, SecurityContext.NONE); + HealthContributorRegistry registry = createRegistry(Collections.emptyMap()); + HealthEndpointGroups groups = HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap()); + HealthEndpointWebExtension endpoint = create(registry, groups); + WebEndpointResponse response = endpoint.health(ApiVersion.LATEST, WebServerNamespace.SERVER, + SecurityContext.NONE); assertThat(response.getStatus()).isEqualTo(200); - HealthComponent health = response.getBody(); + ContributedHealth health = response.getBody(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health).isInstanceOf(Health.class); } @Test void healthWhenPathDoesNotExistReturnsHttp404() { - this.registry.registerContributor("test", createContributor(this.up)); - WebEndpointResponse response = create(this.registry, this.groups).health(ApiVersion.LATEST, - WebServerNamespace.SERVER, SecurityContext.NONE, "missing"); + HealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + HealthEndpointWebExtension endpoint = create(registry, this.groups); + WebEndpointResponse response = endpoint.health(ApiVersion.LATEST, WebServerNamespace.SERVER, + SecurityContext.NONE, "missing"); assertThat(response.getBody()).isNull(); assertThat(response.getStatus()).isEqualTo(404); } @Test void healthWhenPathExistsReturnsHealth() { - this.registry.registerContributor("test", createContributor(this.up)); - WebEndpointResponse response = create(this.registry, this.groups).health(ApiVersion.LATEST, - WebServerNamespace.SERVER, SecurityContext.NONE, "test"); + HealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + HealthEndpointWebExtension endpoint = create(registry, this.groups); + WebEndpointResponse response = endpoint.health(ApiVersion.LATEST, WebServerNamespace.SERVER, + SecurityContext.NONE, "test"); assertThat(response.getBody()).isEqualTo(this.up); assertThat(response.getStatus()).isEqualTo(200); } @@ -88,8 +100,8 @@ protected HealthEndpointWebExtension create(HealthContributorRegistry registry, } @Override - protected HealthContributorRegistry createRegistry() { - return new DefaultHealthContributorRegistry(); + protected HealthContributorRegistry createRegistry(Map contributors) { + return new DefaultHealthContributorRegistry(contributors, Collections.emptyList()); } @Override @@ -103,7 +115,7 @@ protected HealthContributor createCompositeContributor(Map result) { + protected ContributedHealth getHealth(HealthResult result) { return result.getHealth(); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/NamedContributorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/NamedContributorTests.java deleted file mode 100644 index c4dc797feb30..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/NamedContributorTests.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link NamedContributor}. - * - * @author Phillip Webb - */ -class NamedContributorTests { - - @Test - void ofNameAndContributorCreatesContributor() { - NamedContributor contributor = NamedContributor.of("one", "two"); - assertThat(contributor.getName()).isEqualTo("one"); - assertThat(contributor.getContributor()).isEqualTo("two"); - } - - @Test - void ofWhenNameIsNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> NamedContributor.of(null, "two")) - .withMessage("'name' must not be null"); - } - - @Test - void ofWhenContributorIsNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> NamedContributor.of("one", null)) - .withMessage("'contributor' must not be null"); - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/NamedContributorsMapAdapterTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/NamedContributorsMapAdapterTests.java deleted file mode 100644 index ceda9df48884..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/NamedContributorsMapAdapterTests.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link NamedContributorsMapAdapter}. - * - * @author Phillip Webb - * @author Guirong Hu - */ -class NamedContributorsMapAdapterTests { - - @Test - void createWhenMapIsNullThrowsException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(null, Function.identity())) - .withMessage("'map' must not be null"); - } - - @Test - void createWhenValueAdapterIsNullThrowsException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(Collections.emptyMap(), null)) - .withMessage("'valueAdapter' must not be null"); - } - - @Test - void createWhenMapContainsNullValueThrowsException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(Collections.singletonMap("test", null), - Function.identity())) - .withMessage("'map' must not contain null values"); - } - - @Test - void createWhenMapContainsNullKeyThrowsException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(Collections.singletonMap(null, "test"), - Function.identity())) - .withMessage("'map' must not contain null keys"); - } - - @Test - void createWhenMapContainsKeyWithSlashThrowsException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(Collections.singletonMap("test/key", "test"), - Function.identity())) - .withMessage("'map' keys must not contain a '/'"); - } - - @Test - void iterateReturnsAdaptedEntries() { - TestNamedContributorsMapAdapter adapter = createAdapter(); - Iterator> iterator = adapter.iterator(); - NamedContributor one = iterator.next(); - NamedContributor two = iterator.next(); - assertThat(iterator.hasNext()).isFalse(); - assertThat(one.getName()).isEqualTo("one"); - assertThat(one.getContributor()).isEqualTo("eno"); - assertThat(two.getName()).isEqualTo("two"); - assertThat(two.getContributor()).isEqualTo("owt"); - } - - @Test - void getContributorReturnsAdaptedEntry() { - TestNamedContributorsMapAdapter adapter = createAdapter(); - assertThat(adapter.getContributor("one")).isEqualTo("eno"); - assertThat(adapter.getContributor("two")).isEqualTo("owt"); - } - - @Test - void getContributorCallsAdaptersOnlyOnce() { - Map map = new LinkedHashMap<>(); - map.put("one", "one"); - map.put("two", "two"); - int callCount = map.size(); - AtomicInteger counter = new AtomicInteger(0); - TestNamedContributorsMapAdapter adapter = new TestNamedContributorsMapAdapter<>(map, - (name) -> count(name, counter)); - assertThat(adapter.getContributor("one")).isEqualTo("eno"); - assertThat(counter.get()).isEqualTo(callCount); - assertThat(adapter.getContributor("two")).isEqualTo("owt"); - assertThat(counter.get()).isEqualTo(callCount); - } - - @Test - void getContributorWhenNotInMapReturnsNull() { - TestNamedContributorsMapAdapter adapter = createAdapter(); - assertThat(adapter.getContributor("missing")).isNull(); - } - - private TestNamedContributorsMapAdapter createAdapter() { - Map map = new LinkedHashMap<>(); - map.put("one", "one"); - map.put("two", "two"); - TestNamedContributorsMapAdapter adapter = new TestNamedContributorsMapAdapter<>(map, this::reverse); - return adapter; - } - - private String count(CharSequence charSequence, AtomicInteger counter) { - counter.incrementAndGet(); - return reverse(charSequence); - } - - private String reverse(CharSequence charSequence) { - return new StringBuilder(charSequence).reverse().toString(); - } - - static class TestNamedContributorsMapAdapter extends NamedContributorsMapAdapter { - - TestNamedContributorsMapAdapter(Map map, Function valueAdapter) { - super(map, valueAdapter); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtensionTests.java index ae7f07a35010..93060907d183 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtensionTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtensionTests.java @@ -27,6 +27,14 @@ import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.health.HealthEndpointSupport.HealthResult; +import org.springframework.boot.health.contributor.CompositeReactiveHealthContributor; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Status; +import org.springframework.boot.health.registry.DefaultReactiveHealthContributorRegistry; +import org.springframework.boot.health.registry.ReactiveHealthContributorRegistry; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -38,15 +46,16 @@ * @author Scott Frederick */ class ReactiveHealthEndpointWebExtensionTests extends - HealthEndpointSupportTests> { + HealthEndpointSupportTests> { @Test void healthReturnsSystemHealth() { - this.registry.registerContributor("test", createContributor(this.up)); - WebEndpointResponse response = create(this.registry, this.groups) + ReactiveHealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + ReactiveHealthEndpointWebExtension endpoint = create(registry, this.groups); + WebEndpointResponse response = endpoint .health(ApiVersion.LATEST, null, SecurityContext.NONE) .block(); - HealthComponent health = response.getBody(); + ContributedHealth health = response.getBody(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health).isInstanceOf(SystemHealth.class); assertThat(response.getStatus()).isEqualTo(200); @@ -54,21 +63,23 @@ void healthReturnsSystemHealth() { @Test void healthWithNoContributorReturnsUp() { - assertThat(this.registry).isEmpty(); - WebEndpointResponse response = create(this.registry, - HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap())) + ReactiveHealthContributorRegistry registry = createRegistry(Collections.emptyMap()); + HealthEndpointGroups groups = HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap()); + ReactiveHealthEndpointWebExtension endpoint = create(registry, groups); + WebEndpointResponse response = endpoint .health(ApiVersion.LATEST, null, SecurityContext.NONE) .block(); assertThat(response.getStatus()).isEqualTo(200); - HealthComponent health = response.getBody(); + ContributedHealth health = response.getBody(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health).isInstanceOf(Health.class); } @Test void healthWhenPathDoesNotExistReturnsHttp404() { - this.registry.registerContributor("test", createContributor(this.up)); - WebEndpointResponse response = create(this.registry, this.groups) + ReactiveHealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + ReactiveHealthEndpointWebExtension endpoint = create(registry, this.groups); + WebEndpointResponse response = endpoint .health(ApiVersion.LATEST, null, SecurityContext.NONE, "missing") .block(); assertThat(response.getBody()).isNull(); @@ -77,8 +88,9 @@ void healthWhenPathDoesNotExistReturnsHttp404() { @Test void healthWhenPathExistsReturnsHealth() { - this.registry.registerContributor("test", createContributor(this.up)); - WebEndpointResponse response = create(this.registry, this.groups) + ReactiveHealthContributorRegistry registry = createRegistry("test", createContributor(this.up)); + ReactiveHealthEndpointWebExtension endpoint = create(registry, this.groups); + WebEndpointResponse response = endpoint .health(ApiVersion.LATEST, null, SecurityContext.NONE, "test") .block(); assertThat(response.getBody()).isEqualTo(this.up); @@ -92,8 +104,8 @@ protected ReactiveHealthEndpointWebExtension create(ReactiveHealthContributorReg } @Override - protected ReactiveHealthContributorRegistry createRegistry() { - return new DefaultReactiveHealthContributorRegistry(); + protected ReactiveHealthContributorRegistry createRegistry(Map contributors) { + return new DefaultReactiveHealthContributorRegistry(contributors, Collections.emptyList()); } @Override @@ -108,7 +120,7 @@ protected ReactiveHealthContributor createCompositeContributor( } @Override - protected HealthComponent getHealth(HealthResult> result) { + protected ContributedHealth getHealth(HealthResult> result) { return result.getHealth().block(); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthIndicatorImplementationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthIndicatorImplementationTests.java index 8f63de4ef9c2..5e4da2143c3d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthIndicatorImplementationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthIndicatorImplementationTests.java @@ -23,7 +23,8 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import org.springframework.boot.actuate.health.Health.Builder; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; @@ -73,7 +74,7 @@ private static final class SimpleReactiveHealthIndicator extends AbstractReactiv } @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { return Mono.just(builder.up().build()); } @@ -86,7 +87,7 @@ private static final class CustomErrorMessageReactiveHealthIndicator extends Abs } @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { return Mono.error(new UnsupportedOperationException()); } @@ -100,7 +101,7 @@ private static final class CustomErrorMessageFunctionReactiveHealthIndicator } @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { throw new RuntimeException(); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SimpleHttpCodeStatusMapperTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SimpleHttpCodeStatusMapperTests.java index 4b7ce60d03c9..37ad794fbf09 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SimpleHttpCodeStatusMapperTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SimpleHttpCodeStatusMapperTests.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SimpleStatusAggregatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SimpleStatusAggregatorTests.java index a1735af69d5c..64c5233125a2 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SimpleStatusAggregatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SimpleStatusAggregatorTests.java @@ -18,6 +18,8 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.health.contributor.Status; + import static org.assertj.core.api.Assertions.assertThat; /** diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SystemHealthTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SystemHealthTests.java index 8779b4a9304f..0fabc1c2dbaf 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SystemHealthTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/SystemHealthTests.java @@ -17,15 +17,22 @@ package org.springframework.boot.actuate.health; import java.util.Arrays; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; +import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.endpoint.ApiVersion; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; @@ -38,11 +45,11 @@ class SystemHealthTests { @Test void serializeWithJacksonReturnsValidJson() throws Exception { - Map components = new LinkedHashMap<>(); + Map components = new LinkedHashMap<>(); components.put("db1", Health.up().build()); components.put("db2", Health.down().withDetail("a", "b").build()); Set groups = new LinkedHashSet<>(Arrays.asList("liveness", "readiness")); - CompositeHealth health = new SystemHealth(ApiVersion.V3, Status.UP, components, groups); + CompositeHealth health = new SystemHealth(Status.UP, components, groups, ApiVersion.V3); ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(health); assertThat(json).isEqualTo("{\"status\":\"UP\",\"components\":{\"db1\":{\"status\":\"UP\"}," @@ -50,4 +57,28 @@ void serializeWithJacksonReturnsValidJson() throws Exception { + "\"groups\":[\"liveness\",\"readiness\"]}"); } + @Test + void serializeWhenNoGroupsWithJacksonReturnsValidJson() throws Exception { + Map components = new LinkedHashMap<>(); + components.put("db1", Health.up().build()); + components.put("db2", Health.down().withDetail("a", "b").build()); + CompositeHealth health = new SystemHealth(Status.UP, components, null, ApiVersion.V2); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(health); + assertThat(json).isEqualTo("{\"status\":\"UP\",\"details\":{\"db1\":{\"status\":\"UP\"}," + + "\"db2\":{\"status\":\"DOWN\",\"details\":{\"a\":\"b\"}}}}"); + } + + @Test // gh-26797 + void serializeV2WithJacksonAndDisabledCanOverrideAccessModifiersReturnsValidJson() throws Exception { + Map components = new LinkedHashMap<>(); + components.put("db1", Health.up().build()); + components.put("db2", Health.down().withDetail("a", "b").build()); + CompositeHealth health = new SystemHealth(Status.UP, components, Collections.emptySet(), ApiVersion.V2); + JsonMapper mapper = JsonMapper.builder().disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS).build(); + String json = mapper.writeValueAsString(health); + assertThat(json).isEqualTo("{\"status\":\"UP\",\"details\":{\"db1\":{\"status\":\"UP\"}," + + "\"db2\":{\"status\":\"DOWN\",\"details\":{\"a\":\"b\"}}}}"); + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/http/OutcomeTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/http/OutcomeTests.java deleted file mode 100644 index 1a472a63230f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/http/OutcomeTests.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.metrics.http; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link Outcome}. - * - * @author Andy Wilkinson - */ -class OutcomeTests { - - @Test - void outcomeForInformationalStatusIsInformational() { - for (int status = 100; status < 200; status++) { - assertThat(Outcome.forStatus(status)).isEqualTo(Outcome.INFORMATIONAL); - } - } - - @Test - void outcomeForSuccessStatusIsSuccess() { - for (int status = 200; status < 300; status++) { - assertThat(Outcome.forStatus(status)).isEqualTo(Outcome.SUCCESS); - } - } - - @Test - void outcomeForRedirectionStatusIsRedirection() { - for (int status = 300; status < 400; status++) { - assertThat(Outcome.forStatus(status)).isEqualTo(Outcome.REDIRECTION); - } - } - - @Test - void outcomeForClientErrorStatusIsClientError() { - for (int status = 400; status < 500; status++) { - assertThat(Outcome.forStatus(status)).isEqualTo(Outcome.CLIENT_ERROR); - } - } - - @Test - void outcomeForServerErrorStatusIsServerError() { - for (int status = 500; status < 600; status++) { - assertThat(Outcome.forStatus(status)).isEqualTo(Outcome.SERVER_ERROR); - } - } - - @Test - void outcomeForStatusBelowLowestKnownSeriesIsUnknown() { - assertThat(Outcome.forStatus(99)).isEqualTo(Outcome.UNKNOWN); - } - - @Test - void outcomeForStatusAboveHighestKnownSeriesIsUnknown() { - assertThat(Outcome.forStatus(600)).isEqualTo(Outcome.UNKNOWN); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ssl/SslHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ssl/SslHealthIndicatorTests.java index 31ddbaa339a8..82977a144bad 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ssl/SslHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ssl/SslHealthIndicatorTests.java @@ -23,8 +23,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.info.SslInfo; import org.springframework.boot.info.SslInfo.BundleInfo; import org.springframework.boot.info.SslInfo.CertificateChainInfo; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicatorTests.java index 3cb3219359e6..a6931783431e 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicatorTests.java @@ -24,9 +24,9 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.util.unit.DataSize; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointTests.java deleted file mode 100644 index d89e4ed4fb22..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/MappingsEndpointTests.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.web.mappings; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -import jakarta.servlet.FilterRegistration; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRegistration; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.web.mappings.MappingsEndpoint.ApplicationMappingsDescriptor; -import org.springframework.boot.actuate.web.mappings.MappingsEndpoint.ContextMappingsDescriptor; -import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlerMappingDescription; -import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletMappingDescription; -import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.FilterRegistrationMappingDescription; -import org.springframework.boot.actuate.web.mappings.servlet.FiltersMappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.ServletRegistrationMappingDescription; -import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.mock.web.MockServletConfig; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.context.ConfigurableWebApplicationContext; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.reactive.config.EnableWebFlux; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.function.RequestPredicates; -import org.springframework.web.servlet.function.RouterFunctions; -import org.springframework.web.util.pattern.PathPatternParser; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.springframework.web.reactive.function.server.RequestPredicates.GET; -import static org.springframework.web.reactive.function.server.RequestPredicates.POST; -import static org.springframework.web.reactive.function.server.RouterFunctions.route; - -/** - * Tests for {@link MappingsEndpoint}. - * - * @author Andy Wilkinson - * @author Stephane Nicoll - * @author Xiong Tang - */ -class MappingsEndpointTests { - - @Test - void servletWebMappings() { - Supplier contextSupplier = prepareContextSupplier(); - new WebApplicationContextRunner(contextSupplier) - .withUserConfiguration(EndpointConfiguration.class, ServletWebConfiguration.class) - .run((context) -> { - ContextMappingsDescriptor contextMappings = contextMappings(context); - assertThat(contextMappings.getParentId()).isNull(); - assertThat(contextMappings.getMappings()).containsOnlyKeys("dispatcherServlets", "servletFilters", - "servlets"); - Map> dispatcherServlets = mappings(contextMappings, - "dispatcherServlets"); - assertThat(dispatcherServlets).containsOnlyKeys("dispatcherServlet"); - List handlerMappings = dispatcherServlets.get("dispatcherServlet"); - assertThat(handlerMappings).hasSize(4); - List servlets = mappings(contextMappings, "servlets"); - assertThat(servlets).hasSize(1); - List filters = mappings(contextMappings, "servletFilters"); - assertThat(filters).hasSize(1); - }); - } - - @Test - void servletWebMappingsWithPathPatternParser() { - Supplier contextSupplier = prepareContextSupplier(); - new WebApplicationContextRunner(contextSupplier) - .withUserConfiguration(EndpointConfiguration.class, ServletWebConfiguration.class, - PathPatternParserConfiguration.class) - .run((context) -> { - ContextMappingsDescriptor contextMappings = contextMappings(context); - assertThat(contextMappings.getParentId()).isNull(); - assertThat(contextMappings.getMappings()).containsOnlyKeys("dispatcherServlets", "servletFilters", - "servlets"); - Map> dispatcherServlets = mappings(contextMappings, - "dispatcherServlets"); - assertThat(dispatcherServlets).containsOnlyKeys("dispatcherServlet"); - List handlerMappings = dispatcherServlets.get("dispatcherServlet"); - assertThat(handlerMappings).hasSize(4); - List servlets = mappings(contextMappings, "servlets"); - assertThat(servlets).hasSize(1); - List filters = mappings(contextMappings, "servletFilters"); - assertThat(filters).hasSize(1); - }); - } - - @Test - void servletWebMappingsWithAdditionalDispatcherServlets() { - Supplier contextSupplier = prepareContextSupplier(); - new WebApplicationContextRunner(contextSupplier) - .withUserConfiguration(EndpointConfiguration.class, ServletWebConfiguration.class, - CustomDispatcherServletConfiguration.class) - .run((context) -> { - ContextMappingsDescriptor contextMappings = contextMappings(context); - Map> dispatcherServlets = mappings(contextMappings, - "dispatcherServlets"); - assertThat(dispatcherServlets).containsOnlyKeys("dispatcherServlet", - "customDispatcherServletRegistration", "anotherDispatcherServletRegistration"); - assertThat(dispatcherServlets.get("dispatcherServlet")).hasSize(4); - assertThat(dispatcherServlets.get("customDispatcherServletRegistration")).hasSize(4); - assertThat(dispatcherServlets.get("anotherDispatcherServletRegistration")).hasSize(4); - }); - } - - @SuppressWarnings("unchecked") - private Supplier prepareContextSupplier() { - ServletContext servletContext = mock(ServletContext.class); - given(servletContext.getInitParameterNames()).willReturn(Collections.emptyEnumeration()); - given(servletContext.getAttributeNames()).willReturn(Collections.emptyEnumeration()); - FilterRegistration filterRegistration = mock(FilterRegistration.class); - given((Map) servletContext.getFilterRegistrations()) - .willReturn(Collections.singletonMap("testFilter", filterRegistration)); - ServletRegistration servletRegistration = mock(ServletRegistration.class); - given((Map) servletContext.getServletRegistrations()) - .willReturn(Collections.singletonMap("testServlet", servletRegistration)); - return () -> { - AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext(); - context.setServletContext(servletContext); - return context; - }; - } - - @Test - void reactiveWebMappings() { - new ReactiveWebApplicationContextRunner() - .withUserConfiguration(EndpointConfiguration.class, ReactiveWebConfiguration.class) - .run((context) -> { - ContextMappingsDescriptor contextMappings = contextMappings(context); - assertThat(contextMappings.getParentId()).isNull(); - assertThat(contextMappings.getMappings()).containsOnlyKeys("dispatcherHandlers"); - Map> dispatcherHandlers = mappings(contextMappings, - "dispatcherHandlers"); - assertThat(dispatcherHandlers).containsOnlyKeys("webHandler"); - List handlerMappings = dispatcherHandlers.get("webHandler"); - assertThat(handlerMappings).hasSize(4); - }); - } - - private ContextMappingsDescriptor contextMappings(ApplicationContext context) { - ApplicationMappingsDescriptor applicationMappings = context.getBean(MappingsEndpoint.class).mappings(); - assertThat(applicationMappings.getContexts()).containsOnlyKeys(context.getId()); - return applicationMappings.getContexts().get(context.getId()); - } - - @SuppressWarnings("unchecked") - private T mappings(ContextMappingsDescriptor contextMappings, String key) { - return (T) contextMappings.getMappings().get(key); - } - - @Configuration(proxyBeanMethods = false) - static class EndpointConfiguration { - - @Bean - MappingsEndpoint mappingsEndpoint(Collection descriptionProviders, - ApplicationContext context) { - return new MappingsEndpoint(descriptionProviders, context); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableWebFlux - @Controller - static class ReactiveWebConfiguration { - - @Bean - DispatcherHandlersMappingDescriptionProvider dispatcherHandlersMappingDescriptionProvider() { - return new DispatcherHandlersMappingDescriptionProvider(); - } - - @Bean - RouterFunction routerFunction() { - return route(GET("/one"), (request) -> ServerResponse.ok().build()).andRoute(POST("/two"), - (request) -> ServerResponse.ok().build()); - } - - @RequestMapping("/three") - void three() { - - } - - @Bean - RouterFunction routerFunctionWithAttributes() { - return route(GET("/four"), (request) -> ServerResponse.ok().build()).withAttribute("test", "test"); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableWebMvc - @Controller - static class ServletWebConfiguration { - - @Bean - DispatcherServletsMappingDescriptionProvider dispatcherServletsMappingDescriptionProvider() { - return new DispatcherServletsMappingDescriptionProvider(); - } - - @Bean - ServletsMappingDescriptionProvider servletsMappingDescriptionProvider() { - return new ServletsMappingDescriptionProvider(); - } - - @Bean - FiltersMappingDescriptionProvider filtersMappingDescriptionProvider() { - return new FiltersMappingDescriptionProvider(); - } - - @Bean - DispatcherServlet dispatcherServlet(WebApplicationContext context) throws ServletException { - DispatcherServlet dispatcherServlet = new DispatcherServlet(context); - dispatcherServlet.init(new MockServletConfig()); - return dispatcherServlet; - } - - @Bean - org.springframework.web.servlet.function.RouterFunction routerFunction() { - return RouterFunctions - .route(RequestPredicates.GET("/one"), - (request) -> org.springframework.web.servlet.function.ServerResponse.ok().build()) - .andRoute(RequestPredicates.POST("/two"), - (request) -> org.springframework.web.servlet.function.ServerResponse.ok().build()); - } - - @RequestMapping("/three") - void three() { - - } - - @Bean - org.springframework.web.servlet.function.RouterFunction routerFunctionWithAttributes() { - return RouterFunctions - .route(RequestPredicates.GET("/four"), - (request) -> org.springframework.web.servlet.function.ServerResponse.ok().build()) - .withAttribute("test", "test"); - } - - } - - @Configuration - static class CustomDispatcherServletConfiguration { - - @Bean - ServletRegistrationBean customDispatcherServletRegistration(WebApplicationContext context) { - ServletRegistrationBean registration = new ServletRegistrationBean<>( - createTestDispatcherServlet(context)); - registration.setName("customDispatcherServletRegistration"); - return registration; - } - - @Bean - DispatcherServlet anotherDispatcherServlet(WebApplicationContext context) { - return createTestDispatcherServlet(context); - } - - @Bean - ServletRegistrationBean anotherDispatcherServletRegistration( - DispatcherServlet dispatcherServlet, WebApplicationContext context) { - ServletRegistrationBean registrationBean = new ServletRegistrationBean<>( - anotherDispatcherServlet(context)); - registrationBean.setName("anotherDispatcherServletRegistration"); - return registrationBean; - } - - private DispatcherServlet createTestDispatcherServlet(WebApplicationContext context) { - try { - DispatcherServlet dispatcherServlet = new DispatcherServlet(context); - dispatcherServlet.init(new MockServletConfig()); - return dispatcherServlet; - } - catch (ServletException ex) { - throw new IllegalStateException(ex); - } - } - - } - - @Configuration - static class PathPatternParserConfiguration { - - @Bean - WebMvcConfigurer pathPatternParserConfigurer() { - return new WebMvcConfigurer() { - - @Override - public void configurePathMatch(PathMatchConfigurer configurer) { - configurer.setPatternParser(new PathPatternParser()); - } - - }; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointInfrastructureProvider.java b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointInfrastructureProvider.java new file mode 100644 index 000000000000..7e32ef05db6d --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointInfrastructureProvider.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.test; + +import java.util.List; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; + +/** + * Strategy interface to provide the web endpoint configuration for a target + * {@linkplain Infrastructure infrastructure}. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +public interface WebEndpointInfrastructureProvider { + + /** + * Specify if the given {@link Infrastructure} is supported. + * @param infrastructure the infrastructure to target + * @return {@code true} if this instance can provide the configuration + */ + boolean supports(Infrastructure infrastructure); + + /** + * Return the configuration to use for the given {@code infrastructure}. + * @param infrastructure the infrastructure to target + * @return the configuration for that infrastructure + */ + List> getInfrastructureConfiguration(Infrastructure infrastructure); + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java similarity index 77% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java rename to spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java index 7d8f05b7b629..4cd071eacee8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java +++ b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java @@ -31,9 +31,10 @@ /** * Signals that a test should be run against one or more of the web endpoint - * infrastructure implementations (Jersey, Web MVC, and WebFlux) + * infrastructure implementations (Jersey, Web MVC, and WebFlux). * * @author Andy Wilkinson + * @since 4.0.0 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @@ -52,29 +53,27 @@ enum Infrastructure { /** * Actuator running on the Jersey-based infrastructure. */ - JERSEY("Jersey", WebEndpointTestInvocationContextProvider::createJerseyContext), + JERSEY("Jersey"), /** * Actuator running on the WebMVC-based infrastructure. */ - MVC("WebMvc", WebEndpointTestInvocationContextProvider::createWebMvcContext), + MVC("WebMvc"), /** * Actuator running on the WebFlux-based infrastructure. */ - WEBFLUX("WebFlux", WebEndpointTestInvocationContextProvider::createWebFluxContext); + WEBFLUX("WebFlux"); private final String name; - private final Function>, ConfigurableApplicationContext> contextFactory; - - Infrastructure(String name, Function>, ConfigurableApplicationContext> contextFactory) { + Infrastructure(String name) { this.name = name; - this.contextFactory = contextFactory; } - WebEndpointsInvocationContext createInvocationContext() { - return new WebEndpointsInvocationContext(this.name, this.contextFactory); + WebEndpointsInvocationContext createInvocationContext( + Function>, ConfigurableApplicationContext> contextFactory) { + return new WebEndpointsInvocationContext(this.name, contextFactory); } } diff --git a/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java new file mode 100644 index 000000000000..2a5d45020224 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java @@ -0,0 +1,257 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.test; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.jupiter.api.extension.TestTemplateInvocationContext; +import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; +import org.junit.platform.commons.util.AnnotationUtils; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; +import org.springframework.boot.web.server.context.WebServerInitializedEvent; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigRegistry; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.MergedAnnotations; +import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; +import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.http.HttpMethod; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.ClassUtils; +import org.springframework.web.util.DefaultUriBuilderFactory; +import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode; + +/** + * {@link TestTemplateInvocationContextProvider} for + * {@link WebEndpointTest @WebEndpointTest}. + * + * @author Andy Wilkinson` + * @author Stephane Nicoll + */ +class WebEndpointTestInvocationContextProvider implements TestTemplateInvocationContextProvider { + + private final Map>> infrastructures; + + private final Map>, ConfigurableApplicationContext>> contextFactories; + + WebEndpointTestInvocationContextProvider() { + this.infrastructures = new HashMap<>(); + List providers = SpringFactoriesLoader + .loadFactories(WebEndpointInfrastructureProvider.class, getClass().getClassLoader()); + Stream.of(Infrastructure.values()) + .forEach((infrastructure) -> providers.stream() + .filter((provider) -> provider.supports(infrastructure)) + .findFirst() + .ifPresent((provider) -> this.infrastructures.put(infrastructure, + provider.getInfrastructureConfiguration(infrastructure)))); + this.contextFactories = Map.of(Infrastructure.JERSEY, this::createJerseyContext, Infrastructure.MVC, + this::createWebMvcContext, Infrastructure.WEBFLUX, this::createWebFluxContext); + } + + @Override + public boolean supportsTestTemplate(ExtensionContext context) { + return true; + } + + @Override + public Stream provideTestTemplateInvocationContexts( + ExtensionContext extensionContext) { + WebEndpointTest webEndpointTest = AnnotationUtils + .findAnnotation(extensionContext.getRequiredTestMethod(), WebEndpointTest.class) + .orElseThrow(() -> new IllegalStateException("Unable to find WebEndpointTest annotation on %s" + .formatted(extensionContext.getRequiredTestMethod()))); + return Stream.of(webEndpointTest.infrastructure()).distinct().map(this::createInvocationContext); + } + + private WebEndpointsInvocationContext createInvocationContext(Infrastructure infrastructure) { + return infrastructure.createInvocationContext(this.contextFactories.get(infrastructure)); + } + + private ConfigurableApplicationContext createJerseyContext(List> classes) { + AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); + classes.addAll(getEndpointInfrastructureConfiguration(Infrastructure.JERSEY)); + context.register(ClassUtils.toClassArray(classes)); + context.refresh(); + return context; + } + + private ConfigurableApplicationContext createWebMvcContext(List> classes) { + AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); + classes.addAll(getEndpointInfrastructureConfiguration(Infrastructure.MVC)); + context.register(ClassUtils.toClassArray(classes)); + context.refresh(); + return context; + } + + private ConfigurableApplicationContext createWebFluxContext(List> classes) { + AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext(); + classes.addAll(getEndpointInfrastructureConfiguration(Infrastructure.WEBFLUX)); + context.register(ClassUtils.toClassArray(classes)); + context.refresh(); + return context; + } + + private List> getEndpointInfrastructureConfiguration(Infrastructure infrastructure) { + List> configurationClasses = new ArrayList<>(); + configurationClasses.add(EndpointBaseConfiguration.class); + List> endpointConfiguration = this.infrastructures.get(infrastructure); + if (endpointConfiguration == null) { + throw new IllegalStateException( + "No endpoint infrastructure configuration found for " + infrastructure.name()); + } + configurationClasses.addAll(endpointConfiguration); + return configurationClasses; + } + + static class WebEndpointsInvocationContext + implements TestTemplateInvocationContext, BeforeEachCallback, AfterEachCallback, ParameterResolver { + + private static final Duration TIMEOUT = Duration.ofMinutes(5); + + private final String name; + + private final Function>, ConfigurableApplicationContext> contextFactory; + + private ConfigurableApplicationContext context; + + WebEndpointsInvocationContext(String name, + Function>, ConfigurableApplicationContext> contextFactory) { + this.name = name; + this.contextFactory = contextFactory; + } + + @Override + public void beforeEach(ExtensionContext extensionContext) throws Exception { + List> configurationClasses = Stream + .of(extensionContext.getRequiredTestClass().getDeclaredClasses()) + .filter(this::isConfiguration) + .collect(Collectors.toCollection(ArrayList::new)); + this.context = this.contextFactory.apply(configurationClasses); + } + + private boolean isConfiguration(Class candidate) { + return MergedAnnotations.from(candidate, SearchStrategy.TYPE_HIERARCHY).isPresent(Configuration.class); + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + if (this.context != null) { + this.context.close(); + } + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + Class type = parameterContext.getParameter().getType(); + return type.equals(WebTestClient.class) || type.isAssignableFrom(ConfigurableApplicationContext.class); + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + Class type = parameterContext.getParameter().getType(); + if (type.equals(WebTestClient.class)) { + return createWebTestClient(); + } + else { + return this.context; + } + } + + @Override + public List getAdditionalExtensions() { + return Collections.singletonList(this); + } + + @Override + public String getDisplayName(int invocationIndex) { + return this.name; + } + + private WebTestClient createWebTestClient() { + DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory( + "http://localhost:" + determinePort()); + uriBuilderFactory.setEncodingMode(EncodingMode.NONE); + return WebTestClient.bindToServer() + .uriBuilderFactory(uriBuilderFactory) + .responseTimeout(TIMEOUT) + .codecs((codecs) -> codecs.defaultCodecs().maxInMemorySize(-1)) + .filter((request, next) -> { + if (HttpMethod.GET == request.method()) { + return next.exchange(request).retry(10); + } + return next.exchange(request); + }) + .build(); + } + + private int determinePort() { + return this.context.getBean(PortHolder.class).getPort(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class EndpointBaseConfiguration implements ApplicationListener { + + private final PortHolder portHolder = new PortHolder(); + + @Bean + PortHolder portHolder() { + return this.portHolder; + } + + @Override + public void onApplicationEvent(WebServerInitializedEvent event) { + this.portHolder.setPort(event.getWebServer().getPort()); + } + + } + + private static final class PortHolder { + + private int port; + + private int getPort() { + return this.port; + } + + private void setPort(int port) { + this.port = port; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/package-info.java b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/package-info.java new file mode 100644 index 000000000000..64d151484a79 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testing endpoints against one or more of the web endpoint infrastructure + * implementations. + */ +package org.springframework.boot.actuate.endpoint.web.test; diff --git a/spring-boot-project/spring-boot-amqp/build.gradle b/spring-boot-project/spring-boot-amqp/build.gradle new file mode 100644 index 000000000000..c2ef2a194c51 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/build.gradle @@ -0,0 +1,58 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot AMQP" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-messaging") + api("org.springframework.amqp:spring-rabbit") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + implementation(project(":spring-boot-project:spring-boot-tx")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("io.micrometer:micrometer-core") + optional("org.springframework.amqp:spring-rabbit-stream") + optional("org.testcontainers:rabbitmq") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("ch.qos.logback:logback-classic") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java index 45026f8c9509..1748e9f4b0bd 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.rabbit; +package org.springframework.boot.amqp.docker.compose; -import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails; -import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails.Address; +import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; +import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/amqp/RabbitContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java similarity index 93% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/amqp/RabbitContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java index ba0999b44c72..4efbcd087315 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/amqp/RabbitContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-amqp/src/dockerTest/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.amqp; +package org.springframework.boot.amqp.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -30,9 +30,9 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; -import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-amqp/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-amqp/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/rabbit/rabbit-bitnami-compose.yaml b/spring-boot-project/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/rabbit/rabbit-bitnami-compose.yaml rename to spring-boot-project/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/rabbit/rabbit-compose.yaml b/spring-boot-project/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/rabbit/rabbit-compose.yaml rename to spring-boot-project/spring-boot-amqp/src/dockerTest/resources/org/springframework/boot/amqp/docker/compose/rabbit-compose.yaml diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-amqp/src/dockerTest/resources/spring.properties similarity index 100% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/resources/spring.properties rename to spring-boot-project/spring-boot-amqp/src/dockerTest/resources/spring.properties diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/AbstractConnectionFactoryConfigurer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractConnectionFactoryConfigurer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/AbstractConnectionFactoryConfigurer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractConnectionFactoryConfigurer.java index 967449a3ac39..dabc7b4e3ae3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/AbstractConnectionFactoryConfigurer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractConnectionFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.util.stream.Collectors; @@ -31,7 +31,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 2.6.0 + * @since 4.0.0 */ public abstract class AbstractConnectionFactoryConfigurer { @@ -56,7 +56,6 @@ protected AbstractConnectionFactoryConfigurer(RabbitProperties properties) { * @param properties the properties to use to configure the connection factory * @param connectionDetails the connection details to use to configure the connection * factory - * @since 3.1.0 */ protected AbstractConnectionFactoryConfigurer(RabbitProperties properties, RabbitConnectionDetails connectionDetails) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/AbstractRabbitListenerContainerFactoryConfigurer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/AbstractRabbitListenerContainerFactoryConfigurer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java index 52c65bb769d9..89fc7cf87dd7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/AbstractRabbitListenerContainerFactoryConfigurer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/AbstractRabbitListenerContainerFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.util.List; import java.util.concurrent.Executor; @@ -25,7 +25,7 @@ import org.springframework.amqp.rabbit.retry.MessageRecoverer; import org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer; import org.springframework.amqp.support.converter.MessageConverter; -import org.springframework.boot.autoconfigure.amqp.RabbitProperties.ListenerRetry; +import org.springframework.boot.amqp.autoconfigure.RabbitProperties.ListenerRetry; import org.springframework.retry.support.RetryTemplate; import org.springframework.util.Assert; @@ -36,7 +36,7 @@ * @param the container factory type. * @author Gary Russell * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public abstract class AbstractRabbitListenerContainerFactoryConfigurer> { @@ -53,7 +53,6 @@ public abstract class AbstractRabbitListenerContainerFactoryConfigurer r /** * Set the task executor to use. * @param taskExecutor the task executor - * @since 3.2.0 */ public void setTaskExecutor(Executor taskExecutor) { this.taskExecutor = taskExecutor; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/CachingConnectionFactoryConfigurer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/CachingConnectionFactoryConfigurer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/CachingConnectionFactoryConfigurer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/CachingConnectionFactoryConfigurer.java index 6fa78cab4b6a..fc6a70bafeb8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/CachingConnectionFactoryConfigurer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/CachingConnectionFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.time.Duration; @@ -33,7 +33,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 2.6.0 + * @since 4.0.0 */ public class CachingConnectionFactoryConfigurer extends AbstractConnectionFactoryConfigurer { @@ -52,7 +52,6 @@ public CachingConnectionFactoryConfigurer(RabbitProperties properties) { * @param properties the properties to use to configure the connection factory * @param connectionDetails the connection details to use to configure the connection * factory - * @since 3.1.0 */ public CachingConnectionFactoryConfigurer(RabbitProperties properties, RabbitConnectionDetails connectionDetails) { super(properties, connectionDetails); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/ConnectionFactoryCustomizer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/ConnectionFactoryCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/ConnectionFactoryCustomizer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/ConnectionFactoryCustomizer.java index 1a18cf746dfa..6e49974738c0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/ConnectionFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/ConnectionFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import com.rabbitmq.client.ConnectionFactory; @@ -23,7 +23,7 @@ * auto-configured RabbitMQ {@link ConnectionFactory}. * * @author Andy Wilkinson - * @since 2.5.0 + * @since 4.0.0 */ @FunctionalInterface public interface ConnectionFactoryCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/DirectRabbitListenerContainerFactoryConfigurer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/DirectRabbitListenerContainerFactoryConfigurer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java index 0e29f481f17a..ef909b877a81 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/DirectRabbitListenerContainerFactoryConfigurer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/DirectRabbitListenerContainerFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; @@ -30,7 +30,7 @@ * * @author Gary Russell * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public final class DirectRabbitListenerContainerFactoryConfigurer extends AbstractRabbitListenerContainerFactoryConfigurer { @@ -38,7 +38,6 @@ public final class DirectRabbitListenerContainerFactoryConfigurer /** * Creates a new configurer that will use the given {@code rabbitProperties}. * @param rabbitProperties properties to use - * @since 2.6.0 */ public DirectRabbitListenerContainerFactoryConfigurer(RabbitProperties rabbitProperties) { super(rabbitProperties); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/EnvironmentBuilderCustomizer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/EnvironmentBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/EnvironmentBuilderCustomizer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/EnvironmentBuilderCustomizer.java index 2145ef4a9d19..74cccaca41c1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/EnvironmentBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/EnvironmentBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import com.rabbitmq.stream.Environment; import com.rabbitmq.stream.EnvironmentBuilder; @@ -24,7 +24,7 @@ * auto-configured {@link Environment} that is created by an {@link EnvironmentBuilder}. * * @author Andy Wilkinson - * @since 3.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface EnvironmentBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/PropertiesRabbitConnectionDetails.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetails.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/PropertiesRabbitConnectionDetails.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetails.java index 23108cd74346..23135fd3516e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/PropertiesRabbitConnectionDetails.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetails.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.util.ArrayList; import java.util.List; -import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Ssl; +import org.springframework.boot.amqp.autoconfigure.RabbitProperties.Ssl; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; import org.springframework.util.Assert; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java index 785986c74818..a8a07f794187 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAnnotationDrivenConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import org.springframework.amqp.rabbit.annotation.EnableRabbit; import org.springframework.amqp.rabbit.config.ContainerCustomizer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java index 71a2d7561864..8780f1db85df 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import com.rabbitmq.client.Channel; import com.rabbitmq.client.impl.CredentialsProvider; @@ -71,7 +71,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Scott Frederick - * @since 1.0.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ RabbitTemplate.class, Channel.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitConnectionDetails.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitConnectionDetails.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionDetails.java index 3e0ec7067a4f..2783e397097c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitConnectionDetails.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.util.List; @@ -28,7 +28,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface RabbitConnectionDetails extends ConnectionDetails { @@ -77,7 +77,6 @@ default Address getFirstAddress() { /** * SSL bundle to use. * @return the SSL bundle to use - * @since 3.5.0 */ default SslBundle getSslBundle() { return null; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitConnectionFactoryBeanConfigurer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitConnectionFactoryBeanConfigurer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java index fb7df7237897..5ff9f055db6f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitConnectionFactoryBeanConfigurer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitConnectionFactoryBeanConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.time.Duration; @@ -22,7 +22,7 @@ import com.rabbitmq.client.impl.CredentialsRefreshService; import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean; -import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails.Address; +import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; @@ -43,7 +43,7 @@ * @author Andy Wilkinson * @author Phillip Webb * @author Scott Frederick - * @since 2.6.0 + * @since 4.0.0 */ public class RabbitConnectionFactoryBeanConfigurer { @@ -74,7 +74,6 @@ public RabbitConnectionFactoryBeanConfigurer(ResourceLoader resourceLoader, Rabb * @param resourceLoader the resource loader * @param properties the properties * @param connectionDetails the connection details - * @since 3.1.0 */ public RabbitConnectionFactoryBeanConfigurer(ResourceLoader resourceLoader, RabbitProperties properties, RabbitConnectionDetails connectionDetails) { @@ -89,7 +88,6 @@ public RabbitConnectionFactoryBeanConfigurer(ResourceLoader resourceLoader, Rabb * @param properties the properties * @param connectionDetails the connection details * @param sslBundles the SSL bundles - * @since 3.2.0 */ public RabbitConnectionFactoryBeanConfigurer(ResourceLoader resourceLoader, RabbitProperties properties, RabbitConnectionDetails connectionDetails, SslBundles sslBundles) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitProperties.java index 5cc04de9c839..7a954d002c3c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -48,7 +48,7 @@ * @author Scott Frederick * @author Lasse Wulff * @author Yanming Zhou - * @since 1.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.rabbitmq") public class RabbitProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitRetryTemplateCustomizer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitRetryTemplateCustomizer.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitRetryTemplateCustomizer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitRetryTemplateCustomizer.java index 9e15fd2ad2ef..edd70c17a44d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitRetryTemplateCustomizer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitRetryTemplateCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer; @@ -25,7 +25,7 @@ * of the Rabbit infrastructure. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface RabbitRetryTemplateCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamConfiguration.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamConfiguration.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfiguration.java index c5d0778a563e..f59f0461c47f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamConfiguration.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.util.function.Function; import java.util.function.Supplier; @@ -25,7 +25,7 @@ import org.springframework.amqp.rabbit.config.ContainerCustomizer; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.amqp.RabbitProperties.StreamContainer; +import org.springframework.boot.amqp.autoconfigure.RabbitProperties.StreamContainer; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamTemplateConfigurer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamTemplateConfigurer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamTemplateConfigurer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamTemplateConfigurer.java index d875683ea3c3..58f2b9a2cf68 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamTemplateConfigurer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamTemplateConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.rabbit.stream.producer.ProducerCustomizer; @@ -29,7 +29,7 @@ * auto-configuration. * * @author Eddú Meléndez - * @since 2.7.0 + * @since 4.0.0 */ public class RabbitStreamTemplateConfigurer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitTemplateConfigurer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateConfigurer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitTemplateConfigurer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateConfigurer.java index 968566469325..2273e1d85859 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitTemplateConfigurer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.time.Duration; import java.util.List; @@ -38,7 +38,7 @@ * * @author Stephane Nicoll * @author Yanming Zhou - * @since 2.3.0 + * @since 4.0.0 */ public class RabbitTemplateConfigurer { @@ -51,7 +51,6 @@ public class RabbitTemplateConfigurer { /** * Creates a new configurer that will use the given {@code rabbitProperties}. * @param rabbitProperties properties to use - * @since 2.6.0 */ public RabbitTemplateConfigurer(RabbitProperties rabbitProperties) { Assert.notNull(rabbitProperties, "'rabbitProperties' must not be null"); @@ -62,7 +61,6 @@ public RabbitTemplateConfigurer(RabbitProperties rabbitProperties) { * Set the {@link MessageConverter} to use or {@code null} if the out-of-the-box * converter should be used. * @param messageConverter the {@link MessageConverter} - * @since 2.6.0 */ public void setMessageConverter(MessageConverter messageConverter) { this.messageConverter = messageConverter; @@ -71,7 +69,6 @@ public void setMessageConverter(MessageConverter messageConverter) { /** * Set the {@link RabbitRetryTemplateCustomizer} instances to use. * @param retryTemplateCustomizers the retry template customizers - * @since 2.6.0 */ public void setRetryTemplateCustomizers(List retryTemplateCustomizers) { this.retryTemplateCustomizers = retryTemplateCustomizers; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitTemplateCustomizer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitTemplateCustomizer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateCustomizer.java index db6cc6d92cf5..9015fa8ca49d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitTemplateCustomizer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RabbitTemplateCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import org.springframework.amqp.rabbit.core.RabbitTemplate; @@ -22,7 +22,7 @@ * Callback interface that can be used to customize a {@link RabbitTemplate}. * * @author dang zhicairang - * @since 3.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface RabbitTemplateCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RetryTemplateFactory.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RetryTemplateFactory.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RetryTemplateFactory.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RetryTemplateFactory.java index 95e9889ee1f4..577233599a45 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RetryTemplateFactory.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/RetryTemplateFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.time.Duration; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SimpleRabbitListenerContainerFactoryConfigurer.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SimpleRabbitListenerContainerFactoryConfigurer.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java index 7f8841b706a6..b9be211d6a31 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SimpleRabbitListenerContainerFactoryConfigurer.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SimpleRabbitListenerContainerFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; @@ -30,7 +30,7 @@ * * @author Stephane Nicoll * @author Gary Russell - * @since 1.3.3 + * @since 4.0.0 */ public final class SimpleRabbitListenerContainerFactoryConfigurer extends AbstractRabbitListenerContainerFactoryConfigurer { @@ -38,7 +38,6 @@ public final class SimpleRabbitListenerContainerFactoryConfigurer /** * Creates a new configurer that will use the given {@code rabbitProperties}. * @param rabbitProperties properties to use - * @since 2.6.0 */ public SimpleRabbitListenerContainerFactoryConfigurer(RabbitProperties rabbitProperties) { super(rabbitProperties); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SslBundleRabbitConnectionFactoryBean.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SslBundleRabbitConnectionFactoryBean.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SslBundleRabbitConnectionFactoryBean.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SslBundleRabbitConnectionFactoryBean.java index af71c00c63ff..243938c1de9d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SslBundleRabbitConnectionFactoryBean.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/SslBundleRabbitConnectionFactoryBean.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean; import org.springframework.boot.ssl.SslBundle; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java similarity index 76% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java index 9e8ccdd6b14f..689e176dc306 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfiguration.java @@ -14,30 +14,30 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure.health; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.amqp.RabbitHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; +import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.amqp.health.RabbitHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; import org.springframework.context.annotation.Bean; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link RabbitHealthIndicator}. * * @author Christian Dupuis - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = RabbitAutoConfiguration.class) -@ConditionalOnClass(RabbitTemplate.class) +@ConditionalOnClass({ RabbitHealthIndicator.class, RabbitTemplate.class, ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(RabbitTemplate.class) @ConditionalOnEnabledHealthIndicator("rabbit") public class RabbitHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..6eaf5d43bd10 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for RabbitMQ health. + */ +package org.springframework.boot.amqp.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitConnectionFactoryMetricsPostProcessor.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitConnectionFactoryMetricsPostProcessor.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java index 9975d7af4ff9..651a451cc7d2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitConnectionFactoryMetricsPostProcessor.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitConnectionFactoryMetricsPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.amqp; +package org.springframework.boot.amqp.autoconfigure.metrics; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.MetricsCollector; @@ -23,7 +23,7 @@ import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory; import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.actuate.metrics.amqp.RabbitMetrics; +import org.springframework.boot.amqp.metrics.RabbitMetrics; import org.springframework.context.ApplicationContext; import org.springframework.core.Ordered; import org.springframework.util.StringUtils; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java similarity index 78% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java index 50382517074a..b5bd5ed3bf29 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfiguration.java @@ -14,17 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.amqp; +package org.springframework.boot.amqp.autoconfigure.metrics; import com.rabbitmq.client.ConnectionFactory; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; +import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.ApplicationContext; @@ -35,11 +33,11 @@ * {@link ConnectionFactory connection factories}. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, RabbitAutoConfiguration.class, - SimpleMetricsExportAutoConfiguration.class }) -@ConditionalOnClass({ ConnectionFactory.class, AbstractConnectionFactory.class }) +@AutoConfiguration(afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration", + after = RabbitAutoConfiguration.class) +@ConditionalOnClass({ ConnectionFactory.class, AbstractConnectionFactory.class, MeterRegistry.class }) @ConditionalOnBean({ org.springframework.amqp.rabbit.connection.ConnectionFactory.class, MeterRegistry.class }) public class RabbitMetricsAutoConfiguration { diff --git a/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..7e04a5a18be5 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for RabbitMQ metrics. + */ +package org.springframework.boot.amqp.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/package-info.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/package-info.java new file mode 100644 index 000000000000..2bc9284570c1 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for RabbitMQ. + */ +package org.springframework.boot.amqp.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java index a52c81bf68fd..7f8583f18da6 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitDockerComposeConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.rabbit; +package org.springframework.boot.amqp.docker.compose; import java.util.List; -import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails; +import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitEnvironment.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironment.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitEnvironment.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironment.java index ac2b50d789fa..ad3b5564f48d 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitEnvironment.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.rabbit; +package org.springframework.boot.amqp.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/package-info.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/package-info.java new file mode 100644 index 000000000000..df1e3ade8b7e --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose RabbitMQ service connections. + */ +package org.springframework.boot.amqp.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/amqp/RabbitHealthIndicator.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/RabbitHealthIndicator.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/amqp/RabbitHealthIndicator.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/RabbitHealthIndicator.java index 5d3351da2cc9..8f0b9a911652 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/amqp/RabbitHealthIndicator.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/RabbitHealthIndicator.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.amqp; +package org.springframework.boot.amqp.health; import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.util.Assert; /** @@ -27,7 +27,7 @@ * RabbitMQ messaging system. * * @author Christian Dupuis - * @since 1.1.0 + * @since 4.0.0 */ public class RabbitHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/package-info.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/package-info.java new file mode 100644 index 000000000000..cacab20fb2a9 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for AMQP and RabbitMQ. + */ +package org.springframework.boot.amqp.health; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetrics.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/RabbitMetrics.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetrics.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/RabbitMetrics.java index 30c17d2c18b9..799e01950387 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetrics.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/RabbitMetrics.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.amqp; +package org.springframework.boot.amqp.metrics; import java.util.Collections; @@ -31,7 +31,7 @@ * * @author Arnaud Cogoluègnes * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public class RabbitMetrics implements MeterBinder { diff --git a/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/package-info.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/package-info.java new file mode 100644 index 000000000000..645c30fb49b5 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Metrics for AMQP and RabbitMQ. + */ +package org.springframework.boot.amqp.metrics; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/amqp/RabbitContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/amqp/RabbitContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactory.java index cd194ac3cd42..54702a1e9c24 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/amqp/RabbitContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/testcontainers/RabbitContainerConnectionDetailsFactory.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.amqp; +package org.springframework.boot.amqp.testcontainers; import java.net.URI; import java.util.List; import org.testcontainers.containers.RabbitMQContainer; -import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails; +import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; diff --git a/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/testcontainers/package-info.java b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/testcontainers/package-info.java new file mode 100644 index 000000000000..f4eed1ef104e --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/java/org/springframework/boot/amqp/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers RabbitMQ service connections. + */ +package org.springframework.boot.amqp.testcontainers; diff --git a/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..6624bfce5c66 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,39 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.health.rabbit.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable RabbitMQ health check.", + "defaultValue": true + }, + { + "name": "spring.rabbitmq.dynamic", + "type": "java.lang.Boolean", + "description": "Whether to create an AmqpAdmin bean.", + "defaultValue": true + }, + { + "name": "spring.rabbitmq.listener.simple.transaction-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.rabbitmq.publisher-confirms", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.rabbitmq.template.queue", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.rabbitmq.template.default-receive-queue", + "level": "error" + } + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..412b6813fab6 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.amqp.docker.compose.RabbitDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.amqp.testcontainers.RabbitContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..daf8ae3ba45f --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration +org.springframework.boot.amqp.autoconfigure.health.RabbitHealthContributorAutoConfiguration +org.springframework.boot.amqp.autoconfigure.metrics.RabbitMetricsAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/PropertiesRabbitConnectionDetailsTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetailsTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/PropertiesRabbitConnectionDetailsTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetailsTests.java index 3ad9223eee21..fb37bd6f2712 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/PropertiesRabbitConnectionDetailsTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/PropertiesRabbitConnectionDetailsTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails.Address; +import org.springframework.boot.amqp.autoconfigure.RabbitConnectionDetails.Address; import org.springframework.boot.ssl.DefaultSslBundleRegistry; import org.springframework.boot.ssl.SslBundle; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java index ba743efef553..56f57061096e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.security.NoSuchAlgorithmException; import java.util.Collection; @@ -910,7 +910,7 @@ void enableSslWithInvalidTrustStoreTypeShouldFail() { void enableSslWithBundle() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.bundle=test-bundle", - "spring.ssl.bundle.jks.test-bundle.keystore.location=classpath:org/springframework/boot/autoconfigure/amqp/test.jks", + "spring.ssl.bundle.jks.test-bundle.keystore.location=classpath:org/springframework/boot/amqp/autoconfigure/test.jks", "spring.ssl.bundle.jks.test-bundle.keystore.password=secret") .run((context) -> { com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(context); @@ -922,9 +922,9 @@ void enableSslWithBundle() { void enableSslWithKeystoreTypeAndTrustStoreTypeShouldWork() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.enabled:true", - "spring.rabbitmq.ssl.key-store=/org/springframework/boot/autoconfigure/amqp/test.jks", + "spring.rabbitmq.ssl.key-store=/org/springframework/boot/amqp/autoconfigure/test.jks", "spring.rabbitmq.ssl.key-store-type=jks", "spring.rabbitmq.ssl.key-store-password=secret", - "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/autoconfigure/amqp/test.jks", + "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/amqp/autoconfigure/test.jks", "spring.rabbitmq.ssl.trust-store-type=jks", "spring.rabbitmq.ssl.trust-store-password=secret") .run((context) -> assertThat(context).hasNotFailed()); } @@ -956,10 +956,10 @@ void enableSslWithValidateServerCertificateDefault(CapturedOutput output) { void enableSslWithValidStoreAlgorithmShouldWork() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.enabled:true", - "spring.rabbitmq.ssl.key-store=/org/springframework/boot/autoconfigure/amqp/test.jks", + "spring.rabbitmq.ssl.key-store=/org/springframework/boot/amqp/autoconfigure/test.jks", "spring.rabbitmq.ssl.key-store-type=jks", "spring.rabbitmq.ssl.key-store-password=secret", "spring.rabbitmq.ssl.key-store-algorithm=PKIX", - "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/autoconfigure/amqp/test.jks", + "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/amqp/autoconfigure/test.jks", "spring.rabbitmq.ssl.trust-store-type=jks", "spring.rabbitmq.ssl.trust-store-password=secret", "spring.rabbitmq.ssl.trust-store-algorithm=PKIX") .run((context) -> assertThat(context).hasNotFailed()); @@ -969,7 +969,7 @@ void enableSslWithValidStoreAlgorithmShouldWork() { void enableSslWithInvalidKeyStoreAlgorithmShouldFail() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.enabled:true", - "spring.rabbitmq.ssl.key-store=/org/springframework/boot/autoconfigure/amqp/test.jks", + "spring.rabbitmq.ssl.key-store=/org/springframework/boot/amqp/autoconfigure/test.jks", "spring.rabbitmq.ssl.key-store-type=jks", "spring.rabbitmq.ssl.key-store-password=secret", "spring.rabbitmq.ssl.key-store-algorithm=test-invalid-algo") .run((context) -> { @@ -983,7 +983,7 @@ void enableSslWithInvalidKeyStoreAlgorithmShouldFail() { void enableSslWithInvalidTrustStoreAlgorithmShouldFail() { this.contextRunner.withUserConfiguration(TestConfiguration.class) .withPropertyValues("spring.rabbitmq.ssl.enabled:true", - "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/autoconfigure/amqp/test.jks", + "spring.rabbitmq.ssl.trust-store=/org/springframework/boot/amqp/autoconfigure/test.jks", "spring.rabbitmq.ssl.trust-store-type=jks", "spring.rabbitmq.ssl.trust-store-password=secret", "spring.rabbitmq.ssl.trust-store-algorithm=test-invalid-algo") .run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitPropertiesTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitPropertiesTests.java index 54bfb6985bf9..cc3f17a5a802 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamConfigurationTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamConfigurationTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java index 4e876a95ff73..27bbc9918845 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitStreamConfigurationTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/RabbitStreamConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure; import java.time.Duration; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java index a20f77a0c6d3..8739399d0aae 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/health/RabbitHealthContributorAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.amqp; +package org.springframework.boot.amqp.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.amqp.RabbitHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; +import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.amqp.health.RabbitHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java new file mode 100644 index 000000000000..76c0f82e5987 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests.java @@ -0,0 +1,77 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.amqp.autoconfigure.metrics; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; + +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test to check that {@link RabbitMetricsAutoConfiguration} does not cause a + * dependency cycle when used with {@link MeterBinder}. + * + * @author Phillip Webb + * @see gh-30636 + */ +class RabbitMetricsAutoConfigurationMeterBinderCycleIntegrationTests { + + @Test + void doesNotFormCycle() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class); + TestService testService = context.getBean(TestService.class); + context.close(); + assertThat(testService.bound).isTrue(); + } + + @Configuration + @Import({ TestService.class, RabbitAutoConfiguration.class, MetricsAutoConfiguration.class, + RabbitMetricsAutoConfiguration.class }) + static class TestConfig { + + @Bean + SimpleMeterRegistry meterRegistry() { + return new SimpleMeterRegistry(); + } + + } + + static class TestService implements MeterBinder { + + private boolean bound; + + TestService(RabbitTemplate rabbitTemplate) { + } + + @Override + public void bindTo(MeterRegistry registry) { + this.bound = true; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java index 01c3b9c59272..fea709700fc0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/amqp/RabbitMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/autoconfigure/metrics/RabbitMetricsAutoConfigurationTests.java @@ -14,16 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.amqp; +package org.springframework.boot.amqp.autoconfigure.metrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; +import org.springframework.boot.amqp.autoconfigure.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -37,8 +38,11 @@ */ class RabbitMetricsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class, RabbitMetricsAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class) + .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class, RabbitMetricsAutoConfiguration.class, + MetricsAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=false"); @Test void autoConfiguredConnectionFactoryIsInstrumented() { diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitEnvironmentTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java similarity index 96% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitEnvironmentTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java index 3dbb3e5a52a5..1ecb0b4d6ff4 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/rabbit/RabbitEnvironmentTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/docker/compose/RabbitEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.rabbit; +package org.springframework.boot.amqp.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/amqp/RabbitHealthIndicatorTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/health/RabbitHealthIndicatorTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/amqp/RabbitHealthIndicatorTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/health/RabbitHealthIndicatorTests.java index 93b70088fa75..780f68260099 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/amqp/RabbitHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/health/RabbitHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.amqp; +package org.springframework.boot.amqp.health; import java.util.Collections; @@ -27,8 +27,8 @@ import org.springframework.amqp.rabbit.core.ChannelCallback; import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetricsTests.java b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/metrics/RabbitMetricsTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetricsTests.java rename to spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/metrics/RabbitMetricsTests.java index 72f32a711d0c..780de803e4f6 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetricsTests.java +++ b/spring-boot-project/spring-boot-amqp/src/test/java/org/springframework/boot/amqp/metrics/RabbitMetricsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.amqp; +package org.springframework.boot.amqp.metrics; import com.rabbitmq.client.ConnectionFactory; import io.micrometer.core.instrument.Tags; diff --git a/spring-boot-project/spring-boot-amqp/src/test/resources/logback-test.xml b/spring-boot-project/spring-boot-amqp/src/test/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-amqp/src/test/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/amqp/test.jks b/spring-boot-project/spring-boot-amqp/src/test/resources/org/springframework/boot/amqp/autoconfigure/test.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/amqp/test.jks rename to spring-boot-project/spring-boot-amqp/src/test/resources/org/springframework/boot/amqp/autoconfigure/test.jks diff --git a/spring-boot-project/spring-boot-artemis/build.gradle b/spring-boot-project/spring-boot-artemis/build.gradle new file mode 100644 index 000000000000..8370137e3be9 --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/build.gradle @@ -0,0 +1,52 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Artemis" + +dependencies { + api(project(":spring-boot-project:spring-boot-jms")) + api("org.apache.activemq:artemis-jakarta-client") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional(project(":spring-boot-project:spring-boot-tx")) + optional("org.apache.activemq:artemis-jakarta-server") + optional("org.messaginghub:pooled-jms") { + exclude group: "org.apache.geronimo.specs", module: "geronimo-jms_2.0_spec" + } + optional("org.testcontainers:activemq") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("ch.qos.logback:logback-classic") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-artemis/src/dockerTest/java/org/springframework/boot/artemis/docker/compose/ArtemisDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 86% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-artemis/src/dockerTest/java/org/springframework/boot/artemis/docker/compose/ArtemisDockerComposeConnectionDetailsFactoryIntegrationTests.java index 54b75fb28bdb..a06c69aa6b77 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-artemis/src/dockerTest/java/org/springframework/boot/artemis/docker/compose/ArtemisDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.artemis.docker.compose; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConnectionDetails; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisMode; +import org.springframework.boot.artemis.autoconfigure.ArtemisConnectionDetails; +import org.springframework.boot.artemis.autoconfigure.ArtemisMode; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ArtemisContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-artemis/src/dockerTest/java/org/springframework/boot/artemis/testcontainers/ArtemisContainerConnectionDetailsFactoryIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ArtemisContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-artemis/src/dockerTest/java/org/springframework/boot/artemis/testcontainers/ArtemisContainerConnectionDetailsFactoryIntegrationTests.java index ae66a47b8b73..73a1134f9c06 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/activemq/ArtemisContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-artemis/src/dockerTest/java/org/springframework/boot/artemis/testcontainers/ArtemisContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.activemq; +package org.springframework.boot.artemis.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -27,9 +27,9 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.artemis.autoconfigure.ArtemisAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-artemis/src/dockerTest/resources/org/springframework/boot/artemis/docker/compose/artemis-compose.yaml b/spring-boot-project/spring-boot-artemis/src/dockerTest/resources/org/springframework/boot/artemis/docker/compose/artemis-compose.yaml new file mode 100644 index 000000000000..c9ea82fbadd4 --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/src/dockerTest/resources/org/springframework/boot/artemis/docker/compose/artemis-compose.yaml @@ -0,0 +1,8 @@ +services: + artemis: + image: '{imageName}' + ports: + - '61616' + environment: + ARTEMIS_USER: 'root' + ARTEMIS_PASSWORD: 'secret' diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfiguration.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisAutoConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfiguration.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisAutoConfiguration.java index aafb1931d106..9a8dafd2dd89 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfiguration.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import jakarta.jms.ConnectionFactory; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; @@ -23,10 +23,11 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.JmsProperties; -import org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration; +import org.springframework.boot.jms.autoconfigure.JmsProperties; +import org.springframework.boot.jms.autoconfigure.JndiConnectionFactoryAutoConfiguration; +import org.springframework.boot.transaction.jta.autoconfigure.JtaAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -38,10 +39,11 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 * @see ArtemisProperties */ -@AutoConfiguration(before = JmsAutoConfiguration.class, after = JndiConnectionFactoryAutoConfiguration.class) +@AutoConfiguration(before = JmsAutoConfiguration.class, + after = { JndiConnectionFactoryAutoConfiguration.class, JtaAutoConfiguration.class }) @ConditionalOnClass({ ConnectionFactory.class, ActiveMQConnectionFactory.class }) @ConditionalOnMissingBean(ConnectionFactory.class) @EnableConfigurationProperties({ ArtemisProperties.class, JmsProperties.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConfigurationCustomizer.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConfigurationCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConfigurationCustomizer.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConfigurationCustomizer.java index 3f89d43626cd..952bd3a55681 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConfigurationCustomizer.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConfigurationCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import org.apache.activemq.artemis.core.config.Configuration; import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; @@ -26,7 +26,7 @@ * * @author Eddú Meléndez * @author Phillip Webb - * @since 1.3.0 + * @since 4.0.0 * @see ArtemisAutoConfiguration */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionDetails.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionDetails.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionDetails.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionDetails.java index 0232e24cd1a0..c021a20bf050 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionDetails.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; @@ -22,7 +22,7 @@ * Details required to establish a connection to an Artemis service. * * @author Eddú Meléndez - * @since 3.3.0 + * @since 4.0.0 */ public interface ArtemisConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryConfiguration.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionFactoryConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryConfiguration.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionFactoryConfiguration.java index d449d3cce468..7bf9edaeb456 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionFactoryConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import jakarta.jms.ConnectionFactory; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; @@ -25,8 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryFactory; -import org.springframework.boot.autoconfigure.jms.JmsProperties; +import org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryFactory; +import org.springframework.boot.jms.autoconfigure.JmsProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.connection.CachingConnectionFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryFactory.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionFactoryFactory.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryFactory.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionFactoryFactory.java index 48fc5fceb523..16a322194bbf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryFactory.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisConnectionFactoryFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import java.util.function.Function; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedConfigurationFactory.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedConfigurationFactory.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedConfigurationFactory.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedConfigurationFactory.java index c815445d0abd..4041e9177b87 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedConfigurationFactory.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedConfigurationFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import java.io.File; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedServerConfiguration.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedServerConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedServerConfiguration.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedServerConfiguration.java index dfc35c17c715..d7ea0625625b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedServerConfiguration.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedServerConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import org.apache.activemq.artemis.api.core.QueueConfiguration; import org.apache.activemq.artemis.api.core.RoutingType; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisMode.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisMode.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisMode.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisMode.java index db49b7acb2c5..23c4344fbdde 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisMode.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisMode.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; /** * Define the mode in which Artemis can operate. * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ public enum ArtemisMode { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisNoOpBindingRegistry.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisNoOpBindingRegistry.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisNoOpBindingRegistry.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisNoOpBindingRegistry.java index 005e41750a44..3107050c225c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisNoOpBindingRegistry.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisNoOpBindingRegistry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import org.apache.activemq.artemis.spi.core.naming.BindingRegistry; @@ -23,7 +23,7 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ public class ArtemisNoOpBindingRegistry implements BindingRegistry { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisProperties.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisProperties.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisProperties.java index 9779fd5987f5..0ba3e2003139 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisProperties.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import java.util.HashMap; import java.util.Map; @@ -23,9 +23,9 @@ import org.apache.activemq.artemis.core.remoting.impl.invm.TransportConstants; -import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; +import org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties; /** * Configuration properties for Artemis. @@ -33,7 +33,7 @@ * @author Eddú Meléndez * @author Stephane Nicoll * @author Justin Bertram - * @since 1.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.artemis") public class ArtemisProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisXAConnectionFactoryConfiguration.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisXAConnectionFactoryConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisXAConnectionFactoryConfiguration.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisXAConnectionFactoryConfiguration.java index ab1d56a3a57e..53911de6dfb3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisXAConnectionFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/ArtemisXAConnectionFactoryConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import jakarta.jms.ConnectionFactory; import jakarta.transaction.TransactionManager; diff --git a/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/package-info.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/package-info.java new file mode 100644 index 000000000000..60dcdbaf31ab --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/autoconfigure/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Artemis. + * + * @author Eddú Meléndez + */ +package org.springframework.boot.artemis.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/ArtemisDockerComposeConnectionDetailsFactory.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/ArtemisDockerComposeConnectionDetailsFactory.java index 1d668c0010d3..4e491ecdcf35 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/ArtemisDockerComposeConnectionDetailsFactory.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.artemis.docker.compose; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConnectionDetails; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisMode; +import org.springframework.boot.artemis.autoconfigure.ArtemisConnectionDetails; +import org.springframework.boot.artemis.autoconfigure.ArtemisMode; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisEnvironment.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/ArtemisEnvironment.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisEnvironment.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/ArtemisEnvironment.java index c2ef7cff06b5..77791b5823e2 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisEnvironment.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/ArtemisEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.artemis.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/package-info.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/package-info.java new file mode 100644 index 000000000000..dd415333e261 --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Artemis service connections. + */ +package org.springframework.boot.artemis.docker.compose; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ArtemisContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/testcontainers/ArtemisContainerConnectionDetailsFactory.java similarity index 90% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ArtemisContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/testcontainers/ArtemisContainerConnectionDetailsFactory.java index c4f55082512f..9e46128521c9 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/ArtemisContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/testcontainers/ArtemisContainerConnectionDetailsFactory.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.activemq; +package org.springframework.boot.artemis.testcontainers; import org.testcontainers.activemq.ArtemisContainer; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConnectionDetails; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisMode; +import org.springframework.boot.artemis.autoconfigure.ArtemisConnectionDetails; +import org.springframework.boot.artemis.autoconfigure.ArtemisMode; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/testcontainers/package-info.java b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/testcontainers/package-info.java new file mode 100644 index 000000000000..8a4006e9b94a --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/src/main/java/org/springframework/boot/artemis/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Artemis service connections. + */ +package org.springframework.boot.artemis.testcontainers; diff --git a/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..347468889031 --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,87 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.artemis.broker-url", + "defaultValue": "tcp://localhost:61616" + }, + { + "name": "spring.artemis.host", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.artemis.broker-url", + "level": "error" + } + }, + { + "name": "spring.artemis.pool.block-if-full", + "type": "java.lang.Boolean", + "description": "Whether to block when a connection is requested and the pool is full. Set it to false to throw a \"JMSException\" instead.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": true + }, + { + "name": "spring.artemis.pool.block-if-full-timeout", + "type": "java.time.Duration", + "description": "Blocking period before throwing an exception if the pool is still full.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": "-1ms" + }, + { + "name": "spring.artemis.pool.enabled", + "type": "java.lang.Boolean", + "description": "Whether a JmsPoolConnectionFactory should be created, instead of a regular ConnectionFactory.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": false + }, + { + "name": "spring.artemis.pool.idle-timeout", + "type": "java.time.Duration", + "description": "Connection idle timeout.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": "30s" + }, + { + "name": "spring.artemis.pool.max-connections", + "type": "java.lang.Integer", + "description": "Maximum number of pooled connections.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": 1 + }, + { + "name": "spring.artemis.pool.max-sessions-per-connection", + "type": "java.lang.Integer", + "description": "Maximum number of pooled sessions per connection in the pool.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": 500 + }, + { + "name": "spring.artemis.pool.maximum-active-session-per-connection", + "deprecation": { + "replacement": "spring.artemis.pool.max-sessions-per-connection" + } + }, + { + "name": "spring.artemis.pool.time-between-expiration-check", + "type": "java.time.Duration", + "description": "Time to sleep between runs of the idle connection eviction thread. When negative, no idle connection eviction thread runs.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": "-1ms" + }, + { + "name": "spring.artemis.pool.use-anonymous-producers", + "type": "java.lang.Boolean", + "description": "Whether to use only one anonymous \"MessageProducer\" instance. Set it to false to create one \"MessageProducer\" every time one is required.", + "sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties", + "defaultValue": true + }, + { + "name": "spring.artemis.port", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.artemis.broker-url", + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..b664209f84b5 --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.artemis.docker.compose.ArtemisDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.artemis.testcontainers.ArtemisContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..deda68fed4fb --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.artemis.autoconfigure.ArtemisAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java b/spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/autoconfigure/ArtemisAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java rename to spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/autoconfigure/ArtemisAutoConfigurationTests.java index f5d2c4bbefd0..3481fb690bdf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/autoconfigure/ArtemisAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import java.io.File; import java.io.IOException; @@ -46,9 +46,9 @@ import org.junit.jupiter.api.io.TempDir; import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; +import org.springframework.boot.artemis.autoconfigure.ArtemisAutoConfiguration.PropertiesArtemisConnectionDetails; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration.PropertiesArtemisConnectionDetails; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedConfigurationFactoryTests.java b/spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedConfigurationFactoryTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedConfigurationFactoryTests.java rename to spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedConfigurationFactoryTests.java index c5e47ff9862f..b04ef78965cf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedConfigurationFactoryTests.java +++ b/spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/autoconfigure/ArtemisEmbeddedConfigurationFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.artemis; +package org.springframework.boot.artemis.autoconfigure; import java.util.List; import java.util.Map; diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisEnvironmentTests.java b/spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/docker/compose/ArtemisEnvironmentTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisEnvironmentTests.java rename to spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/docker/compose/ArtemisEnvironmentTests.java index 57c1e43f75f5..fe3e9008da71 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/activemq/ArtemisEnvironmentTests.java +++ b/spring-boot-project/spring-boot-artemis/src/test/java/org/springframework/boot/artemis/docker/compose/ArtemisEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.activemq; +package org.springframework.boot.artemis.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-artemis/src/test/resources/logback-test.xml b/spring-boot-project/spring-boot-artemis/src/test/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-artemis/src/test/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index de6442be48eb..aad64e959d02 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -16,270 +16,42 @@ plugins { id "java-library" + id "java-test-fixtures" id "org.springframework.boot.auto-configuration" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.deployed" - id "org.springframework.boot.docker-test" id "org.springframework.boot.optional-dependencies" } description = "Spring Boot AutoConfigure" -configurations.all { - resolutionStrategy.eachDependency { DependencyResolveDetails details -> - if (details.requested.module.group == "org.apache.kafka" && details.requested.module.name == "kafka-server-common") { - details.artifactSelection { - selectArtifact(DependencyArtifact.DEFAULT_TYPE, null, null) - } - } - } -} - dependencies { api(project(":spring-boot-project:spring-boot")) - dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) - dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) - dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot"))) - dockerTestImplementation("com.redis:testcontainers-redis") - dockerTestImplementation("org.assertj:assertj-core") - dockerTestImplementation("org.awaitility:awaitility") - dockerTestImplementation("org.junit.jupiter:junit-jupiter") - dockerTestImplementation("org.mockito:mockito-core") - dockerTestImplementation("org.springframework:spring-test") - dockerTestImplementation("org.testcontainers:cassandra") - dockerTestImplementation("org.testcontainers:couchbase") - dockerTestImplementation("org.testcontainers:elasticsearch") - dockerTestImplementation("org.testcontainers:junit-jupiter") - dockerTestImplementation("org.testcontainers:mongodb") - dockerTestImplementation("org.testcontainers:neo4j") - dockerTestImplementation("org.testcontainers:pulsar") - dockerTestImplementation("org.testcontainers:testcontainers") - - optional("co.elastic.clients:elasticsearch-java") - optional("com.fasterxml.jackson.core:jackson-databind") - optional("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor") - optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml") - optional("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") - optional("com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations") - optional("com.fasterxml.jackson.module:jackson-module-parameter-names") - optional("com.google.code.gson:gson") - optional("com.hazelcast:hazelcast") - optional("com.hazelcast:hazelcast-spring") - optional("com.h2database:h2") - optional("com.nimbusds:oauth2-oidc-sdk") - optional("com.oracle.database.jdbc:ojdbc11") - optional("com.oracle.database.jdbc:ucp11") - optional("com.querydsl:querydsl-core") - optional("com.samskivert:jmustache") - optional("io.lettuce:lettuce-core") - optional("io.projectreactor.netty:reactor-netty-http") - optional("io.r2dbc:r2dbc-spi") - optional("io.r2dbc:r2dbc-pool") - optional("io.r2dbc:r2dbc-proxy") - optional("io.rsocket:rsocket-core") - optional("io.rsocket:rsocket-transport-netty") - optional("io.undertow:undertow-servlet") - optional("io.undertow:undertow-websockets-jsr") - optional("jakarta.jms:jakarta.jms-api") - optional("jakarta.mail:jakarta.mail-api") - optional("jakarta.json.bind:jakarta.json.bind-api") - optional("jakarta.persistence:jakarta.persistence-api") - optional("jakarta.transaction:jakarta.transaction-api") - optional("jakarta.validation:jakarta.validation-api") - optional("jakarta.websocket:jakarta.websocket-api") - optional("jakarta.ws.rs:jakarta.ws.rs-api") - optional("javax.cache:cache-api") - optional("javax.money:money-api") - optional("org.apache.activemq:activemq-broker") - optional("org.apache.activemq:activemq-client") - optional("org.apache.activemq:artemis-jakarta-client") - optional("org.apache.activemq:artemis-jakarta-server") - optional("org.apache.commons:commons-dbcp2") - optional("org.apache.httpcomponents.client5:httpclient5") - optional("org.apache.httpcomponents.core5:httpcore5-reactive") - optional("org.apache.kafka:kafka-streams") - optional("org.apache.tomcat.embed:tomcat-embed-core") - optional("org.apache.tomcat.embed:tomcat-embed-el") - optional("org.apache.tomcat.embed:tomcat-embed-websocket") - optional("org.apache.tomcat:tomcat-jdbc") - optional("org.apiguardian:apiguardian-api") - optional("org.apache.groovy:groovy-templates") - optional("org.eclipse.angus:angus-mail") optional("com.github.ben-manes.caffeine:caffeine") - optional("com.github.mxab.thymeleaf.extras:thymeleaf-extras-data-attribute") - optional("com.sendgrid:sendgrid-java") - optional("com.unboundid:unboundid-ldapsdk") - optional("com.zaxxer:HikariCP") - optional("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect") optional("org.aspectj:aspectjweaver") - optional("org.cache2k:cache2k-spring") - optional("org.eclipse.jetty.ee10:jetty-ee10-webapp") - optional("org.eclipse.jetty:jetty-reactive-httpclient") - optional("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server") - optional("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server") - optional("org.ehcache:ehcache") { - artifact { - classifier = 'jakarta' - } - } - optional("org.elasticsearch.client:elasticsearch-rest-client") - optional("org.elasticsearch.client:elasticsearch-rest-client-sniffer") - optional("org.flywaydb:flyway-core") - optional("org.flywaydb:flyway-database-postgresql") - optional("org.flywaydb:flyway-database-oracle") - optional("org.flywaydb:flyway-sqlserver") - optional("org.freemarker:freemarker") - optional("org.glassfish.jersey.containers:jersey-container-servlet-core") - optional("org.glassfish.jersey.containers:jersey-container-servlet") - optional("org.glassfish.jersey.core:jersey-server") - optional("org.glassfish.jersey.ext:jersey-spring6") - optional("org.glassfish.jersey.media:jersey-media-json-jackson") - optional("org.hibernate.orm:hibernate-core") - optional("org.hibernate.orm:hibernate-jcache") - optional("org.hibernate.validator:hibernate-validator") - optional("org.infinispan:infinispan-commons") - optional("org.infinispan:infinispan-component-annotations") - optional("org.infinispan:infinispan-core") - optional("org.infinispan:infinispan-jcache") - optional("org.infinispan:infinispan-spring6-embedded") - optional("org.influxdb:influxdb-java") - optional("org.jooq:jooq") - optional("org.liquibase:liquibase-core") { - exclude group: "javax.xml.bind", module: "jaxb-api" - } - optional("org.messaginghub:pooled-jms") { - exclude group: "org.apache.geronimo.specs", module: "geronimo-jms_2.0_spec" - } - optional("org.mongodb:mongodb-driver-reactivestreams") - optional("org.mongodb:mongodb-driver-sync") - optional("org.opensaml:opensaml-core:4.0.1") - optional("org.opensaml:opensaml-saml-api:4.0.1") - optional("org.opensaml:opensaml-saml-impl:4.0.1") - optional("org.quartz-scheduler:quartz") - optional("org.springframework.integration:spring-integration-core") - optional("org.springframework.integration:spring-integration-jdbc") - optional("org.springframework.integration:spring-integration-jmx") - optional("org.springframework.integration:spring-integration-rsocket") - optional("org.springframework:spring-aspects") - optional("org.springframework:spring-jdbc") - optional("org.springframework:spring-jms") - optional("org.springframework:spring-orm") - optional("org.springframework:spring-tx") + optional("jakarta.persistence:jakarta.persistence-api") + optional("jakarta.servlet:jakarta.servlet-api") + optional("javax.money:money-api") optional("org.springframework:spring-web") - optional("org.springframework:spring-websocket") - optional("org.springframework:spring-webflux") - optional("org.springframework:spring-webmvc") - optional("org.springframework.batch:spring-batch-core") - optional("org.springframework.data:spring-data-couchbase") - optional("org.springframework.data:spring-data-envers") { - exclude group: "javax.activation", module: "javax.activation-api" - exclude group: "javax.persistence", module: "javax.persistence-api" - exclude group: "org.jboss.spec.javax.transaction", module: "jboss-transaction-api_1.2_spec" - } - optional("org.springframework.data:spring-data-jpa") - optional("org.springframework.data:spring-data-rest-webmvc") - optional("org.springframework.data:spring-data-cassandra") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } - optional("org.springframework.data:spring-data-elasticsearch") { - exclude group: "org.elasticsearch.client", module: "transport" - } - optional("org.springframework.data:spring-data-jdbc") - optional("org.springframework.data:spring-data-ldap") - optional("org.springframework.data:spring-data-mongodb") - optional("org.springframework.data:spring-data-neo4j") - optional("org.springframework.data:spring-data-r2dbc") - optional("org.springframework.data:spring-data-redis") - optional("org.springframework.graphql:spring-graphql") - optional("org.springframework.hateoas:spring-hateoas") - optional("org.springframework.pulsar:spring-pulsar") - optional("org.springframework.pulsar:spring-pulsar-reactive") - optional("org.springframework.security:spring-security-acl") - optional("org.springframework.security:spring-security-config") - optional("org.springframework.security:spring-security-data") - optional("org.springframework.security:spring-security-messaging") - optional("org.springframework.security:spring-security-oauth2-authorization-server") - optional("org.springframework.security:spring-security-oauth2-client") - optional("org.springframework.security:spring-security-oauth2-jose") - optional("org.springframework.security:spring-security-oauth2-resource-server") - optional("org.springframework.security:spring-security-rsocket") - optional("org.springframework.security:spring-security-saml2-service-provider") { - exclude group: "org.opensaml", module: "opensaml-core" - exclude group: "org.opensaml", module: "opensaml-saml-api" - exclude group: "org.opensaml", module: "opensaml-saml-impl" - } - optional("org.springframework.security:spring-security-web") - optional("org.springframework.session:spring-session-core") - optional("org.springframework.session:spring-session-data-mongodb") - optional("org.springframework.session:spring-session-data-redis") - optional("org.springframework.session:spring-session-hazelcast") - optional("org.springframework.session:spring-session-jdbc") - optional("org.springframework.amqp:spring-rabbit") - optional("org.springframework.amqp:spring-rabbit-stream") - optional("org.springframework.kafka:spring-kafka") - optional("org.springframework.ws:spring-ws-core") { - exclude group: "com.sun.mail", module: "jakarta.mail" - exclude group: "jakarta.platform", module: "jakarta.jakartaee-api" - exclude group: "org.eclipse.jetty", module: "jetty-server" - exclude group: "org.eclipse.jetty", module: "jetty-servlet" - exclude group: "jakarta.mail", module: "jakarta.mail-api" - } - optional("org.thymeleaf:thymeleaf") - optional("org.thymeleaf:thymeleaf-spring6") - optional("org.thymeleaf.extras:thymeleaf-extras-springsecurity6") - optional("redis.clients:jedis") + optional("org.springframework.data:spring-data-commons") + + testFixturesCompileOnly(project(":spring-boot-project:spring-boot-test")) + testFixturesCompileOnly(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testFixturesCompileOnly("javax.cache:cache-api") + testFixturesImplementation(testFixtures(project(":spring-boot-project:spring-boot"))) - testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(testFixtures(project(":spring-boot-project:spring-boot"))) testImplementation("ch.qos.logback:logback-classic") - testImplementation("commons-fileupload:commons-fileupload") - testImplementation("com.github.h-thurow:simple-jndi") - testImplementation("com.ibm.db2:jcc") - testImplementation("com.jayway.jsonpath:json-path") - testImplementation("com.mysql:mysql-connector-j") - testImplementation("com.squareup.okhttp3:mockwebserver") - testImplementation("com.sun.xml.messaging.saaj:saaj-impl") - testImplementation("io.micrometer:context-propagation") - testImplementation("io.projectreactor:reactor-test") - testImplementation("io.r2dbc:r2dbc-h2") - testImplementation("jakarta.json:jakarta.json-api") - testImplementation("jakarta.xml.ws:jakarta.xml.ws-api") - testImplementation("org.apache.logging.log4j:log4j-to-slf4j") - testImplementation("org.apache.tomcat.embed:tomcat-embed-jasper") - testImplementation("org.assertj:assertj-core") - testImplementation("org.awaitility:awaitility") - testImplementation("org.eclipse:yasson") - testImplementation("org.hsqldb:hsqldb") - testImplementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.postgresql:postgresql") - testImplementation("org.postgresql:r2dbc-postgresql") - testImplementation("org.skyscreamer:jsonassert") - testImplementation("org.springframework:spring-test") - testImplementation("org.springframework:spring-core-test") - testImplementation("org.springframework.graphql:spring-graphql-test") - testImplementation("org.springframework.kafka:spring-kafka-test") - testImplementation("org.springframework.pulsar:spring-pulsar-cache-provider-caffeine") - testImplementation("org.springframework.security:spring-security-test") - testImplementation("org.yaml:snakeyaml") - - testRuntimeOnly("jakarta.management.j2ee:jakarta.management.j2ee-api") - testRuntimeOnly("org.flywaydb:flyway-database-hsqldb") - testRuntimeOnly("org.jetbrains.kotlin:kotlin-reflect") -} + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("io.projectreactor:reactor-core") + testImplementation("org.springframework:spring-context-support") + testImplementation("org.springframework.security:spring-security-config") -tasks.named("checkSpringConfigurationMetadata").configure { - exclusions = [ - "spring.datasource.dbcp2.*", - "spring.datasource.hikari.*", - "spring.datasource.oracleucp.*", - "spring.datasource.tomcat.*", - "spring.groovy.template.configuration.*" - ] + testRuntimeOnly("com.github.ben-manes.caffeine:caffeine") + testRuntimeOnly("org.springframework:spring-webflux") } test { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java deleted file mode 100644 index 4b2f236855bb..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.elasticsearch; - -import org.junit.jupiter.api.Test; -import org.testcontainers.elasticsearch.ElasticsearchContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.alt.elasticsearch.CityReactiveElasticsearchDbRepository; -import org.springframework.boot.autoconfigure.data.elasticsearch.city.City; -import org.springframework.boot.autoconfigure.data.elasticsearch.city.ReactiveCityRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchTemplate; -import org.springframework.data.elasticsearch.config.EnableElasticsearchAuditing; -import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ReactiveElasticsearchRepositoriesAutoConfiguration}. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @author Brian Clozel - * @author Scott Frederick - */ -@Testcontainers(disabledWithoutDocker = true) -class ReactiveElasticsearchRepositoriesAutoConfigurationTests { - - @Container - static final ElasticsearchContainer elasticsearch = TestImage.container(ElasticsearchContainer.class); - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ElasticsearchClientAutoConfiguration.class, - ElasticsearchRestClientAutoConfiguration.class, - ReactiveElasticsearchRepositoriesAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, - ReactiveElasticsearchClientAutoConfiguration.class)) - .withPropertyValues( - "spring.elasticsearch.uris=" + elasticsearch.getHost() + ":" + elasticsearch.getFirstMappedPort(), - "spring.elasticsearch.socket-timeout=30s"); - - @Test - void backsOffWithoutReactor() { - this.contextRunner.withUserConfiguration(TestConfiguration.class) - .withClassLoader(new FilteredClassLoader(Mono.class)) - .run((context) -> assertThat(context) - .doesNotHaveBean(ReactiveElasticsearchRepositoriesAutoConfiguration.class)); - } - - @Test - void testDefaultRepositoryConfiguration() { - this.contextRunner.withUserConfiguration(TestConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ReactiveCityRepository.class) - .hasSingleBean(ReactiveElasticsearchTemplate.class)); - } - - @Test - void testNoRepositoryConfiguration() { - this.contextRunner.withUserConfiguration(EmptyConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchTemplate.class)); - } - - @Test - void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { - this.contextRunner.withUserConfiguration(CustomizedConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(CityReactiveElasticsearchDbRepository.class)); - } - - @Test - void testAuditingConfiguration() { - this.contextRunner.withUserConfiguration(AuditingConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchTemplate.class)); - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(City.class) - static class TestConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(EmptyDataPackage.class) - static class EmptyConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(ReactiveElasticsearchRepositoriesAutoConfigurationTests.class) - @EnableReactiveElasticsearchRepositories(basePackageClasses = CityReactiveElasticsearchDbRepository.class) - static class CustomizedConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(ElasticsearchRepositoriesAutoConfigurationTests.class) - @EnableReactiveElasticsearchRepositories - @EnableElasticsearchAuditing - static class AuditingConfiguration { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfigurationIntegrationTests.java deleted file mode 100644 index 6ecb92adf1ff..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.elasticsearch; - -import java.util.Map; - -import co.elastic.clients.elasticsearch.core.GetResponse; -import co.elastic.clients.elasticsearch.core.IndexResponse; -import org.junit.jupiter.api.Test; -import org.testcontainers.elasticsearch.ElasticsearchContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link ReactiveElasticsearchClientAutoConfiguration}. - * - * @author Brian Clozel - * @author Andy Wilkinson - */ -@Testcontainers(disabledWithoutDocker = true) -class ReactiveElasticsearchClientAutoConfigurationIntegrationTests { - - @Container - static final ElasticsearchContainer elasticsearch = TestImage.container(ElasticsearchContainer.class); - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, - ElasticsearchRestClientAutoConfiguration.class, ReactiveElasticsearchClientAutoConfiguration.class)); - - @Test - void reactiveClientCanQueryElasticsearchNode() { - this.contextRunner - .withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(), - "spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s") - .run((context) -> { - ReactiveElasticsearchClient client = context.getBean(ReactiveElasticsearchClient.class); - Mono index = client - .index((b) -> b.index("foo").id("1").document(Map.of("a", "alpha", "b", "bravo"))); - index.block(); - Mono> get = client.get((b) -> b.index("foo").id("1"), Object.class); - GetResponse response = get.block(); - assertThat(response).isNotNull(); - assertThat(response.found()).isTrue(); - }); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationIntegrationTests.java deleted file mode 100644 index 0326eeadc02e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.pulsar; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.PulsarContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.pulsar.annotation.PulsarListener; -import org.springframework.pulsar.core.PulsarTemplate; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link PulsarAutoConfiguration}. - * - * @author Chris Bono - * @author Phillip Webb - */ -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@Testcontainers(disabledWithoutDocker = true) -class PulsarAutoConfigurationIntegrationTests { - - @Container - static final PulsarContainer pulsar = TestImage.container(PulsarContainer.class); - - private static final CountDownLatch listenLatch = new CountDownLatch(1); - - private static final String TOPIC = "pacit-hello-topic"; - - @DynamicPropertySource - static void pulsarProperties(DynamicPropertyRegistry registry) { - registry.add("spring.pulsar.client.service-url", pulsar::getPulsarBrokerUrl); - registry.add("spring.pulsar.admin.service-url", pulsar::getHttpServiceUrl); - } - - @Test - void appStartsWithAutoConfiguredSpringPulsarComponents( - @Autowired(required = false) PulsarTemplate pulsarTemplate) { - assertThat(pulsarTemplate).isNotNull(); - } - - @Test - void templateCanBeAccessedDuringWebRequest(@Autowired TestRestTemplate restTemplate) throws InterruptedException { - assertThat(restTemplate.getForObject("/hello", String.class)).startsWith("Hello World -> "); - assertThat(listenLatch.await(5, TimeUnit.SECONDS)).isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ DispatcherServletAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class, - WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, JacksonAutoConfiguration.class, - PulsarAutoConfiguration.class, PulsarReactiveAutoConfiguration.class }) - @Import(TestWebController.class) - static class TestConfiguration { - - @PulsarListener(subscriptionName = TOPIC + "-sub", topics = TOPIC) - void listen(String ignored) { - listenLatch.countDown(); - } - - } - - @RestController - static class TestWebController { - - private final PulsarTemplate pulsarTemplate; - - TestWebController(PulsarTemplate pulsarTemplate) { - this.pulsarTemplate = pulsarTemplate; - } - - @GetMapping("/hello") - String sayHello() { - return "Hello World -> " + this.pulsarTemplate.send(TOPIC, "hello"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationMongoTests.java b/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationMongoTests.java deleted file mode 100644 index 894143497d0e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationMongoTests.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.time.Duration; -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.MongoDBContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.http.ResponseCookie; -import org.springframework.session.MapSession; -import org.springframework.session.data.mongo.ReactiveMongoSessionRepository; -import org.springframework.session.data.redis.ReactiveRedisSessionRepository; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Mongo-specific tests for {@link SessionAutoConfiguration}. - * - * @author Andy Wilkinson - * @author Weix Sun - */ -@Testcontainers(disabledWithoutDocker = true) -class ReactiveSessionAutoConfigurationMongoTests extends AbstractSessionAutoConfigurationTests { - - @Container - static final MongoDBContainer mongoDb = TestImage.container(MongoDBContainer.class); - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withClassLoader(new FilteredClassLoader(ReactiveRedisSessionRepository.class)) - .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class, MongoAutoConfiguration.class, - MongoDataAutoConfiguration.class, MongoReactiveAutoConfiguration.class, - MongoReactiveDataAutoConfiguration.class)); - - @Test - void defaultConfig() { - this.contextRunner.withPropertyValues("spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) - .run(validateSpringSessionUsesMongo("sessions")); - } - - @Test - void defaultConfigWithCustomTimeout() { - this.contextRunner - .withPropertyValues("spring.session.timeout=1m", "spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) - .run((context) -> { - ReactiveMongoSessionRepository repository = validateSessionRepository(context, - ReactiveMongoSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); - }); - } - - @Test - void defaultConfigWithCustomSessionTimeout() { - this.contextRunner - .withPropertyValues("server.reactive.session.timeout=1m", - "spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) - .run((context) -> { - ReactiveMongoSessionRepository repository = validateSessionRepository(context, - ReactiveMongoSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); - }); - } - - @Test - void mongoSessionStoreWithCustomizations() { - this.contextRunner - .withPropertyValues("spring.session.mongodb.collection-name=foo", - "spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) - .run(validateSpringSessionUsesMongo("foo")); - } - - @Test - void sessionCookieConfigurationIsAppliedToAutoConfiguredWebSessionIdResolver() { - AutoConfigurations autoConfigurations = AutoConfigurations.of(SessionAutoConfiguration.class, - MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, MongoReactiveAutoConfiguration.class, - MongoReactiveDataAutoConfiguration.class, WebSessionIdResolverAutoConfiguration.class); - new ReactiveWebApplicationContextRunner().withConfiguration(autoConfigurations) - .withUserConfiguration(Config.class) - .withClassLoader(new FilteredClassLoader(ReactiveRedisSessionRepository.class)) - .withPropertyValues("server.reactive.session.cookie.name:JSESSIONID", - "server.reactive.session.cookie.domain:.example.com", - "server.reactive.session.cookie.path:/example", "server.reactive.session.cookie.max-age:60", - "server.reactive.session.cookie.http-only:false", "server.reactive.session.cookie.secure:false", - "server.reactive.session.cookie.same-site:strict", - "spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) - .run(assertExchangeWithSession((exchange) -> { - List cookies = exchange.getResponse().getCookies().get("JSESSIONID"); - assertThat(cookies).isNotEmpty(); - assertThat(cookies).allMatch((cookie) -> cookie.getDomain().equals(".example.com")); - assertThat(cookies).allMatch((cookie) -> cookie.getPath().equals("/example")); - assertThat(cookies).allMatch((cookie) -> cookie.getMaxAge().equals(Duration.ofSeconds(60))); - assertThat(cookies).allMatch((cookie) -> !cookie.isHttpOnly()); - assertThat(cookies).allMatch((cookie) -> !cookie.isSecure()); - assertThat(cookies).allMatch((cookie) -> cookie.getSameSite().equals("Strict")); - })); - } - - private ContextConsumer validateSpringSessionUsesMongo( - String collectionName) { - return (context) -> { - ReactiveMongoSessionRepository repository = validateSessionRepository(context, - ReactiveMongoSessionRepository.class); - assertThat(repository.getCollectionName()).isEqualTo(collectionName); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", - MapSession.DEFAULT_MAX_INACTIVE_INTERVAL); - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationRedisTests.java b/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationRedisTests.java deleted file mode 100644 index a1d3f9181256..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationRedisTests.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.time.Duration; -import java.util.List; -import java.util.Map; - -import com.redis.testcontainers.RedisContainer; -import org.junit.jupiter.api.Test; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.data.redis.connection.ReactiveRedisConnection; -import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.http.ResponseCookie; -import org.springframework.session.MapSession; -import org.springframework.session.SaveMode; -import org.springframework.session.data.mongo.ReactiveMongoSessionRepository; -import org.springframework.session.data.redis.ReactiveRedisIndexedSessionRepository; -import org.springframework.session.data.redis.ReactiveRedisSessionRepository; -import org.springframework.session.data.redis.config.ConfigureReactiveRedisAction; -import org.springframework.session.data.redis.config.annotation.ConfigureNotifyKeyspaceEventsReactiveAction; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - -/** - * Reactive Redis-specific tests for {@link SessionAutoConfiguration}. - * - * @author Stephane Nicoll - * @author Andy Wilkinson - * @author Vedran Pavic - * @author Weix Sun - */ -@Testcontainers(disabledWithoutDocker = true) -class ReactiveSessionAutoConfigurationRedisTests extends AbstractSessionAutoConfigurationTests { - - @Container - public static RedisContainer redis = TestImage.container(RedisContainer.class); - - protected final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withClassLoader(new FilteredClassLoader(ReactiveMongoSessionRepository.class)) - .withConfiguration( - AutoConfigurations.of(SessionAutoConfiguration.class, WebSessionIdResolverAutoConfiguration.class, - RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class)); - - @Test - void defaultConfig() { - this.contextRunner.run(validateSpringSessionUsesRedis("spring:session:", SaveMode.ON_SET_ATTRIBUTE)); - } - - @Test - void redisTakesPrecedenceMultipleImplementations() { - ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner().withConfiguration( - AutoConfigurations.of(SessionAutoConfiguration.class, WebSessionIdResolverAutoConfiguration.class, - RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class)); - contextRunner.run(validateSpringSessionUsesRedis("spring:session:", SaveMode.ON_SET_ATTRIBUTE)); - } - - @Test - void defaultConfigWithCustomTimeout() { - this.contextRunner.withPropertyValues("spring.session.timeout=1m").run((context) -> { - ReactiveRedisSessionRepository repository = validateSessionRepository(context, - ReactiveRedisSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); - }); - } - - @Test - void defaultConfigWithCustomWebFluxTimeout() { - this.contextRunner.withPropertyValues("server.reactive.session.timeout=1m").run((context) -> { - ReactiveRedisSessionRepository repository = validateSessionRepository(context, - ReactiveRedisSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); - }); - } - - @Test - void redisSessionStoreWithCustomizations() { - this.contextRunner - .withPropertyValues("spring.session.redis.namespace=foo", "spring.session.redis.save-mode=on-get-attribute") - .run(validateSpringSessionUsesRedis("foo:", SaveMode.ON_GET_ATTRIBUTE)); - } - - @Test - void sessionCookieConfigurationIsAppliedToAutoConfiguredWebSessionIdResolver() { - this.contextRunner.withUserConfiguration(Config.class) - .withPropertyValues("spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort(), - "server.reactive.session.cookie.name:JSESSIONID", - "server.reactive.session.cookie.domain:.example.com", - "server.reactive.session.cookie.path:/example", "server.reactive.session.cookie.max-age:60", - "server.reactive.session.cookie.http-only:false", "server.reactive.session.cookie.secure:false", - "server.reactive.session.cookie.same-site:strict") - .run(assertExchangeWithSession((exchange) -> { - List cookies = exchange.getResponse().getCookies().get("JSESSIONID"); - assertThat(cookies).isNotEmpty(); - assertThat(cookies).allMatch((cookie) -> cookie.getDomain().equals(".example.com")); - assertThat(cookies).allMatch((cookie) -> cookie.getPath().equals("/example")); - assertThat(cookies).allMatch((cookie) -> cookie.getMaxAge().equals(Duration.ofSeconds(60))); - assertThat(cookies).allMatch((cookie) -> !cookie.isHttpOnly()); - assertThat(cookies).allMatch((cookie) -> !cookie.isSecure()); - assertThat(cookies).allMatch((cookie) -> cookie.getSameSite().equals("Strict")); - })); - } - - @Test - void indexedRedisSessionDefaultConfig() { - this.contextRunner - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) - .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .run(validateSpringSessionUsesIndexedRedis("spring:session:", SaveMode.ON_SET_ATTRIBUTE)); - } - - @Test - void indexedRedisSessionStoreWithCustomizations() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withPropertyValues("spring.session.redis.repository-type=indexed", "spring.session.redis.namespace=foo", - "spring.session.redis.save-mode=on-get-attribute", "spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateSpringSessionUsesIndexedRedis("foo:", SaveMode.ON_GET_ATTRIBUTE)); - } - - @Test - void indexedRedisSessionWithConfigureActionNone() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.session.redis.configure-action=none", "spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateStrategy(ConfigureReactiveRedisAction.NO_OP.getClass())); - } - - @Test - void indexedRedisSessionWithDefaultConfigureActionNone() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateStrategy(ConfigureNotifyKeyspaceEventsReactiveAction.class, - entry("notify-keyspace-events", "gxE"))); - } - - @Test - void indexedRedisSessionWithCustomConfigureReactiveRedisActionBean() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withUserConfiguration(MaxEntriesReactiveRedisAction.class) - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateStrategy(MaxEntriesReactiveRedisAction.class, entry("set-max-intset-entries", "1024"))); - - } - - private ContextConsumer validateSpringSessionUsesRedis(String namespace, - SaveMode saveMode) { - return (context) -> { - ReactiveRedisSessionRepository repository = validateSessionRepository(context, - ReactiveRedisSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", - MapSession.DEFAULT_MAX_INACTIVE_INTERVAL); - assertThat(repository).hasFieldOrPropertyWithValue("namespace", namespace); - assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); - }; - } - - private ContextConsumer validateSpringSessionUsesIndexedRedis( - String keyNamespace, SaveMode saveMode) { - return (context) -> { - ReactiveRedisIndexedSessionRepository repository = validateSessionRepository(context, - ReactiveRedisIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", - new ServerProperties().getReactive().getSession().getTimeout()); - assertThat(repository).hasFieldOrPropertyWithValue("namespace", keyNamespace); - assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); - }; - } - - private ContextConsumer validateStrategy( - Class expectedConfigureReactiveRedisActionType, - Map.Entry... expectedConfig) { - return (context) -> { - assertThat(context).hasSingleBean(ConfigureReactiveRedisAction.class); - assertThat(context).hasSingleBean(RedisConnectionFactory.class); - assertThat(context.getBean(ConfigureReactiveRedisAction.class)) - .isInstanceOf(expectedConfigureReactiveRedisActionType); - ReactiveRedisConnection connection = context.getBean(ReactiveRedisConnectionFactory.class) - .getReactiveConnection(); - if (expectedConfig.length > 0) { - assertThat(connection.serverCommands().getConfig("*").block(Duration.ofSeconds(30))) - .contains(expectedConfig); - } - }; - } - - static class MaxEntriesReactiveRedisAction implements ConfigureReactiveRedisAction { - - @Override - public Mono configure(ReactiveRedisConnection connection) { - return Mono.when(connection.serverCommands().setConfig("set-max-intset-entries", "1024")); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationMongoTests.java b/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationMongoTests.java deleted file mode 100644 index 7b0271f17215..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationMongoTests.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.MongoDBContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.session.data.mongo.MongoIndexedSessionRepository; -import org.springframework.session.data.redis.RedisIndexedSessionRepository; -import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository; -import org.springframework.session.jdbc.JdbcIndexedSessionRepository; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Mongo-specific tests for {@link SessionAutoConfiguration}. - * - * @author Andy Wilkinson - */ -@Testcontainers(disabledWithoutDocker = true) -class SessionAutoConfigurationMongoTests extends AbstractSessionAutoConfigurationTests { - - @Container - static final MongoDBContainer mongoDb = TestImage.container(MongoDBContainer.class); - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withClassLoader(new FilteredClassLoader(HazelcastIndexedSessionRepository.class, - JdbcIndexedSessionRepository.class, RedisIndexedSessionRepository.class)) - .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, - SessionAutoConfiguration.class)) - .withPropertyValues("spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()); - - @Test - void defaultConfig() { - this.contextRunner.run(validateSpringSessionUsesMongo("sessions")); - } - - @Test - void defaultConfigWithCustomTimeout() { - this.contextRunner.withPropertyValues("spring.session.timeout=1m") - .run(validateSpringSessionUsesMongo("sessions", Duration.ofMinutes(1))); - } - - @Test - void mongoSessionStoreWithCustomizations() { - this.contextRunner.withPropertyValues("spring.session.mongodb.collection-name=foo") - .run(validateSpringSessionUsesMongo("foo")); - } - - @Test - void whenTheUserDefinesTheirOwnSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { - this.contextRunner.withUserConfiguration(CustomizerConfiguration.class) - .withPropertyValues("spring.session.mongodb.collection-name=foo") - .run(validateSpringSessionUsesMongo("customized")); - } - - private ContextConsumer validateSpringSessionUsesMongo(String collectionName) { - return validateSpringSessionUsesMongo(collectionName, - new ServerProperties().getServlet().getSession().getTimeout()); - } - - private ContextConsumer validateSpringSessionUsesMongo(String collectionName, - Duration timeout) { - return (context) -> { - MongoIndexedSessionRepository repository = validateSessionRepository(context, - MongoIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("collectionName", collectionName); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", timeout); - }; - } - - @Configuration(proxyBeanMethods = false) - static class CustomizerConfiguration { - - @Bean - SessionRepositoryCustomizer sessionRepositoryCustomizer() { - return (repository) -> repository.setCollectionName("customized"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java b/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java deleted file mode 100644 index ab0abebc44ae..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.time.Duration; -import java.util.Map; - -import com.redis.testcontainers.RedisContainer; -import org.junit.jupiter.api.Test; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.session.FlushMode; -import org.springframework.session.SaveMode; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.session.data.mongo.MongoIndexedSessionRepository; -import org.springframework.session.data.redis.RedisIndexedSessionRepository; -import org.springframework.session.data.redis.RedisSessionRepository; -import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction; -import org.springframework.session.data.redis.config.ConfigureRedisAction; -import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository; -import org.springframework.session.jdbc.JdbcIndexedSessionRepository; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - -/** - * Redis specific tests for {@link SessionAutoConfiguration}. - * - * @author Stephane Nicoll - * @author Vedran Pavic - */ -@Testcontainers(disabledWithoutDocker = true) -class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfigurationTests { - - @Container - public static RedisContainer redis = TestImage.container(RedisContainer.class); - - protected final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withClassLoader(new FilteredClassLoader(HazelcastIndexedSessionRepository.class, - JdbcIndexedSessionRepository.class, MongoIndexedSessionRepository.class)) - .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class)); - - @Test - void defaultConfig() { - this.contextRunner - .withPropertyValues("spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort()) - .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .run(validateSpringSessionUsesDefaultRedis("spring:session:", FlushMode.ON_SAVE, - SaveMode.ON_SET_ATTRIBUTE)); - } - - @Test - void invalidConfigurationPropertyValueWhenDefaultConfigIsUsedWithCustomCronCleanup() { - this.contextRunner.withPropertyValues("spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort(), "spring.session.redis.cleanup-cron=0 0 * * * *") - .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasFailed(); - assertThat(context.getStartupFailure()) - .hasRootCauseExactlyInstanceOf(InvalidConfigurationPropertyValueException.class); - }); - } - - @Test - void redisTakesPrecedenceMultipleImplementations() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withPropertyValues("spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateSpringSessionUsesDefaultRedis("spring:session:", FlushMode.ON_SAVE, - SaveMode.ON_SET_ATTRIBUTE)); - } - - @Test - void defaultConfigWithCustomTimeout() { - this.contextRunner - .withPropertyValues("spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort(), "spring.session.timeout=1m") - .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .run((context) -> { - RedisSessionRepository repository = validateSessionRepository(context, RedisSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); - }); - } - - @Test - void defaultRedisSessionStoreWithCustomizations() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withPropertyValues("spring.session.redis.namespace=foo", "spring.session.redis.flush-mode=immediate", - "spring.session.redis.save-mode=on-get-attribute", "spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateSpringSessionUsesDefaultRedis("foo:", FlushMode.IMMEDIATE, SaveMode.ON_GET_ATTRIBUTE)); - } - - @Test - void indexedRedisSessionDefaultConfig() { - this.contextRunner - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) - .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .run(validateSpringSessionUsesIndexedRedis("spring:session:", FlushMode.ON_SAVE, SaveMode.ON_SET_ATTRIBUTE, - "0 * * * * *")); - } - - @Test - void indexedRedisSessionStoreWithCustomizations() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withPropertyValues("spring.session.redis.repository-type=indexed", "spring.session.redis.namespace=foo", - "spring.session.redis.flush-mode=immediate", "spring.session.redis.save-mode=on-get-attribute", - "spring.session.redis.cleanup-cron=0 0 12 * * *", "spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateSpringSessionUsesIndexedRedis("foo:", FlushMode.IMMEDIATE, SaveMode.ON_GET_ATTRIBUTE, - "0 0 12 * * *")); - } - - @Test - void indexedRedisSessionWithConfigureActionNone() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.session.redis.configure-action=none", "spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateStrategy(ConfigureRedisAction.NO_OP.getClass())); - } - - @Test - void indexedRedisSessionWithDefaultConfigureActionNone() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateStrategy(ConfigureNotifyKeyspaceEventsAction.class, entry("notify-keyspace-events", "gxE"))); - } - - @Test - void indexedRedisSessionWithCustomConfigureRedisActionBean() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withUserConfiguration(MaxEntriesRedisAction.class) - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run(validateStrategy(MaxEntriesRedisAction.class, entry("set-max-intset-entries", "1024"))); - - } - - @Test - void whenTheUserDefinesTheirOwnSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withUserConfiguration(CustomizerConfiguration.class) - .withPropertyValues("spring.session.redis.flush-mode=immediate", - "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run((context) -> { - RedisSessionRepository repository = validateSessionRepository(context, RedisSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.ON_SAVE); - }); - } - - @Test - void whenIndexedAndTheUserDefinesTheirOwnSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { - this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) - .withUserConfiguration(IndexedCustomizerConfiguration.class) - .withPropertyValues("spring.session.redis.repository-type=indexed", - "spring.session.redis.flush-mode=immediate", "spring.data.redis.host=" + redis.getHost(), - "spring.data.redis.port=" + redis.getFirstMappedPort()) - .run((context) -> { - RedisIndexedSessionRepository repository = validateSessionRepository(context, - RedisIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.ON_SAVE); - }); - } - - private ContextConsumer validateSpringSessionUsesDefaultRedis(String keyNamespace, - FlushMode flushMode, SaveMode saveMode) { - return (context) -> { - RedisSessionRepository repository = validateSessionRepository(context, RedisSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", - new ServerProperties().getServlet().getSession().getTimeout()); - assertThat(repository).hasFieldOrPropertyWithValue("keyNamespace", keyNamespace); - assertThat(repository).hasFieldOrPropertyWithValue("flushMode", flushMode); - assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); - }; - } - - private ContextConsumer validateSpringSessionUsesIndexedRedis(String keyNamespace, - FlushMode flushMode, SaveMode saveMode, String cleanupCron) { - return (context) -> { - RedisIndexedSessionRepository repository = validateSessionRepository(context, - RedisIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", - new ServerProperties().getServlet().getSession().getTimeout()); - assertThat(repository).hasFieldOrPropertyWithValue("namespace", keyNamespace); - assertThat(repository).hasFieldOrPropertyWithValue("flushMode", flushMode); - assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); - assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", cleanupCron); - }; - } - - private ContextConsumer validateStrategy( - Class expectedConfigureRedisActionType, Map.Entry... expectedConfig) { - return (context) -> { - assertThat(context).hasSingleBean(ConfigureRedisAction.class); - assertThat(context).hasSingleBean(RedisConnectionFactory.class); - assertThat(context.getBean(ConfigureRedisAction.class)).isInstanceOf(expectedConfigureRedisActionType); - RedisConnection connection = context.getBean(RedisConnectionFactory.class).getConnection(); - if (expectedConfig.length > 0) { - assertThat(connection.serverCommands().getConfig("*")).contains(expectedConfig); - } - }; - } - - static class MaxEntriesRedisAction implements ConfigureRedisAction { - - @Override - public void configure(RedisConnection connection) { - connection.serverCommands().setConfig("set-max-intset-entries", "1024"); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomizerConfiguration { - - @Bean - SessionRepositoryCustomizer sessionRepositoryCustomizer() { - return (repository) -> repository.setFlushMode(FlushMode.ON_SAVE); - } - - } - - @Configuration(proxyBeanMethods = false) - static class IndexedCustomizerConfiguration { - - @Bean - SessionRepositoryCustomizer sessionRepositoryCustomizer() { - return (repository) -> repository.setFlushMode(FlushMode.ON_SAVE); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/BackgroundPreinitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/BackgroundPreinitializer.java deleted file mode 100644 index c9575206ea3d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/BackgroundPreinitializer.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure; - -import java.nio.charset.StandardCharsets; -import java.time.ZoneId; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicBoolean; - -import jakarta.validation.Configuration; -import jakarta.validation.Validation; -import org.apache.catalina.authenticator.NonLoginAuthenticator; -import org.apache.tomcat.util.http.Rfc6265CookieProcessor; - -import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; -import org.springframework.boot.context.event.ApplicationFailedEvent; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.boot.context.event.SpringApplicationEvent; -import org.springframework.boot.context.logging.LoggingApplicationListener; -import org.springframework.context.ApplicationListener; -import org.springframework.core.NativeDetector; -import org.springframework.core.Ordered; -import org.springframework.format.support.DefaultFormattingConversionService; -import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; - -/** - * {@link ApplicationListener} to trigger early initialization in a background thread of - * time-consuming tasks. - *

- * Set the {@link #IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME} system property to - * {@code true} to disable this mechanism and let such initialization happen in the - * foreground. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @author Artsiom Yudovin - * @author Sebastien Deleuze - * @since 1.3.0 - */ -public class BackgroundPreinitializer implements ApplicationListener, Ordered { - - /** - * System property that instructs Spring Boot how to run pre initialization. When the - * property is set to {@code true}, no pre-initialization happens and each item is - * initialized in the foreground as it needs to. When the property is {@code false} - * (default), pre initialization runs in a separate thread in the background. - * @since 2.1.0 - */ - public static final String IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME = "spring.backgroundpreinitializer.ignore"; - - private static final AtomicBoolean preinitializationStarted = new AtomicBoolean(); - - private static final CountDownLatch preinitializationComplete = new CountDownLatch(1); - - private static final boolean ENABLED = !Boolean.getBoolean(IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME) - && Runtime.getRuntime().availableProcessors() > 1; - - @Override - public int getOrder() { - return LoggingApplicationListener.DEFAULT_ORDER + 1; - } - - @Override - public void onApplicationEvent(SpringApplicationEvent event) { - if (!ENABLED || NativeDetector.inNativeImage()) { - return; - } - if (event instanceof ApplicationEnvironmentPreparedEvent - && preinitializationStarted.compareAndSet(false, true)) { - performPreinitialization(); - } - if ((event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent) - && preinitializationStarted.get()) { - try { - preinitializationComplete.await(); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } - - private void performPreinitialization() { - try { - Thread thread = new Thread(new Runnable() { - - @Override - public void run() { - runSafely(new ConversionServiceInitializer()); - runSafely(new ValidationInitializer()); - if (!runSafely(new MessageConverterInitializer())) { - // If the MessageConverterInitializer fails to run, we still might - // be able to - // initialize Jackson - runSafely(new JacksonInitializer()); - } - runSafely(new CharsetInitializer()); - runSafely(new TomcatInitializer()); - runSafely(new JdkInitializer()); - preinitializationComplete.countDown(); - } - - boolean runSafely(Runnable runnable) { - try { - runnable.run(); - return true; - } - catch (Throwable ex) { - return false; - } - } - - }, "background-preinit"); - thread.start(); - } - catch (Exception ex) { - // This will fail on GAE where creating threads is prohibited. We can safely - // continue but startup will be slightly slower as the initialization will now - // happen on the main thread. - preinitializationComplete.countDown(); - } - } - - /** - * Early initializer for Spring MessageConverters. - */ - private static final class MessageConverterInitializer implements Runnable { - - @Override - public void run() { - new AllEncompassingFormHttpMessageConverter(); - } - - } - - /** - * Early initializer for jakarta.validation. - */ - private static final class ValidationInitializer implements Runnable { - - @Override - public void run() { - Configuration configuration = Validation.byDefaultProvider().configure(); - configuration.buildValidatorFactory().getValidator(); - } - - } - - /** - * Early initializer for Jackson. - */ - @SuppressWarnings({ "removal", "deprecation" }) - private static final class JacksonInitializer implements Runnable { - - @Override - public void run() { - org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.json().build(); - } - - } - - /** - * Early initializer for Spring's ConversionService. - */ - private static final class ConversionServiceInitializer implements Runnable { - - @Override - public void run() { - new DefaultFormattingConversionService(); - } - - } - - private static final class CharsetInitializer implements Runnable { - - @Override - public void run() { - StandardCharsets.UTF_8.name(); - } - - } - - private static final class TomcatInitializer implements Runnable { - - @Override - public void run() { - new Rfc6265CookieProcessor(); - new NonLoginAuthenticator(); - } - - } - - private static final class JdkInitializer implements Runnable { - - @Override - public void run() { - ZoneId.systemDefault(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/EnableAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/EnableAutoConfiguration.java index b6684c0ba79e..da5601efb125 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/EnableAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/EnableAutoConfiguration.java @@ -27,8 +27,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.annotation.ImportCandidates; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -36,10 +34,7 @@ /** * Enable auto-configuration of the Spring Application Context, attempting to guess and * configure beans that you are likely to need. Auto-configuration classes are usually - * applied based on your classpath and what beans you have defined. For example, if you - * have {@code tomcat-embedded.jar} on your classpath you are likely to want a - * {@link TomcatServletWebServerFactory} (unless you have defined your own - * {@link ServletWebServerFactory} bean). + * applied based on your classpath and what beans you have defined. *

* When using {@link SpringBootApplication @SpringBootApplication}, the auto-configuration * of the context is automatically enabled and adding this annotation has therefore no diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java index 78a80f5febee..61bdcb45fb4c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java @@ -34,7 +34,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.core.annotation.AliasFor; -import org.springframework.data.repository.Repository; /** * Indicates a {@link Configuration configuration} class that declares one or more @@ -80,9 +79,8 @@ *

* Note: this setting is an alias for * {@link ComponentScan @ComponentScan} only. It has no effect on {@code @Entity} - * scanning or Spring Data {@link Repository} scanning. For those you should add - * {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} and - * {@code @Enable...Repositories} annotations. + * scanning or Spring Data repository scanning. For those you should add + * {@code @EntityScan} and {@code @Enable...Repositories} annotations. * @return base packages to scan * @since 1.3.0 */ @@ -98,9 +96,8 @@ *

* Note: this setting is an alias for * {@link ComponentScan @ComponentScan} only. It has no effect on {@code @Entity} - * scanning or Spring Data {@link Repository} scanning. For those you should add - * {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} and - * {@code @Enable...Repositories} annotations. + * scanning or Spring Data repository scanning. For those you should add + * {@code @EntityScan} and {@code @Enable...Repositories} annotations. * @return base packages to scan * @since 1.3.0 */ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/package-info.java deleted file mode 100644 index d4b1b61b8dd6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for RabbitMQ. - */ -package org.springframework.boot.autoconfigure.amqp; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/package-info.java deleted file mode 100644 index e644f5e18f49..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Batch. - */ -package org.springframework.boot.autoconfigure.batch; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheType.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheType.java index 8784de81178e..c86dea31a73f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheType.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheType.java @@ -22,7 +22,7 @@ * @author Stephane Nicoll * @author Phillip Webb * @author Eddú Meléndez - * @since 1.3.0 + * @since 4.0.0 */ public enum CacheType { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/package-info.java index 9498501f9c4a..9eaa0a0d7b51 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/package-info.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/package-info.java @@ -15,6 +15,6 @@ */ /** - * Auto-configuration for the cache abstraction. + * Auto-configuration base classes for Caching support. */ package org.springframework.boot.autoconfigure.cache; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/package-info.java deleted file mode 100644 index 90d8eb8478b1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Cassandra. - */ -package org.springframework.boot.autoconfigure.cassandra; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/codec/CodecProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/codec/CodecProperties.java deleted file mode 100644 index 587d3f0229e1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/codec/CodecProperties.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.codec; - -import org.springframework.boot.autoconfigure.http.codec.HttpCodecsProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; -import org.springframework.util.unit.DataSize; - -/** - * {@link ConfigurationProperties Properties} for reactive codecs. - * - * @author Brian Clozel - * @since 2.2.1 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link HttpCodecsProperties} - */ -@ConfigurationProperties("spring.codec") -@Deprecated(since = "3.5.0", forRemoval = true) -public class CodecProperties { - - /** - * Whether to log form data at DEBUG level, and headers at TRACE level. - */ - private boolean logRequestDetails; - - /** - * Limit on the number of bytes that can be buffered whenever the input stream needs - * to be aggregated. This applies only to the auto-configured WebFlux server and - * WebClient instances. By default this is not set, in which case individual codec - * defaults apply. Most codecs are limited to 256K by default. - */ - private DataSize maxInMemorySize; - - @DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.codecs.log-request-details") - public boolean isLogRequestDetails() { - return this.logRequestDetails; - } - - public void setLogRequestDetails(boolean logRequestDetails) { - this.logRequestDetails = logRequestDetails; - } - - @DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.codecs.max-in-memory-size") - public DataSize getMaxInMemorySize() { - return this.maxInMemorySize; - } - - public void setMaxInMemorySize(DataSize maxInMemorySize) { - this.maxInMemorySize = maxInMemorySize; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/codec/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/codec/package-info.java deleted file mode 100644 index cf1b3305306a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/codec/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for reactive codecs. - */ -package org.springframework.boot.autoconfigure.codec; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionOutcome.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionOutcome.java index cef20658de95..0a1ae61c7634 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionOutcome.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionOutcome.java @@ -148,17 +148,4 @@ public String toString() { return (this.message != null) ? this.message.toString() : ""; } - /** - * Return the inverse of the specified condition outcome. - * @param outcome the outcome to inverse - * @return the inverse of the condition outcome - * @since 1.3.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #ConditionOutcome(boolean, ConditionMessage)} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - public static ConditionOutcome inverse(ConditionOutcome outcome) { - return new ConditionOutcome(!outcome.isMatch(), outcome.getConditionMessage()); - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBean.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingFilterBean.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBean.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingFilterBean.java index bde34a4c42fa..9db20c20d369 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBean.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingFilterBean.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.autoconfigure.condition; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -25,7 +25,6 @@ import jakarta.servlet.Filter; import org.springframework.beans.factory.BeanFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Conditional; import org.springframework.core.annotation.AliasFor; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnWebApplicationCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnWebApplicationCondition.java index c31bfc092aa4..912aa4aeaf7e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnWebApplicationCondition.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnWebApplicationCondition.java @@ -20,8 +20,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurationMetadata; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebEnvironment; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebEnvironment; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.Ordered; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/package-info.java deleted file mode 100644 index 108f00a0db79..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Couchbase. - */ -package org.springframework.boot.autoconfigure.couchbase; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/dao/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/dao/package-info.java deleted file mode 100644 index 81e49234abe5..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/dao/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring DAO. - */ -package org.springframework.boot.autoconfigure.dao; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/package-info.java deleted file mode 100644 index 54663a43469c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data Cassandra. - */ -package org.springframework.boot.autoconfigure.data.cassandra; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/package-info.java deleted file mode 100644 index 653d3d5cc1ef..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data Couchbase. - */ -package org.springframework.boot.autoconfigure.data.couchbase; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfiguration.java deleted file mode 100644 index 29740b554227..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.elasticsearch; - -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Import; -import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; -import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; -import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; -import org.springframework.data.elasticsearch.repository.support.ReactiveElasticsearchRepositoryFactoryBean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Elasticsearch - * Reactive Repositories. - * - * @author Brian Clozel - * @since 2.2.0 - * @see EnableReactiveElasticsearchRepositories - */ -@AutoConfiguration -@ConditionalOnClass({ ReactiveElasticsearchClient.class, ReactiveElasticsearchRepository.class, Mono.class }) -@ConditionalOnBooleanProperty(name = "spring.data.elasticsearch.repositories.enabled", matchIfMissing = true) -@ConditionalOnMissingBean(ReactiveElasticsearchRepositoryFactoryBean.class) -@Import(ReactiveElasticsearchRepositoriesRegistrar.class) -public class ReactiveElasticsearchRepositoriesAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesRegistrar.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesRegistrar.java deleted file mode 100644 index e37647d03823..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesRegistrar.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.elasticsearch; - -import java.lang.annotation.Annotation; - -import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; -import org.springframework.data.elasticsearch.repository.config.ReactiveElasticsearchRepositoryConfigurationExtension; -import org.springframework.data.repository.config.RepositoryConfigurationExtension; - -/** - * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Elasticsearch - * Reactive Repositories. - * - * @author Brian Clozel - */ -class ReactiveElasticsearchRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport { - - @Override - protected Class getAnnotation() { - return EnableReactiveElasticsearchRepositories.class; - } - - @Override - protected Class getConfiguration() { - return EnableElasticsearchRepositoriesConfiguration.class; - } - - @Override - protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() { - return new ReactiveElasticsearchRepositoryConfigurationExtension(); - } - - @EnableReactiveElasticsearchRepositories - private static final class EnableElasticsearchRepositoriesConfiguration { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/package-info.java deleted file mode 100644 index 0c3fb3c69444..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data Elasticsearch. - */ -package org.springframework.boot.autoconfigure.data.elasticsearch; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/package-info.java deleted file mode 100644 index a695bace831e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data JDBC. - */ -package org.springframework.boot.autoconfigure.data.jdbc; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/package-info.java deleted file mode 100644 index 5ec2a203147f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data JPA. - */ -package org.springframework.boot.autoconfigure.data.jpa; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/package-info.java deleted file mode 100644 index 47801e42c0d9..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data LDAP. - */ -package org.springframework.boot.autoconfigure.data.ldap; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/package-info.java deleted file mode 100644 index 0dca2403f25b..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data Mongo. - */ -package org.springframework.boot.autoconfigure.data.mongo; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/package-info.java deleted file mode 100644 index 4a681dcbfd81..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data Neo4j. - */ -package org.springframework.boot.autoconfigure.data.neo4j; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/package-info.java deleted file mode 100644 index 5946c44012cb..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-Configuration for Spring Data R2DBC. - */ -package org.springframework.boot.autoconfigure.data.r2dbc; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/package-info.java deleted file mode 100644 index c95b7d12c895..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data Redis. - */ -package org.springframework.boot.autoconfigure.data.redis; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/package-info.java deleted file mode 100644 index 05d38c596425..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data REST. - */ -package org.springframework.boot.autoconfigure.data.rest; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/package-info.java deleted file mode 100644 index d89eb7468c2f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Data's Web Support. - */ -package org.springframework.boot.autoconfigure.data.web; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScan.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScan.java index 4569c904efce..d242ff16d4e7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScan.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScan.java @@ -27,23 +27,8 @@ /** * Configures the base packages used by auto-configuration when scanning for entity - * classes. - *

- * Using {@code @EntityScan} will cause auto-configuration to: - *

    - *
  • Set the - * {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#setPackagesToScan(String...) - * packages scanned} for JPA entities.
  • - *
  • Set the - * {@link org.springframework.data.mapping.context.AbstractMappingContext#setInitialEntitySet(java.util.Set) - * initial entity set} used with Spring Data - * {@link org.springframework.data.mongodb.core.mapping.MongoMappingContext MongoDB}, - * {@link org.springframework.data.neo4j.core.mapping.Neo4jMappingContext Neo4j}, - * {@link org.springframework.data.cassandra.core.mapping.CassandraMappingContext - * Cassandra} and - * {@link org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext - * Couchbase} mapping contexts.
  • - *
+ * classes. Refer to the documentation of the data technology you are using for more + * details. *

* One of {@link #basePackageClasses()}, {@link #basePackages()} or its alias * {@link #value()} may be specified to define specific packages to scan. If specific @@ -51,7 +36,7 @@ * annotation. * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 * @see EntityScanPackages */ @Target(ElementType.TYPE) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScanPackages.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScanPackages.java index 2d25a00e119f..8988ace90361 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScanPackages.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScanPackages.java @@ -43,7 +43,7 @@ * (e.g. by JPA auto-configuration). * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 * @see EntityScan * @see EntityScanner */ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScanner.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScanner.java index 6ad27aae1a83..c9f30335004a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScanner.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/domain/EntityScanner.java @@ -36,7 +36,7 @@ * specified packages. * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 */ public class EntityScanner { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfiguration.java deleted file mode 100644 index c1688fae9eea..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfiguration.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.elasticsearch; - -import co.elastic.clients.transport.ElasticsearchTransport; -import org.elasticsearch.client.RestClient; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Data Elasticsearch's - * reactive client. - * - * @author Brian Clozel - * @since 3.0.0 - */ -@AutoConfiguration(after = ElasticsearchClientAutoConfiguration.class) -@ConditionalOnBean(RestClient.class) -@ConditionalOnClass({ ReactiveElasticsearchClient.class, ElasticsearchTransport.class, Mono.class }) -@EnableConfigurationProperties(ElasticsearchProperties.class) -@Import({ ElasticsearchClientConfigurations.JsonpMapperConfiguration.class, - ElasticsearchClientConfigurations.ElasticsearchTransportConfiguration.class }) -public class ReactiveElasticsearchClientAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(ElasticsearchTransport.class) - ReactiveElasticsearchClient reactiveElasticsearchClient(ElasticsearchTransport transport) { - return new ReactiveElasticsearchClient(transport); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/package-info.java deleted file mode 100644 index 5db9b82a1495..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Elasticsearch client. - */ -package org.springframework.boot.autoconfigure.elasticsearch; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/package-info.java deleted file mode 100644 index 5ad2047295d5..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Flyway. - */ -package org.springframework.boot.autoconfigure.flyway; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerProperties.java deleted file mode 100644 index 39c3e7141754..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerProperties.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.freemarker; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.autoconfigure.template.AbstractTemplateViewResolverProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * {@link ConfigurationProperties @ConfigurationProperties} for configuring FreeMarker. - * - * @author Dave Syer - * @author Andy Wilkinson - * @since 1.1.0 - */ -@ConfigurationProperties("spring.freemarker") -public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties { - - public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/"; - - public static final String DEFAULT_PREFIX = ""; - - public static final String DEFAULT_SUFFIX = ".ftlh"; - - /** - * Well-known FreeMarker keys which are passed to FreeMarker's Configuration. - */ - private Map settings = new HashMap<>(); - - /** - * List of template paths. - */ - private String[] templateLoaderPath = new String[] { DEFAULT_TEMPLATE_LOADER_PATH }; - - /** - * Whether to prefer file system access for template loading to enable hot detection - * of template changes. When a template path is detected as a directory, templates are - * loaded from the directory only and other matching classpath locations will not be - * considered. - */ - private boolean preferFileSystemAccess; - - public FreeMarkerProperties() { - super(DEFAULT_PREFIX, DEFAULT_SUFFIX); - } - - public Map getSettings() { - return this.settings; - } - - public void setSettings(Map settings) { - this.settings = settings; - } - - public String[] getTemplateLoaderPath() { - return this.templateLoaderPath; - } - - public void setTemplateLoaderPath(String... templateLoaderPaths) { - this.templateLoaderPath = templateLoaderPaths; - } - - public boolean isPreferFileSystemAccess() { - return this.preferFileSystemAccess; - } - - public void setPreferFileSystemAccess(boolean preferFileSystemAccess) { - this.preferFileSystemAccess = preferFileSystemAccess; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/package-info.java deleted file mode 100644 index f2932fca100b..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for FreeMarker. - */ -package org.springframework.boot.autoconfigure.freemarker; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java deleted file mode 100644 index ff41200b2ec1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration classes for data integrations with GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.data; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/package-info.java deleted file mode 100644 index 547623d20610..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/package-info.java deleted file mode 100644 index 8ce45ac969c9..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration classes for WebFlux support in Spring GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/package-info.java deleted file mode 100644 index 9cad8eaabea5..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration classes for RSocket integration with GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.rsocket; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/package-info.java deleted file mode 100644 index 8b53a35c6034..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration classes for Security support in Spring GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.security; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/package-info.java deleted file mode 100644 index 7dacfccc3d0f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration classes for MVC support in Spring GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.servlet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateProperties.java deleted file mode 100644 index da9f904931b1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateProperties.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.groovy.template; - -import java.util.Locale; - -import groovy.text.markup.BaseTemplate; - -import org.springframework.boot.autoconfigure.template.AbstractTemplateViewResolverProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * {@link ConfigurationProperties @ConfigurationProperties} for configuring Groovy - * templates. - * - * @author Dave Syer - * @author Marten Deinum - * @since 1.1.0 - */ -@ConfigurationProperties("spring.groovy.template") -public class GroovyTemplateProperties extends AbstractTemplateViewResolverProperties { - - public static final String DEFAULT_RESOURCE_LOADER_PATH = "classpath:/templates/"; - - public static final String DEFAULT_PREFIX = ""; - - public static final String DEFAULT_SUFFIX = ".tpl"; - - public static final String DEFAULT_REQUEST_CONTEXT_ATTRIBUTE = "spring"; - - /** - * Whether models that are assignable to CharSequence are escaped automatically. - */ - private boolean autoEscape; - - /** - * Whether indents are rendered automatically. - */ - private boolean autoIndent; - - /** - * String used for auto-indents. - */ - private String autoIndentString; - - /** - * Whether new lines are rendered automatically. - */ - private boolean autoNewLine; - - /** - * Template base class. - */ - private Class baseTemplateClass = BaseTemplate.class; - - /** - * Encoding used to write the declaration heading. - */ - private String declarationEncoding; - - /** - * Whether elements without a body should be written expanded (<br></br>) - * or not (<br/>). - */ - private boolean expandEmptyElements; - - /** - * Default locale for template resolution. - */ - private Locale locale; - - /** - * String used to write a new line. Defaults to the system's line separator. - */ - private String newLineString; - - /** - * Template path. - */ - private String resourceLoaderPath = DEFAULT_RESOURCE_LOADER_PATH; - - /** - * Whether attributes should use double quotes. - */ - private boolean useDoubleQuotes; - - public GroovyTemplateProperties() { - super(DEFAULT_PREFIX, DEFAULT_SUFFIX); - setRequestContextAttribute(DEFAULT_REQUEST_CONTEXT_ATTRIBUTE); - } - - public boolean isAutoEscape() { - return this.autoEscape; - } - - public void setAutoEscape(boolean autoEscape) { - this.autoEscape = autoEscape; - } - - public boolean isAutoIndent() { - return this.autoIndent; - } - - public void setAutoIndent(boolean autoIndent) { - this.autoIndent = autoIndent; - } - - public String getAutoIndentString() { - return this.autoIndentString; - } - - public void setAutoIndentString(String autoIndentString) { - this.autoIndentString = autoIndentString; - } - - public boolean isAutoNewLine() { - return this.autoNewLine; - } - - public void setAutoNewLine(boolean autoNewLine) { - this.autoNewLine = autoNewLine; - } - - public Class getBaseTemplateClass() { - return this.baseTemplateClass; - } - - public void setBaseTemplateClass(Class baseTemplateClass) { - this.baseTemplateClass = baseTemplateClass; - } - - public String getDeclarationEncoding() { - return this.declarationEncoding; - } - - public void setDeclarationEncoding(String declarationEncoding) { - this.declarationEncoding = declarationEncoding; - } - - public boolean isExpandEmptyElements() { - return this.expandEmptyElements; - } - - public void setExpandEmptyElements(boolean expandEmptyElements) { - this.expandEmptyElements = expandEmptyElements; - } - - public Locale getLocale() { - return this.locale; - } - - public void setLocale(Locale locale) { - this.locale = locale; - } - - public String getNewLineString() { - return this.newLineString; - } - - public void setNewLineString(String newLineString) { - this.newLineString = newLineString; - } - - public String getResourceLoaderPath() { - return this.resourceLoaderPath; - } - - public void setResourceLoaderPath(String resourceLoaderPath) { - this.resourceLoaderPath = resourceLoaderPath; - } - - public boolean isUseDoubleQuotes() { - return this.useDoubleQuotes; - } - - public void setUseDoubleQuotes(boolean useDoubleQuotes) { - this.useDoubleQuotes = useDoubleQuotes; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/package-info.java deleted file mode 100644 index 2cad38841fc0..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Groovy templates. - */ -package org.springframework.boot.autoconfigure.groovy.template; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/package-info.java deleted file mode 100644 index d28439fe90eb..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for GSON. - */ -package org.springframework.boot.autoconfigure.gson; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/package-info.java deleted file mode 100644 index d0d923e91236..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for H2's Console. - */ -package org.springframework.boot.autoconfigure.h2; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/package-info.java deleted file mode 100644 index e30bf6ca02bf..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring HATEOAS. - */ -package org.springframework.boot.autoconfigure.hateoas; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastJpaDependencyAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastJpaDependencyAutoConfiguration.java deleted file mode 100644 index c1adad06f3dc..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastJpaDependencyAutoConfiguration.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.hazelcast; - -import com.hazelcast.core.HazelcastInstance; -import jakarta.persistence.EntityManagerFactory; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration.HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor; -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Import; -import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; - -/** - * Additional configuration to ensure that {@link EntityManagerFactory} beans depend on - * the {@code hazelcastInstance} bean. - * - * @author Stephane Nicoll - * @since 1.3.2 - */ -@AutoConfiguration(after = { HazelcastAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) -@ConditionalOnClass({ HazelcastInstance.class, LocalContainerEntityManagerFactoryBean.class }) -@Import(HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor.class) -public class HazelcastJpaDependencyAutoConfiguration { - - @Conditional(OnHazelcastAndJpaCondition.class) - static class HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor - extends EntityManagerFactoryDependsOnPostProcessor { - - HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor() { - super("hazelcastInstance"); - } - - } - - static class OnHazelcastAndJpaCondition extends AllNestedConditions { - - OnHazelcastAndJpaCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnBean(name = "hazelcastInstance") - static class HasHazelcastInstance { - - } - - @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) - static class HasJpa { - - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/package-info.java deleted file mode 100644 index 3460a8edac01..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Hazelcast. - */ -package org.springframework.boot.autoconfigure.hazelcast; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/ConditionalOnPreferredJsonMapper.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/ConditionalOnPreferredJsonMapper.java deleted file mode 100644 index 076aa3f5b738..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/ConditionalOnPreferredJsonMapper.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Conditional; - -/** - * {@link Conditional @Conditional} that matches based on the preferred JSON mapper. A - * preference is expressed using the {@code spring.http.converters.preferred-json-mapper} - * configuration property, falling back to the - * {@code spring.mvc.converters.preferred-json-mapper} configuration property. When no - * preference is expressed Jackson is preferred by default. - * - * @author Andy Wilkinson - */ -@Conditional(OnPreferredJsonMapperCondition.class) -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Documented -@interface ConditionalOnPreferredJsonMapper { - - JsonMapper value(); - - enum JsonMapper { - - GSON, - - JACKSON, - - JSONB, - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/OnPreferredJsonMapperCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/OnPreferredJsonMapperCondition.java deleted file mode 100644 index f779bf3ea2a5..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/OnPreferredJsonMapperCondition.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http; - -import java.util.Locale; - -import org.springframework.boot.autoconfigure.condition.ConditionMessage; -import org.springframework.boot.autoconfigure.condition.ConditionOutcome; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.autoconfigure.http.ConditionalOnPreferredJsonMapper.JsonMapper; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.core.env.Environment; -import org.springframework.core.type.AnnotatedTypeMetadata; - -/** - * {@link SpringBootCondition} for - * {@link ConditionalOnPreferredJsonMapper @ConditionalOnPreferredJsonMapper}. - * - * @author Andy Wilkinson - */ -class OnPreferredJsonMapperCondition extends SpringBootCondition { - - private static final String PREFERRED_MAPPER_PROPERTY = "spring.http.converters.preferred-json-mapper"; - - @Deprecated(since = "3.5.0", forRemoval = true) - private static final String DEPRECATED_PREFERRED_MAPPER_PROPERTY = "spring.mvc.converters.preferred-json-mapper"; - - @Override - public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { - JsonMapper conditionMapper = metadata.getAnnotations() - .get(ConditionalOnPreferredJsonMapper.class) - .getEnum("value", JsonMapper.class); - ConditionOutcome outcome = getMatchOutcome(context.getEnvironment(), PREFERRED_MAPPER_PROPERTY, - conditionMapper); - if (outcome != null) { - return outcome; - } - outcome = getMatchOutcome(context.getEnvironment(), DEPRECATED_PREFERRED_MAPPER_PROPERTY, conditionMapper); - if (outcome != null) { - return outcome; - } - ConditionMessage message = ConditionMessage - .forCondition(ConditionalOnPreferredJsonMapper.class, conditionMapper.name()) - .because("no property was configured and Jackson is the default"); - return (conditionMapper == JsonMapper.JACKSON) ? ConditionOutcome.match(message) - : ConditionOutcome.noMatch(message); - } - - private ConditionOutcome getMatchOutcome(Environment environment, String key, JsonMapper conditionMapper) { - String property = environment.getProperty(key); - if (property == null) { - return null; - } - JsonMapper configuredMapper = JsonMapper.valueOf(property.toUpperCase(Locale.ROOT)); - ConditionMessage message = ConditionMessage - .forCondition(ConditionalOnPreferredJsonMapper.class, configuredMapper.name()) - .because("property '%s' had the value '%s'".formatted(key, property)); - return (configuredMapper == conditionMapper) ? ConditionOutcome.match(message) - : ConditionOutcome.noMatch(message); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/AbstractHttpClientProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/AbstractHttpClientProperties.java deleted file mode 100644 index d0ba8bae2c83..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/AbstractHttpClientProperties.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client; - -import java.time.Duration; - -import org.springframework.boot.http.client.HttpClientSettings; -import org.springframework.boot.http.client.HttpRedirects; - -/** - * Abstract base class for properties that directly or indirectly make use of a blocking - * or reactive HTTP client. - * - * @author Phillip Webb - * @since 3.5.0 - * @see HttpClientSettings - */ -public abstract class AbstractHttpClientProperties { - - /** - * Handling for HTTP redirects. - */ - private HttpRedirects redirects; - - /** - * Default connect timeout for a client HTTP request. - */ - private Duration connectTimeout; - - /** - * Default read timeout for a client HTTP request. - */ - private Duration readTimeout; - - /** - * Default SSL configuration for a client HTTP request. - */ - private final Ssl ssl = new Ssl(); - - public HttpRedirects getRedirects() { - return this.redirects; - } - - public void setRedirects(HttpRedirects redirects) { - this.redirects = redirects; - } - - public Duration getConnectTimeout() { - return this.connectTimeout; - } - - public void setConnectTimeout(Duration connectTimeout) { - this.connectTimeout = connectTimeout; - } - - public Duration getReadTimeout() { - return this.readTimeout; - } - - public void setReadTimeout(Duration readTimeout) { - this.readTimeout = readTimeout; - } - - public Ssl getSsl() { - return this.ssl; - } - - /** - * SSL configuration. - */ - public static class Ssl { - - /** - * SSL bundle to use. - */ - private String bundle; - - public String getBundle() { - return this.bundle; - } - - public void setBundle(String bundle) { - this.bundle = bundle; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/AbstractHttpRequestFactoryProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/AbstractHttpRequestFactoryProperties.java deleted file mode 100644 index 2ed3a810d98c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/AbstractHttpRequestFactoryProperties.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client; - -import java.util.function.Supplier; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; -import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; -import org.springframework.http.client.ClientHttpRequestFactory; - -/** - * Base {@link ConfigurationProperties @ConfigurationProperties} for configuring a - * {@link ClientHttpRequestFactory}. - * - * @author Phillip Webb - * @since 3.5.0 - * @see ClientHttpRequestFactorySettings - */ -public abstract class AbstractHttpRequestFactoryProperties extends AbstractHttpClientProperties { - - /** - * Default factory used for a client HTTP request. - */ - private Factory factory; - - public Factory getFactory() { - return this.factory; - } - - public void setFactory(Factory factory) { - this.factory = factory; - } - - /** - * Supported factory types. - */ - public enum Factory { - - /** - * Apache HttpComponents HttpClient. - */ - HTTP_COMPONENTS(ClientHttpRequestFactoryBuilder::httpComponents), - - /** - * Jetty's HttpClient. - */ - JETTY(ClientHttpRequestFactoryBuilder::jetty), - - /** - * Reactor-Netty. - */ - REACTOR(ClientHttpRequestFactoryBuilder::reactor), - - /** - * Java's HttpClient. - */ - JDK(ClientHttpRequestFactoryBuilder::jdk), - - /** - * Standard JDK facilities. - */ - SIMPLE(ClientHttpRequestFactoryBuilder::simple); - - private final Supplier> builderSupplier; - - Factory(Supplier> builderSupplier) { - this.builderSupplier = builderSupplier; - } - - ClientHttpRequestFactoryBuilder builder() { - return this.builderSupplier.get(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactories.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactories.java deleted file mode 100644 index fd260b35059d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactories.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client; - -import java.time.Duration; -import java.util.Objects; -import java.util.function.Function; -import java.util.function.Predicate; - -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.boot.autoconfigure.http.client.AbstractHttpClientProperties.Ssl; -import org.springframework.boot.autoconfigure.http.client.AbstractHttpRequestFactoryProperties.Factory; -import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; -import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; -import org.springframework.boot.http.client.HttpRedirects; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslBundles; -import org.springframework.util.StringUtils; - -/** - * Helper class to create {@link ClientHttpRequestFactoryBuilder} and - * {@link ClientHttpRequestFactorySettings}. - * - * @author Phillip Webb - * @since 4.0.0 - */ -public final class ClientHttpRequestFactories { - - private final ObjectFactory sslBundles; - - private final AbstractHttpRequestFactoryProperties[] orderedProperties; - - public ClientHttpRequestFactories(ObjectFactory sslBundles, - AbstractHttpRequestFactoryProperties... orderedProperties) { - this.sslBundles = sslBundles; - this.orderedProperties = orderedProperties; - } - - public ClientHttpRequestFactoryBuilder builder(ClassLoader classLoader) { - Factory factory = getProperty(AbstractHttpRequestFactoryProperties::getFactory); - return (factory != null) ? factory.builder() : ClientHttpRequestFactoryBuilder.detect(classLoader); - } - - public ClientHttpRequestFactorySettings settings() { - HttpRedirects redirects = getProperty(AbstractHttpRequestFactoryProperties::getRedirects); - Duration connectTimeout = getProperty(AbstractHttpRequestFactoryProperties::getConnectTimeout); - Duration readTimeout = getProperty(AbstractHttpRequestFactoryProperties::getReadTimeout); - String sslBundleName = getProperty(AbstractHttpRequestFactoryProperties::getSsl, Ssl::getBundle, - StringUtils::hasLength); - SslBundle sslBundle = (StringUtils.hasLength(sslBundleName)) - ? this.sslBundles.getObject().getBundle(sslBundleName) : null; - return new ClientHttpRequestFactorySettings(redirects, connectTimeout, readTimeout, sslBundle); - } - - private T getProperty(Function accessor) { - return getProperty(accessor, Function.identity(), Objects::nonNull); - } - - private T getProperty(Function accessor, Function extractor, - Predicate predicate) { - for (AbstractHttpRequestFactoryProperties properties : this.orderedProperties) { - if (properties != null) { - P value = accessor.apply(properties); - T extracted = (value != null) ? extractor.apply(value) : null; - if (predicate.test(extracted)) { - return extracted; - } - } - } - return null; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/NotReactiveWebApplicationCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/NotReactiveWebApplicationCondition.java deleted file mode 100644 index c3369362175f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/NotReactiveWebApplicationCondition.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; - -/** - * {@link SpringBootCondition} that applies only when running in a non-reactive web - * application. - * - * @author Phillip Webb - */ -class NotReactiveWebApplicationCondition extends NoneNestedConditions { - - NotReactiveWebApplicationCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - private static final class ReactiveWebApplication { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/package-info.java deleted file mode 100644 index a17ff86ba7f0..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for client-side HTTP. - */ -package org.springframework.boot.autoconfigure.http.client; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/AbstractClientHttpConnectorProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/AbstractClientHttpConnectorProperties.java deleted file mode 100644 index 3cad344c9906..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/AbstractClientHttpConnectorProperties.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client.reactive; - -import java.util.function.Supplier; - -import org.springframework.boot.autoconfigure.http.client.AbstractHttpClientProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; -import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; -import org.springframework.http.client.reactive.ClientHttpConnector; - -/** - * Base {@link ConfigurationProperties @ConfigurationProperties} for configuring a - * {@link ClientHttpConnector}. - * - * @author Phillip Webb - * @since 3.5.0 - * @see ClientHttpConnectorSettings - */ -public abstract class AbstractClientHttpConnectorProperties extends AbstractHttpClientProperties { - - /** - * Default connector used for a client HTTP request. - */ - private Connector connector; - - public Connector getConnector() { - return this.connector; - } - - public void setConnector(Connector connector) { - this.connector = connector; - } - - /** - * Supported factory types. - */ - public enum Connector { - - /** - * Reactor-Netty. - */ - REACTOR(ClientHttpConnectorBuilder::reactor), - - /** - * Jetty's HttpClient. - */ - JETTY(ClientHttpConnectorBuilder::jetty), - - /** - * Apache HttpComponents HttpClient. - */ - HTTP_COMPONENTS(ClientHttpConnectorBuilder::httpComponents), - - /** - * Java's HttpClient. - */ - JDK(ClientHttpConnectorBuilder::jdk); - - private final Supplier> builderSupplier; - - Connector(Supplier> builderSupplier) { - this.builderSupplier = builderSupplier; - } - - ClientHttpConnectorBuilder builder() { - return this.builderSupplier.get(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfiguration.java deleted file mode 100644 index 7c2770d0bdd0..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfiguration.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client.reactive; - -import java.util.List; - -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigurations; -import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; -import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; -import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.util.LambdaSafe; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Lazy; -import org.springframework.http.client.reactive.ClientHttpConnector; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for - * {@link ClientHttpConnectorBuilder} and {@link ClientHttpConnectorSettings}. - * - * @author Phillip Webb - * @since 3.5.0 - */ -@AutoConfiguration(after = SslAutoConfiguration.class) -@ConditionalOnClass({ ClientHttpConnector.class, Mono.class }) -@Conditional(ConditionalOnClientHttpConnectorBuilderDetection.class) -@EnableConfigurationProperties(HttpReactiveClientProperties.class) -public class ClientHttpConnectorAutoConfiguration implements BeanClassLoaderAware { - - private final ClientHttpConnectors connectors; - - private ClassLoader beanClassLoader; - - ClientHttpConnectorAutoConfiguration(ObjectProvider sslBundles, - HttpReactiveClientProperties properties) { - this.connectors = new ClientHttpConnectors(sslBundles, properties); - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - - @Bean - @ConditionalOnMissingBean - ClientHttpConnectorBuilder clientHttpConnectorBuilder( - ObjectProvider> clientHttpConnectorBuilderCustomizers) { - ClientHttpConnectorBuilder builder = this.connectors.builder(this.beanClassLoader); - return customize(builder, clientHttpConnectorBuilderCustomizers.orderedStream().toList()); - } - - @SuppressWarnings("unchecked") - private ClientHttpConnectorBuilder customize(ClientHttpConnectorBuilder builder, - List> customizers) { - ClientHttpConnectorBuilder[] builderReference = { builder }; - LambdaSafe.callbacks(ClientHttpConnectorBuilderCustomizer.class, customizers, builderReference[0]) - .invoke((customizer) -> builderReference[0] = customizer.customize(builderReference[0])); - return builderReference[0]; - } - - @Bean - @ConditionalOnMissingBean - ClientHttpConnectorSettings clientHttpConnectorSettings() { - return this.connectors.settings(); - } - - @Bean - @Lazy - @ConditionalOnMissingBean - ClientHttpConnector clientHttpConnector(ClientHttpConnectorBuilder clientHttpConnectorBuilder, - ClientHttpConnectorSettings clientHttpRequestFactorySettings) { - return clientHttpConnectorBuilder.build(clientHttpRequestFactorySettings); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(reactor.netty.http.client.HttpClient.class) - @Import(ReactorNettyConfigurations.ReactorResourceFactoryConfiguration.class) - static class ReactorNetty { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/package-info.java deleted file mode 100644 index 762e5cc4b14c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for client-side reactive HTTP. - */ -package org.springframework.boot.autoconfigure.http.client.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/package-info.java deleted file mode 100644 index 20df40a9f00c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-Configuration for Spring's Reactive HTTP Service Interface Clients. - */ -package org.springframework.boot.autoconfigure.http.client.reactive.service; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/NotReactiveWebApplicationCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/NotReactiveWebApplicationCondition.java deleted file mode 100644 index b209f5166655..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/NotReactiveWebApplicationCondition.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client.service; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; - -/** - * {@link SpringBootCondition} that applies only when running in a non-reactive web - * application. - * - * @author Phillip Webb - */ -class NotReactiveWebApplicationCondition extends NoneNestedConditions { - - NotReactiveWebApplicationCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - private static final class ReactiveWebApplication { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/package-info.java deleted file mode 100644 index f0a4dff7a320..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-Configuration for Spring's Blocking HTTP Service Interface Clients. - */ -package org.springframework.boot.autoconfigure.http.client.service; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/HttpCodecsProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/HttpCodecsProperties.java deleted file mode 100644 index d8f37612e236..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/HttpCodecsProperties.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.codec; - -import java.util.function.Supplier; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.unit.DataSize; - -/** - * {@link ConfigurationProperties Properties} for reactive HTTP codecs. - * - * @author Brian Clozel - * @author Andy Wilkinson - * @since 3.5.0 - */ -@ConfigurationProperties("spring.http.codecs") -public class HttpCodecsProperties { - - /** - * Whether to log form data at DEBUG level, and headers at TRACE level. - */ - private boolean logRequestDetails; - - @Deprecated(since = "3.5.0", forRemoval = true) - private boolean logRequestDetailsBound = false; - - /** - * Limit on the number of bytes that can be buffered whenever the input stream needs - * to be aggregated. This applies only to the auto-configured WebFlux server and - * WebClient instances. By default this is not set, in which case individual codec - * defaults apply. Most codecs are limited to 256K by default. - */ - private DataSize maxInMemorySize; - - @Deprecated(since = "3.5.0", forRemoval = true) - private boolean maxInMemorySizeBound = false; - - public boolean isLogRequestDetails() { - return this.logRequestDetails; - } - - boolean isLogRequestDetails(Supplier fallback) { - return this.logRequestDetailsBound ? this.logRequestDetails : fallback.get(); - } - - public void setLogRequestDetails(boolean logRequestDetails) { - this.logRequestDetails = logRequestDetails; - this.logRequestDetailsBound = true; - } - - public DataSize getMaxInMemorySize() { - return this.maxInMemorySize; - } - - DataSize getMaxInMemorySize(Supplier fallback) { - return this.maxInMemorySizeBound ? this.maxInMemorySize : fallback.get(); - } - - public void setMaxInMemorySize(DataSize maxInMemorySize) { - this.maxInMemorySize = maxInMemorySize; - this.maxInMemorySizeBound = true; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/package-info.java deleted file mode 100644 index 480f0cb82236..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for HTTP codecs. - */ -package org.springframework.boot.autoconfigure.http.codec; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/package-info.java deleted file mode 100644 index 6bb3c7a9232e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for HTTP concerns. - */ -package org.springframework.boot.autoconfigure.http; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/package-info.java deleted file mode 100644 index 096d1949677a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Integration. - */ -package org.springframework.boot.autoconfigure.integration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/package-info.java deleted file mode 100644 index 91c44e64966a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Jackson. - */ -package org.springframework.boot.autoconfigure.jackson; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/metadata/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/metadata/package-info.java deleted file mode 100644 index 127eea6cf43e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/metadata/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for JDBC Metadata. - */ -package org.springframework.boot.autoconfigure.jdbc.metadata; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/package-info.java deleted file mode 100644 index 7ccc4d2c0da0..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for JDBC. - */ -package org.springframework.boot.autoconfigure.jdbc; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/package-info.java deleted file mode 100644 index 86731decb8e8..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Jersey. - */ -package org.springframework.boot.autoconfigure.jersey; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/package-info.java deleted file mode 100644 index 986c29ae290e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for ActiveMQ. - */ -package org.springframework.boot.autoconfigure.jms.activemq; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/package-info.java deleted file mode 100644 index 1ab6f2b19c79..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Artemis. - * - * @author Eddú Meléndez - */ -package org.springframework.boot.autoconfigure.jms.artemis; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/package-info.java deleted file mode 100644 index 612b34c016b4..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for JMS. - */ -package org.springframework.boot.autoconfigure.jms; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java deleted file mode 100644 index 5e2468264830..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for jOOQ. - */ -package org.springframework.boot.autoconfigure.jooq; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jsonb/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jsonb/package-info.java deleted file mode 100644 index dbffa9c75522..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jsonb/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for JSON-B. - */ -package org.springframework.boot.autoconfigure.jsonb; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaConnectionDetails.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaConnectionDetails.java deleted file mode 100644 index e5f58f8a76ad..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaConnectionDetails.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.kafka; - -import java.util.List; - -import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; -import org.springframework.boot.ssl.SslBundle; - -/** - * Details required to establish a connection to a Kafka service. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @since 3.1.0 - */ -public interface KafkaConnectionDetails extends ConnectionDetails { - - /** - * Returns the list of bootstrap servers. - * @return the list of bootstrap servers - */ - List getBootstrapServers(); - - /** - * Returns the SSL bundle. - * @return the SSL bundle - * @since 3.5.0 - */ - default SslBundle getSslBundle() { - return null; - } - - /** - * Returns the security protocol. - * @return the security protocol - * @since 3.5.0 - */ - default String getSecurityProtocol() { - return null; - } - - /** - * Returns the consumer configuration. - * @return the consumer configuration - * @since 3.5.0 - */ - default Configuration getConsumer() { - return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol()); - } - - /** - * Returns the producer configuration. - * @return the producer configuration - * @since 3.5.0 - */ - default Configuration getProducer() { - return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol()); - } - - /** - * Returns the admin configuration. - * @return the admin configuration - * @since 3.5.0 - */ - default Configuration getAdmin() { - return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol()); - } - - /** - * Returns the Kafka Streams configuration. - * @return the Kafka Streams configuration - * @since 3.5.0 - */ - default Configuration getStreams() { - return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol()); - } - - /** - * Returns the list of bootstrap servers used for consumers. - * @return the list of bootstrap servers used for consumers - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link #getConsumer()} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - default List getConsumerBootstrapServers() { - return getConsumer().getBootstrapServers(); - } - - /** - * Returns the list of bootstrap servers used for producers. - * @return the list of bootstrap servers used for producers - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link #getProducer()} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - default List getProducerBootstrapServers() { - return getProducer().getBootstrapServers(); - } - - /** - * Returns the list of bootstrap servers used for the admin. - * @return the list of bootstrap servers used for the admin - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link #getAdmin()} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - default List getAdminBootstrapServers() { - return getAdmin().getBootstrapServers(); - } - - /** - * Returns the list of bootstrap servers used for Kafka Streams. - * @return the list of bootstrap servers used for Kafka Streams - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link #getStreams()} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - default List getStreamsBootstrapServers() { - return getStreams().getBootstrapServers(); - } - - /** - * Kafka connection details configuration. - */ - interface Configuration { - - /** - * Creates a new configuration with the given bootstrap servers. - * @param bootstrapServers the bootstrap servers - * @return the configuration - */ - static Configuration of(List bootstrapServers) { - return Configuration.of(bootstrapServers, null, null); - } - - /** - * Creates a new configuration with the given bootstrap servers and SSL bundle. - * @param bootstrapServers the bootstrap servers - * @param sslBundle the SSL bundle - * @return the configuration - */ - static Configuration of(List bootstrapServers, SslBundle sslBundle) { - return Configuration.of(bootstrapServers, sslBundle, null); - } - - /** - * Creates a new configuration with the given bootstrap servers, SSL bundle and - * security protocol. - * @param bootstrapServers the bootstrap servers - * @param sslBundle the SSL bundle - * @param securityProtocol the security protocol - * @return the configuration - */ - static Configuration of(List bootstrapServers, SslBundle sslBundle, String securityProtocol) { - return new Configuration() { - @Override - public List getBootstrapServers() { - return bootstrapServers; - } - - @Override - public SslBundle getSslBundle() { - return sslBundle; - } - - @Override - public String getSecurityProtocol() { - return securityProtocol; - } - }; - } - - /** - * Returns the list of bootstrap servers. - * @return the list of bootstrap servers - */ - List getBootstrapServers(); - - /** - * Returns the SSL bundle. - * @return the SSL bundle - */ - default SslBundle getSslBundle() { - return null; - } - - /** - * Returns the security protocol. - * @return the security protocol - */ - default String getSecurityProtocol() { - return null; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/package-info.java deleted file mode 100644 index 3c184d8532e6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Apache Kafka. - */ -package org.springframework.boot.autoconfigure.kafka; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/package-info.java deleted file mode 100644 index 0cdfe46e0a23..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for embedded LDAP. - */ -package org.springframework.boot.autoconfigure.ldap.embedded; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/package-info.java deleted file mode 100644 index 5466ab737de8..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for LDAP. - */ -package org.springframework.boot.autoconfigure.ldap; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/package-info.java deleted file mode 100644 index fbfe2f34bfb7..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Liquibase. - */ -package org.springframework.boot.autoconfigure.liquibase; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/package-info.java deleted file mode 100644 index d900682baa34..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for email support. - */ -package org.springframework.boot.autoconfigure.mail; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/package-info.java deleted file mode 100644 index 511b6efede03..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for MongoDB. - */ -package org.springframework.boot.autoconfigure.mongo; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/package-info.java deleted file mode 100644 index c6bdd286ae11..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Mustache. - */ -package org.springframework.boot.autoconfigure.mustache; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/package-info.java deleted file mode 100644 index b26d9e5ccd4c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Neo4j. - */ -package org.springframework.boot.autoconfigure.neo4j; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/package-info.java deleted file mode 100644 index 024563545766..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for the Netty library. - */ -package org.springframework.boot.autoconfigure.netty; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java deleted file mode 100644 index 2bcb91af5ae1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.orm.jpa; - -import jakarta.persistence.EntityManager; -import org.hibernate.engine.spi.SessionImplementor; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Import; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Hibernate JPA. - * - * @author Phillip Webb - * @author Josh Long - * @author Manuel Doninger - * @author Andy Wilkinson - * @since 1.0.0 - */ -@AutoConfiguration( - after = { DataSourceAutoConfiguration.class, TransactionManagerCustomizationAutoConfiguration.class }, - before = { TransactionAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class }) -@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EntityManager.class, SessionImplementor.class }) -@EnableConfigurationProperties(JpaProperties.class) -@Import(HibernateJpaConfiguration.class) -public class HibernateJpaAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/package-info.java deleted file mode 100644 index 41f8d5117ade..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for JPA and Spring ORM. - */ -package org.springframework.boot.autoconfigure.orm.jpa; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/BackgroundPreinitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/BackgroundPreinitializer.java new file mode 100644 index 000000000000..4aaac2499f35 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/BackgroundPreinitializer.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.preinitialize; + +/** + * Interface used to preinitialize in the background code that may otherwise cause a delay + * when first called. Implementations should be registered in {@code spring.factories}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +@FunctionalInterface +public interface BackgroundPreinitializer { + + /** + * Perform any require preinitialization. + * @throws Exception on any initialization error + */ + void preinitialize() throws Exception; + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/BackgroundPreinitializingApplicationListener.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/BackgroundPreinitializingApplicationListener.java new file mode 100644 index 000000000000..7b6c2faf7e1d --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/BackgroundPreinitializingApplicationListener.java @@ -0,0 +1,133 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.preinitialize; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.boot.context.event.ApplicationFailedEvent; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.boot.context.event.SpringApplicationEvent; +import org.springframework.boot.context.logging.LoggingApplicationListener; +import org.springframework.context.ApplicationListener; +import org.springframework.core.NativeDetector; +import org.springframework.core.Ordered; +import org.springframework.core.io.support.SpringFactoriesLoader; + +/** + * {@link ApplicationListener} to trigger early initialization in a background thread of + * time-consuming tasks. + *

+ * Set the {@link #IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME} system property to + * {@code true} to disable this mechanism. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Artsiom Yudovin + * @author Sebastien Deleuze + * @see BackgroundPreinitializer + */ +class BackgroundPreinitializingApplicationListener implements ApplicationListener, Ordered { + + /** + * System property that instructs Spring Boot how to run pre initialization. When the + * property is set to {@code true}, no pre-initialization happens and each item is + * initialized in the foreground as it needs to. When the property is {@code false} + * (default), pre initialization runs in a separate thread in the background. + */ + public static final String IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME = "spring.backgroundpreinitializer.ignore"; + + private static final AtomicBoolean started = new AtomicBoolean(); + + private static final CountDownLatch complete = new CountDownLatch(1); + + private final SpringFactoriesLoader factoriesLoader; + + private final boolean enabled; + + BackgroundPreinitializingApplicationListener() { + this(SpringFactoriesLoader.forDefaultResourceLocation()); + } + + BackgroundPreinitializingApplicationListener(SpringFactoriesLoader factoriesLoader) { + this.factoriesLoader = factoriesLoader; + this.enabled = !NativeDetector.inNativeImage() + && !Boolean.getBoolean(IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME) + && Runtime.getRuntime().availableProcessors() > 1; + } + + @Override + public int getOrder() { + return LoggingApplicationListener.DEFAULT_ORDER + 1; + } + + @Override + public void onApplicationEvent(SpringApplicationEvent event) { + if (!this.enabled) { + return; + } + if (event instanceof ApplicationEnvironmentPreparedEvent && started.compareAndSet(false, true)) { + preinitialize(); + } + if ((event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent) && started.get()) { + try { + complete.await(); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + } + + private void preinitialize() { + Runner runner = new Runner(this.factoriesLoader.load(BackgroundPreinitializer.class)); + try { + Thread thread = new Thread(runner, "background-preinit"); + thread.start(); + } + catch (Exception ex) { + // This will fail on Google App Engine where creating threads is + // prohibited. We can safely continue but startup will be slightly slower + // as the initialization will now happen on the main thread. + complete.countDown(); + } + } + + /** + * Runner thread to call the {@link BackgroundPreinitializer} instances. + * + * @param preinitializers the preinitializers + */ + record Runner(List preinitializers) implements Runnable { + + @Override + public void run() { + for (BackgroundPreinitializer preinitializer : this.preinitializers) { + try { + preinitializer.preinitialize(); + } + catch (Throwable ex) { + } + } + complete.countDown(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/CharsetsBackgroundPreinitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/CharsetsBackgroundPreinitializer.java new file mode 100644 index 000000000000..ad8ee6226610 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/CharsetsBackgroundPreinitializer.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.preinitialize; + +import java.nio.charset.StandardCharsets; + +/** + * {@link BackgroundPreinitializer} for commonly used charsets. + * + * @author Phillip Webb + */ +final class CharsetsBackgroundPreinitializer implements BackgroundPreinitializer { + + @Override + public void preinitialize() throws Exception { + StandardCharsets.UTF_8.name(); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/ConversionServiceBackgroundPreinitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/ConversionServiceBackgroundPreinitializer.java new file mode 100644 index 000000000000..794de32c0421 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/ConversionServiceBackgroundPreinitializer.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.preinitialize; + +import org.springframework.core.convert.ConversionService; +import org.springframework.format.support.DefaultFormattingConversionService; + +/** + * {@link BackgroundPreinitializer} for Spring's {@link ConversionService}. + * + * @author Phillip Webb + */ +final class ConversionServiceBackgroundPreinitializer implements BackgroundPreinitializer { + + @Override + public void preinitialize() throws Exception { + new DefaultFormattingConversionService(); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/ZoneIdBackgroundPreinitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/ZoneIdBackgroundPreinitializer.java new file mode 100644 index 000000000000..78eb621e37d9 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/ZoneIdBackgroundPreinitializer.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.preinitialize; + +import java.time.ZoneId; + +/** + * {@link BackgroundPreinitializer} for {@link ZoneId}. + * + * @author Phillip Webb + */ +final class ZoneIdBackgroundPreinitializer implements BackgroundPreinitializer { + + @Override + public void preinitialize() throws Exception { + ZoneId.systemDefault(); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/package-info.java new file mode 100644 index 000000000000..e7355136f185 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/preinitialize/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Capabilities to preinitialize code in the background to improve startup performance. + */ +package org.springframework.boot.autoconfigure.preinitialize; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/package-info.java deleted file mode 100644 index 577190f29a8e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring for Apache Pulsar. - */ -package org.springframework.boot.autoconfigure.pulsar; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/package-info.java deleted file mode 100644 index d9c5af25ed42..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Quartz Scheduler. - */ -package org.springframework.boot.autoconfigure.quartz; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/package-info.java deleted file mode 100644 index 11aab683aa5a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-Configuration for R2DBC. - */ -package org.springframework.boot.autoconfigure.r2dbc; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/package-info.java deleted file mode 100644 index 43e932c38d2c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Reactor Netty. - */ -package org.springframework.boot.autoconfigure.reactor.netty; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/package-info.java deleted file mode 100644 index c5bf612c88bb..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Reactor. - */ -package org.springframework.boot.autoconfigure.reactor; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/package-info.java deleted file mode 100644 index cb93fb851123..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for RSocket. - */ -package org.springframework.boot.autoconfigure.rsocket; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientAutoConfiguration.java deleted file mode 100644 index afdb477cd83e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientAutoConfiguration.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.oauth2.client; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration.NonReactiveWebApplicationCondition; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Import; -import org.springframework.security.oauth2.client.registration.ClientRegistration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for OAuth client support. - * - * @author Madhura Bhave - * @author Phillip Webb - * @since 3.5.0 - */ -@AutoConfiguration -@Conditional(NonReactiveWebApplicationCondition.class) -@ConditionalOnClass(ClientRegistration.class) -@Import({ OAuth2ClientConfigurations.ClientRegistrationRepositoryConfiguration.class, - OAuth2ClientConfigurations.OAuth2AuthorizedClientServiceConfiguration.class }) -public class OAuth2ClientAutoConfiguration { - - static class NonReactiveWebApplicationCondition extends NoneNestedConditions { - - NonReactiveWebApplicationCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - static class ReactiveWebApplicationCondition { - - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/package-info.java deleted file mode 100644 index 62caf80dff1d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for Spring Security's OAuth 2 client. - */ -package org.springframework.boot.autoconfigure.security.oauth2.client; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/package-info.java deleted file mode 100644 index a8043e37933e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Security's Reactive OAuth 2 client. - */ -package org.springframework.boot.autoconfigure.security.oauth2.client.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientAutoConfiguration.java deleted file mode 100644 index d5d3fb7c1c19..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientAutoConfiguration.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.oauth2.client.servlet; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for OAuth client support. - * - * @author Madhura Bhave - * @author Phillip Webb - * @since 2.0.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration} - */ -@Deprecated(since = "3.5.0", forRemoval = true) -public class OAuth2ClientAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/package-info.java deleted file mode 100644 index 12b1ba661ff1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Security's OAuth 2 client. - */ -package org.springframework.boot.autoconfigure.security.oauth2.client.servlet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/package-info.java deleted file mode 100644 index 7fbb46d392b1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for Spring Security's OAuth2 resource server. - */ -package org.springframework.boot.autoconfigure.security.oauth2.resource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfiguration.java deleted file mode 100644 index d2890e3880c3..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Import; -import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Reactive OAuth2 resource server - * support. - * - * @author Madhura Bhave - * @since 2.1.0 - */ -@AutoConfiguration( - before = { ReactiveSecurityAutoConfiguration.class, ReactiveUserDetailsServiceAutoConfiguration.class }) -@EnableConfigurationProperties(OAuth2ResourceServerProperties.class) -@ConditionalOnClass({ EnableWebFluxSecurity.class }) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@Import({ ReactiveOAuth2ResourceServerConfiguration.JwtConfiguration.class, - ReactiveOAuth2ResourceServerConfiguration.OpaqueTokenConfiguration.class }) -public class ReactiveOAuth2ResourceServerAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/package-info.java deleted file mode 100644 index 8c22c652abb2..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Security's Reactive OAuth2 resource server. - */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfiguration.java deleted file mode 100644 index 61c762817c30..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Import; -import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for OAuth2 resource server support. - * - * @author Madhura Bhave - * @since 2.1.0 - */ -@AutoConfiguration(before = { SecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class }) -@EnableConfigurationProperties(OAuth2ResourceServerProperties.class) -@ConditionalOnClass(BearerTokenAuthenticationToken.class) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@Import({ Oauth2ResourceServerConfiguration.JwtConfiguration.class, - Oauth2ResourceServerConfiguration.OpaqueTokenConfiguration.class }) -public class OAuth2ResourceServerAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/package-info.java deleted file mode 100644 index 391efec90942..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Security's OAuth2 resource server. - */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/package-info.java deleted file mode 100644 index e8254cfd7920..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Security's OAuth2 authorization server. - */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/package-info.java deleted file mode 100644 index c63ec3f3d563..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Security. - */ -package org.springframework.boot.autoconfigure.security; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/PathRequest.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/PathRequest.java deleted file mode 100644 index 25167e912f00..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/PathRequest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.reactive; - -import org.springframework.boot.autoconfigure.security.StaticResourceLocation; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; - -/** - * Factory that can be used to create a {@link ServerWebExchangeMatcher} for commonly used - * paths. - * - * @author Madhura Bhave - * @since 2.0.0 - */ -public final class PathRequest { - - private PathRequest() { - } - - /** - * Returns a {@link StaticResourceRequest} that can be used to create a matcher for - * {@link StaticResourceLocation locations}. - * @return a {@link StaticResourceRequest} - */ - public static StaticResourceRequest toStaticResources() { - return StaticResourceRequest.INSTANCE; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/StaticResourceRequest.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/StaticResourceRequest.java deleted file mode 100644 index 2aa254b8dd3e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/StaticResourceRequest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.reactive; - -import java.util.EnumSet; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.stream.Stream; - -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.security.StaticResourceLocation; -import org.springframework.security.web.server.util.matcher.OrServerWebExchangeMatcher; -import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; -import org.springframework.util.Assert; -import org.springframework.web.server.ServerWebExchange; - -/** - * Used to create a {@link ServerWebExchangeMatcher} for static resources in commonly used - * locations. Returned by {@link PathRequest#toStaticResources()}. - * - * @author Madhura Bhave - * @since 2.0.0 - * @see PathRequest - */ -public final class StaticResourceRequest { - - static final StaticResourceRequest INSTANCE = new StaticResourceRequest(); - - private StaticResourceRequest() { - } - - /** - * Returns a matcher that includes all commonly used {@link StaticResourceLocation - * Locations}. The - * {@link StaticResourceServerWebExchange#excluding(StaticResourceLocation, StaticResourceLocation...) - * excluding} method can be used to remove specific locations if required. For - * example:

-	 * PathRequest.toStaticResources().atCommonLocations().excluding(StaticResourceLocation.CSS)
-	 * 
- * @return the configured {@link ServerWebExchangeMatcher} - */ - public StaticResourceServerWebExchange atCommonLocations() { - return at(EnumSet.allOf(StaticResourceLocation.class)); - } - - /** - * Returns a matcher that includes the specified {@link StaticResourceLocation - * Locations}. For example:
-	 * PathRequest.toStaticResources().at(StaticResourceLocation.CSS, StaticResourceLocation.JAVA_SCRIPT)
-	 * 
- * @param first the first location to include - * @param rest additional locations to include - * @return the configured {@link ServerWebExchangeMatcher} - */ - public StaticResourceServerWebExchange at(StaticResourceLocation first, StaticResourceLocation... rest) { - return at(EnumSet.of(first, rest)); - } - - /** - * Returns a matcher that includes the specified {@link StaticResourceLocation - * Locations}. For example:
-	 * PathRequest.toStaticResources().at(locations)
-	 * 
- * @param locations the locations to include - * @return the configured {@link ServerWebExchangeMatcher} - */ - public StaticResourceServerWebExchange at(Set locations) { - Assert.notNull(locations, "'locations' must not be null"); - return new StaticResourceServerWebExchange(new LinkedHashSet<>(locations)); - } - - /** - * The server web exchange matcher used to match against resource - * {@link StaticResourceLocation locations}. - */ - public static final class StaticResourceServerWebExchange implements ServerWebExchangeMatcher { - - private final Set locations; - - private StaticResourceServerWebExchange(Set locations) { - this.locations = locations; - } - - /** - * Return a new {@link StaticResourceServerWebExchange} based on this one but - * excluding the specified locations. - * @param first the first location to exclude - * @param rest additional locations to exclude - * @return a new {@link StaticResourceServerWebExchange} - */ - public StaticResourceServerWebExchange excluding(StaticResourceLocation first, StaticResourceLocation... rest) { - return excluding(EnumSet.of(first, rest)); - } - - /** - * Return a new {@link StaticResourceServerWebExchange} based on this one but - * excluding the specified locations. - * @param locations the locations to exclude - * @return a new {@link StaticResourceServerWebExchange} - */ - public StaticResourceServerWebExchange excluding(Set locations) { - Assert.notNull(locations, "'locations' must not be null"); - Set subset = new LinkedHashSet<>(this.locations); - subset.removeAll(locations); - return new StaticResourceServerWebExchange(subset); - } - - private Stream getPatterns() { - return this.locations.stream().flatMap(StaticResourceLocation::getPatterns); - } - - @Override - public Mono matches(ServerWebExchange exchange) { - return new OrServerWebExchangeMatcher(getDelegateMatchers().toList()).matches(exchange); - } - - private Stream getDelegateMatchers() { - return getPatterns().map(PathPatternParserServerWebExchangeMatcher::new); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/package-info.java deleted file mode 100644 index da955c95903e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for reactive Spring Security. - */ -package org.springframework.boot.autoconfigure.security.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/package-info.java deleted file mode 100644 index f1eb4cfd492b..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for RSocket support in Spring Security. - */ -package org.springframework.boot.autoconfigure.security.rsocket; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/package-info.java deleted file mode 100644 index 203ca7d47f85..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Security's SAML 2.0. - */ -package org.springframework.boot.autoconfigure.security.saml2; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/AntPathRequestMatcherProvider.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/AntPathRequestMatcherProvider.java deleted file mode 100644 index 71f5b4202498..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/AntPathRequestMatcherProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.servlet; - -import java.util.function.Function; - -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; - -/** - * {@link RequestMatcherProvider} that provides an {@link AntPathRequestMatcher}. - * - * @author Madhura Bhave - * @since 2.1.8 - * @deprecated since 3.5.0 for removal in 4.0.0 along with {@link RequestMatcherProvider} - */ -@Deprecated(since = "3.5.0", forRemoval = true) -@SuppressWarnings("removal") -public class AntPathRequestMatcherProvider implements RequestMatcherProvider { - - private final Function pathFactory; - - public AntPathRequestMatcherProvider(Function pathFactory) { - this.pathFactory = pathFactory; - } - - @Override - public RequestMatcher getRequestMatcher(String pattern) { - return new AntPathRequestMatcher(this.pathFactory.apply(pattern)); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/PathRequest.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/PathRequest.java deleted file mode 100644 index fd534639eef6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/PathRequest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.servlet; - -import java.util.function.Supplier; - -import jakarta.servlet.http.HttpServletRequest; - -import org.springframework.boot.autoconfigure.h2.H2ConsoleProperties; -import org.springframework.boot.autoconfigure.security.StaticResourceLocation; -import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.web.context.WebApplicationContext; - -/** - * Factory that can be used to create a {@link RequestMatcher} for commonly used paths. - * - * @author Madhura Bhave - * @author Phillip Webb - * @since 2.0.0 - */ -public final class PathRequest { - - private PathRequest() { - } - - /** - * Returns a {@link StaticResourceRequest} that can be used to create a matcher for - * {@link StaticResourceLocation locations}. - * @return a {@link StaticResourceRequest} - */ - public static StaticResourceRequest toStaticResources() { - return StaticResourceRequest.INSTANCE; - } - - /** - * Returns a matcher that includes the H2 console location. For example: - *
-	 * PathRequest.toH2Console()
-	 * 
- * @return the configured {@link RequestMatcher} - */ - public static H2ConsoleRequestMatcher toH2Console() { - return new H2ConsoleRequestMatcher(); - } - - /** - * The request matcher used to match against h2 console path. - */ - public static final class H2ConsoleRequestMatcher extends ApplicationContextRequestMatcher { - - private volatile RequestMatcher delegate; - - private H2ConsoleRequestMatcher() { - super(H2ConsoleProperties.class); - } - - @Override - protected boolean ignoreApplicationContext(WebApplicationContext applicationContext) { - return WebServerApplicationContext.hasServerNamespace(applicationContext, "management"); - } - - @Override - protected void initialized(Supplier h2ConsoleProperties) { - this.delegate = PathPatternRequestMatcher.withDefaults() - .matcher(h2ConsoleProperties.get().getPath() + "/**"); - } - - @Override - protected boolean matches(HttpServletRequest request, Supplier context) { - return this.delegate.matches(request); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/RequestMatcherProvider.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/RequestMatcherProvider.java deleted file mode 100644 index 805141bfd809..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/RequestMatcherProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.servlet; - -import org.springframework.security.web.util.matcher.RequestMatcher; - -/** - * Interface that can be used to provide a {@link RequestMatcher} that can be used with - * Spring Security. - * - * @author Madhura Bhave - * @since 2.0.5 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@code org.springframework.boot.actuate.autoconfigure.security.servlet.RequestMatcherProvider} - */ -@Deprecated(since = "3.5.0", forRemoval = true) -@FunctionalInterface -public interface RequestMatcherProvider { - - /** - * Return the {@link RequestMatcher} to be used for the specified pattern. - * @param pattern the request pattern - * @return a request matcher - */ - RequestMatcher getRequestMatcher(String pattern); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/StaticResourceRequest.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/StaticResourceRequest.java deleted file mode 100644 index d5826fec3844..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/StaticResourceRequest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.servlet; - -import java.util.EnumSet; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import jakarta.servlet.http.HttpServletRequest; - -import org.springframework.boot.autoconfigure.security.StaticResourceLocation; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; -import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; -import org.springframework.security.web.util.matcher.OrRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.Assert; -import org.springframework.web.context.WebApplicationContext; - -/** - * Used to create a {@link RequestMatcher} for static resources in commonly used - * locations. Returned by {@link PathRequest#toStaticResources()}. - * - * @author Madhura Bhave - * @author Phillip Webb - * @since 2.0.0 - * @see PathRequest - */ -public final class StaticResourceRequest { - - static final StaticResourceRequest INSTANCE = new StaticResourceRequest(); - - private StaticResourceRequest() { - } - - /** - * Returns a matcher that includes all commonly used {@link StaticResourceLocation - * Locations}. The - * {@link StaticResourceRequestMatcher#excluding(StaticResourceLocation, StaticResourceLocation...) - * excluding} method can be used to remove specific locations if required. For - * example:
-	 * PathRequest.toStaticResources().atCommonLocations().excluding(StaticResourceLocation.CSS)
-	 * 
- * @return the configured {@link RequestMatcher} - */ - public StaticResourceRequestMatcher atCommonLocations() { - return at(EnumSet.allOf(StaticResourceLocation.class)); - } - - /** - * Returns a matcher that includes the specified {@link StaticResourceLocation - * Locations}. For example:
-	 * PathRequest.toStaticResources().at(StaticResourceLocation.CSS, StaticResourceLocation.JAVA_SCRIPT)
-	 * 
- * @param first the first location to include - * @param rest additional locations to include - * @return the configured {@link RequestMatcher} - */ - public StaticResourceRequestMatcher at(StaticResourceLocation first, StaticResourceLocation... rest) { - return at(EnumSet.of(first, rest)); - } - - /** - * Returns a matcher that includes the specified {@link StaticResourceLocation - * Locations}. For example:
-	 * PathRequest.toStaticResources().at(locations)
-	 * 
- * @param locations the locations to include - * @return the configured {@link RequestMatcher} - */ - public StaticResourceRequestMatcher at(Set locations) { - Assert.notNull(locations, "'locations' must not be null"); - return new StaticResourceRequestMatcher(new LinkedHashSet<>(locations)); - } - - /** - * The request matcher used to match against resource {@link StaticResourceLocation - * Locations}. - */ - public static final class StaticResourceRequestMatcher - extends ApplicationContextRequestMatcher { - - private final Set locations; - - private volatile RequestMatcher delegate; - - private StaticResourceRequestMatcher(Set locations) { - super(DispatcherServletPath.class); - this.locations = locations; - } - - /** - * Return a new {@link StaticResourceRequestMatcher} based on this one but - * excluding the specified locations. - * @param first the first location to exclude - * @param rest additional locations to exclude - * @return a new {@link StaticResourceRequestMatcher} - */ - public StaticResourceRequestMatcher excluding(StaticResourceLocation first, StaticResourceLocation... rest) { - return excluding(EnumSet.of(first, rest)); - } - - /** - * Return a new {@link StaticResourceRequestMatcher} based on this one but - * excluding the specified locations. - * @param locations the locations to exclude - * @return a new {@link StaticResourceRequestMatcher} - */ - public StaticResourceRequestMatcher excluding(Set locations) { - Assert.notNull(locations, "'locations' must not be null"); - Set subset = new LinkedHashSet<>(this.locations); - subset.removeAll(locations); - return new StaticResourceRequestMatcher(subset); - } - - @Override - protected void initialized(Supplier dispatcherServletPath) { - this.delegate = new OrRequestMatcher(getDelegateMatchers(dispatcherServletPath.get()).toList()); - } - - private Stream getDelegateMatchers(DispatcherServletPath dispatcherServletPath) { - return getPatterns(dispatcherServletPath).map(PathPatternRequestMatcher.withDefaults()::matcher); - } - - private Stream getPatterns(DispatcherServletPath dispatcherServletPath) { - return this.locations.stream() - .flatMap(StaticResourceLocation::getPatterns) - .map(dispatcherServletPath::getRelativePath); - } - - @Override - protected boolean ignoreApplicationContext(WebApplicationContext applicationContext) { - return WebServerApplicationContext.hasServerNamespace(applicationContext, "management"); - } - - @Override - protected boolean matches(HttpServletRequest request, Supplier context) { - return this.delegate.matches(request); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/package-info.java deleted file mode 100644 index 584a117e7721..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Servlet-based Spring Security. - */ -package org.springframework.boot.autoconfigure.security.servlet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/package-info.java deleted file mode 100644 index c1c3c847840e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for SendGrid. - */ -package org.springframework.boot.autoconfigure.sendgrid; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactories.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactories.java index 5cfd8f531d8a..6e49280ccbd7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactories.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactories.java @@ -48,16 +48,6 @@ public class ConnectionDetailsFactories { private final List> registrations = new ArrayList<>(); - /** - * Create a new {@link ConnectionDetailsFactories} instance. - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #ConnectionDetailsFactories(ClassLoader)} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - public ConnectionDetailsFactories() { - this((ClassLoader) null); - } - /** * Create a new {@link ConnectionDetailsFactories} instance. * @param classLoader the class loader used to load factories diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionConfiguration.java deleted file mode 100644 index 6e86b56a6f25..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionConfiguration.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import com.hazelcast.core.HazelcastInstance; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.session.SessionRepository; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository; -import org.springframework.session.hazelcast.config.annotation.web.http.HazelcastHttpSessionConfiguration; - -/** - * Hazelcast backed session configuration. - * - * @author Tommy Ludwig - * @author Eddú Meléndez - * @author Stephane Nicoll - * @author Vedran Pavic - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(HazelcastIndexedSessionRepository.class) -@ConditionalOnMissingBean(SessionRepository.class) -@ConditionalOnBean(HazelcastInstance.class) -@EnableConfigurationProperties(HazelcastSessionProperties.class) -@Import(HazelcastHttpSessionConfiguration.class) -class HazelcastSessionConfiguration { - - @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) - SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( - SessionProperties sessionProperties, HazelcastSessionProperties hazelcastSessionProperties, - ServerProperties serverProperties) { - return (sessionRepository) -> { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(sessionProperties.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) - .to(sessionRepository::setDefaultMaxInactiveInterval); - map.from(hazelcastSessionProperties::getMapName).to(sessionRepository::setSessionMapName); - map.from(hazelcastSessionProperties::getFlushMode).to(sessionRepository::setFlushMode); - map.from(hazelcastSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.java deleted file mode 100644 index 86c245fefef4..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.session.SessionRepository; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.session.jdbc.JdbcIndexedSessionRepository; -import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource; -import org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration; - -/** - * JDBC backed session configuration. - * - * @author Eddú Meléndez - * @author Stephane Nicoll - * @author Vedran Pavic - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ JdbcTemplate.class, JdbcIndexedSessionRepository.class }) -@ConditionalOnMissingBean(SessionRepository.class) -@ConditionalOnBean(DataSource.class) -@EnableConfigurationProperties(JdbcSessionProperties.class) -@Import({ DatabaseInitializationDependencyConfigurer.class, JdbcHttpSessionConfiguration.class }) -class JdbcSessionConfiguration { - - @Bean - @ConditionalOnMissingBean - @Conditional(OnJdbcSessionDatasourceInitializationCondition.class) - JdbcSessionDataSourceScriptDatabaseInitializer jdbcSessionDataSourceScriptDatabaseInitializer( - @SpringSessionDataSource ObjectProvider sessionDataSource, - ObjectProvider dataSource, JdbcSessionProperties properties) { - DataSource dataSourceToInitialize = sessionDataSource.getIfAvailable(dataSource::getObject); - return new JdbcSessionDataSourceScriptDatabaseInitializer(dataSourceToInitialize, properties); - } - - @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) - SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( - SessionProperties sessionProperties, JdbcSessionProperties jdbcSessionProperties, - ServerProperties serverProperties) { - return (sessionRepository) -> { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(sessionProperties.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) - .to(sessionRepository::setDefaultMaxInactiveInterval); - map.from(jdbcSessionProperties::getTableName).to(sessionRepository::setTableName); - map.from(jdbcSessionProperties::getFlushMode).to(sessionRepository::setFlushMode); - map.from(jdbcSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); - map.from(jdbcSessionProperties::getCleanupCron).to(sessionRepository::setCleanupCron); - }; - } - - static class OnJdbcSessionDatasourceInitializationCondition extends OnDatabaseInitializationCondition { - - OnJdbcSessionDatasourceInitializationCondition() { - super("Jdbc Session", "spring.session.jdbc.initialize-schema"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoReactiveSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoReactiveSessionConfiguration.java deleted file mode 100644 index b3d0edd2db90..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoReactiveSessionConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.data.mongodb.core.ReactiveMongoOperations; -import org.springframework.session.ReactiveSessionRepository; -import org.springframework.session.config.ReactiveSessionRepositoryCustomizer; -import org.springframework.session.data.mongo.ReactiveMongoSessionRepository; -import org.springframework.session.data.mongo.config.annotation.web.reactive.ReactiveMongoWebSessionConfiguration; - -/** - * Mongo-backed reactive session configuration. - * - * @author Andy Wilkinson - * @author Weix Sun - * @author Vedran Pavic - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ ReactiveMongoOperations.class, ReactiveMongoSessionRepository.class }) -@ConditionalOnMissingBean(ReactiveSessionRepository.class) -@ConditionalOnBean(ReactiveMongoOperations.class) -@EnableConfigurationProperties(MongoSessionProperties.class) -@Import(ReactiveMongoWebSessionConfiguration.class) -class MongoReactiveSessionConfiguration { - - @Bean - ReactiveSessionRepositoryCustomizer springBootSessionRepositoryCustomizer( - SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties, - ServerProperties serverProperties) { - return (sessionRepository) -> { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(sessionProperties.determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout())) - .to(sessionRepository::setDefaultMaxInactiveInterval); - map.from(mongoSessionProperties::getCollectionName).to(sessionRepository::setCollectionName); - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionConfiguration.java deleted file mode 100644 index 2f6170a61608..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionConfiguration.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.data.mongodb.core.MongoOperations; -import org.springframework.session.SessionRepository; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.session.data.mongo.MongoIndexedSessionRepository; -import org.springframework.session.data.mongo.config.annotation.web.http.MongoHttpSessionConfiguration; - -/** - * Mongo-backed session configuration. - * - * @author Eddú Meléndez - * @author Stephane Nicoll - * @author Vedran Pavic - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ MongoOperations.class, MongoIndexedSessionRepository.class }) -@ConditionalOnMissingBean(SessionRepository.class) -@ConditionalOnBean(MongoOperations.class) -@EnableConfigurationProperties(MongoSessionProperties.class) -@Import(MongoHttpSessionConfiguration.class) -class MongoSessionConfiguration { - - @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) - SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( - SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties, - ServerProperties serverProperties) { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - return (sessionRepository) -> { - map.from(sessionProperties.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) - .to(sessionRepository::setDefaultMaxInactiveInterval); - map.from(mongoSessionProperties::getCollectionName).to(sessionRepository::setCollectionName); - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisReactiveSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisReactiveSessionConfiguration.java deleted file mode 100644 index 5c2070503eab..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisReactiveSessionConfiguration.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; -import org.springframework.session.ReactiveSessionRepository; -import org.springframework.session.config.ReactiveSessionRepositoryCustomizer; -import org.springframework.session.data.redis.ReactiveRedisIndexedSessionRepository; -import org.springframework.session.data.redis.ReactiveRedisSessionRepository; -import org.springframework.session.data.redis.config.ConfigureReactiveRedisAction; -import org.springframework.session.data.redis.config.annotation.ConfigureNotifyKeyspaceEventsReactiveAction; -import org.springframework.session.data.redis.config.annotation.web.server.RedisIndexedWebSessionConfiguration; -import org.springframework.session.data.redis.config.annotation.web.server.RedisWebSessionConfiguration; - -/** - * Redis-backed reactive session configuration. - * - * @author Andy Wilkinson - * @author Weix Sun - * @author Vedran Pavic - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ ReactiveRedisConnectionFactory.class, ReactiveRedisSessionRepository.class }) -@ConditionalOnMissingBean(ReactiveSessionRepository.class) -@ConditionalOnBean(ReactiveRedisConnectionFactory.class) -@EnableConfigurationProperties(RedisSessionProperties.class) -class RedisReactiveSessionConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(name = "spring.session.redis.repository-type", havingValue = "default", - matchIfMissing = true) - @Import(RedisWebSessionConfiguration.class) - static class DefaultRedisSessionConfiguration { - - @Bean - ReactiveSessionRepositoryCustomizer springBootSessionRepositoryCustomizer( - SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, - ServerProperties serverProperties) { - return (sessionRepository) -> { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(sessionProperties - .determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout())) - .to(sessionRepository::setDefaultMaxInactiveInterval); - map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace); - map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); - }; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(name = "spring.session.redis.repository-type", havingValue = "indexed") - @Import(RedisIndexedWebSessionConfiguration.class) - static class IndexedRedisSessionConfiguration { - - @Bean - @ConditionalOnMissingBean - ConfigureReactiveRedisAction configureReactiveRedisAction(RedisSessionProperties redisSessionProperties) { - return switch (redisSessionProperties.getConfigureAction()) { - case NOTIFY_KEYSPACE_EVENTS -> new ConfigureNotifyKeyspaceEventsReactiveAction(); - case NONE -> ConfigureReactiveRedisAction.NO_OP; - }; - } - - @Bean - ReactiveSessionRepositoryCustomizer springBootSessionRepositoryCustomizer( - SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, - ServerProperties serverProperties) { - return (sessionRepository) -> { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(sessionProperties - .determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout())) - .to(sessionRepository::setDefaultMaxInactiveInterval); - map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace); - map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); - }; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java deleted file mode 100644 index b7055be57316..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.session.SessionRepository; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.session.data.redis.RedisIndexedSessionRepository; -import org.springframework.session.data.redis.RedisSessionRepository; -import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction; -import org.springframework.session.data.redis.config.ConfigureRedisAction; -import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration; -import org.springframework.session.data.redis.config.annotation.web.http.RedisIndexedHttpSessionConfiguration; - -/** - * Redis backed session configuration. - * - * @author Andy Wilkinson - * @author Tommy Ludwig - * @author Eddú Meléndez - * @author Stephane Nicoll - * @author Vedran Pavic - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ RedisTemplate.class, RedisIndexedSessionRepository.class }) -@ConditionalOnMissingBean(SessionRepository.class) -@ConditionalOnBean(RedisConnectionFactory.class) -@EnableConfigurationProperties(RedisSessionProperties.class) -class RedisSessionConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(name = "spring.session.redis.repository-type", havingValue = "default", - matchIfMissing = true) - @Import(RedisHttpSessionConfiguration.class) - static class DefaultRedisSessionConfiguration { - - @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) - SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( - SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, - ServerProperties serverProperties) { - String cleanupCron = redisSessionProperties.getCleanupCron(); - if (cleanupCron != null) { - throw new InvalidConfigurationPropertyValueException("spring.session.redis.cleanup-cron", cleanupCron, - "Cron-based cleanup is only supported when " - + "spring.session.redis.repository-type is set to indexed."); - } - return (sessionRepository) -> { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(sessionProperties - .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) - .to(sessionRepository::setDefaultMaxInactiveInterval); - map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace); - map.from(redisSessionProperties::getFlushMode).to(sessionRepository::setFlushMode); - map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); - }; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(name = "spring.session.redis.repository-type", havingValue = "indexed") - @Import(RedisIndexedHttpSessionConfiguration.class) - static class IndexedRedisSessionConfiguration { - - @Bean - @ConditionalOnMissingBean - ConfigureRedisAction configureRedisAction(RedisSessionProperties redisSessionProperties) { - return switch (redisSessionProperties.getConfigureAction()) { - case NOTIFY_KEYSPACE_EVENTS -> new ConfigureNotifyKeyspaceEventsAction(); - case NONE -> ConfigureRedisAction.NO_OP; - }; - } - - @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) - SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( - SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, - ServerProperties serverProperties) { - return (sessionRepository) -> { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(sessionProperties - .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) - .to(sessionRepository::setDefaultMaxInactiveInterval); - map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace); - map.from(redisSessionProperties::getFlushMode).to(sessionRepository::setFlushMode); - map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); - map.from(redisSessionProperties::getCleanupCron).to(sessionRepository::setCleanupCron); - }; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.java deleted file mode 100644 index 8d16871cc3af..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.time.Duration; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties; -import org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.server.Cookie; -import org.springframework.boot.web.server.Cookie.SameSite; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.security.web.authentication.RememberMeServices; -import org.springframework.session.ReactiveSessionRepository; -import org.springframework.session.Session; -import org.springframework.session.SessionRepository; -import org.springframework.session.security.web.authentication.SpringSessionRememberMeServices; -import org.springframework.session.web.http.CookieHttpSessionIdResolver; -import org.springframework.session.web.http.CookieSerializer; -import org.springframework.session.web.http.DefaultCookieSerializer; -import org.springframework.session.web.http.HttpSessionIdResolver; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Session. - * - * @author Andy Wilkinson - * @author Tommy Ludwig - * @author Eddú Meléndez - * @author Stephane Nicoll - * @author Vedran Pavic - * @author Weix Sun - * @since 1.4.0 - */ -@AutoConfiguration( - after = { DataSourceAutoConfiguration.class, HazelcastAutoConfiguration.class, - JdbcTemplateAutoConfiguration.class, MongoDataAutoConfiguration.class, - MongoReactiveDataAutoConfiguration.class, RedisAutoConfiguration.class, - RedisReactiveAutoConfiguration.class, WebSessionIdResolverAutoConfiguration.class }, - before = { HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class }) -@ConditionalOnClass(Session.class) -@ConditionalOnWebApplication -@EnableConfigurationProperties({ ServerProperties.class, SessionProperties.class, WebFluxProperties.class }) -public class SessionAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = Type.SERVLET) - @Import(SessionRepositoryFilterConfiguration.class) - static class ServletSessionConfiguration { - - @Bean - @Conditional(DefaultCookieSerializerCondition.class) - DefaultCookieSerializer cookieSerializer(ServerProperties serverProperties, - ObjectProvider cookieSerializerCustomizers) { - Cookie cookie = serverProperties.getServlet().getSession().getCookie(); - DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(cookie::getName).to(cookieSerializer::setCookieName); - map.from(cookie::getDomain).to(cookieSerializer::setDomainName); - map.from(cookie::getPath).to(cookieSerializer::setCookiePath); - map.from(cookie::getHttpOnly).to(cookieSerializer::setUseHttpOnlyCookie); - map.from(cookie::getSecure).to(cookieSerializer::setUseSecureCookie); - map.from(cookie::getMaxAge).asInt(Duration::getSeconds).to(cookieSerializer::setCookieMaxAge); - map.from(cookie::getSameSite).as(SameSite::attributeValue).to(cookieSerializer::setSameSite); - map.from(cookie::getPartitioned).to(cookieSerializer::setPartitioned); - cookieSerializerCustomizers.orderedStream().forEach((customizer) -> customizer.customize(cookieSerializer)); - return cookieSerializer; - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(RememberMeServices.class) - static class RememberMeServicesConfiguration { - - @Bean - DefaultCookieSerializerCustomizer rememberMeServicesCookieSerializerCustomizer() { - return (cookieSerializer) -> cookieSerializer - .setRememberMeRequestAttribute(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(SessionRepository.class) - @Import({ RedisSessionConfiguration.class, JdbcSessionConfiguration.class, HazelcastSessionConfiguration.class, - MongoSessionConfiguration.class }) - static class ServletSessionRepositoryConfiguration { - - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = Type.REACTIVE) - @ConditionalOnMissingBean(ReactiveSessionRepository.class) - @Import({ RedisReactiveSessionConfiguration.class, MongoReactiveSessionConfiguration.class }) - static class ReactiveSessionConfiguration { - - } - - /** - * Condition to trigger the creation of a {@link DefaultCookieSerializer}. This kicks - * in if either no {@link HttpSessionIdResolver} and {@link CookieSerializer} beans - * are registered, or if {@link CookieHttpSessionIdResolver} is registered but - * {@link CookieSerializer} is not. - */ - static class DefaultCookieSerializerCondition extends AnyNestedCondition { - - DefaultCookieSerializerCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnMissingBean({ HttpSessionIdResolver.class, CookieSerializer.class }) - static class NoComponentsAvailable { - - } - - @ConditionalOnBean(CookieHttpSessionIdResolver.class) - @ConditionalOnMissingBean(CookieSerializer.class) - static class CookieHttpSessionIdResolverAvailable { - - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/package-info.java deleted file mode 100644 index 70def9feb9c5..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Session. - */ -package org.springframework.boot.autoconfigure.session; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.java deleted file mode 100644 index 0c167e58ef42..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.sql.init; - -import javax.sql.DataSource; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.datasource.SimpleDriverDataSource; -import org.springframework.jdbc.datasource.init.DatabasePopulator; -import org.springframework.util.StringUtils; - -@Configuration(proxyBeanMethods = false) -@ConditionalOnMissingBean({ SqlDataSourceScriptDatabaseInitializer.class, SqlR2dbcScriptDatabaseInitializer.class }) -@ConditionalOnSingleCandidate(DataSource.class) -@ConditionalOnClass(DatabasePopulator.class) -class DataSourceInitializationConfiguration { - - @Bean - SqlDataSourceScriptDatabaseInitializer dataSourceScriptDatabaseInitializer(DataSource dataSource, - SqlInitializationProperties properties) { - return new SqlDataSourceScriptDatabaseInitializer( - determineDataSource(dataSource, properties.getUsername(), properties.getPassword()), properties); - } - - private static DataSource determineDataSource(DataSource dataSource, String username, String password) { - if (StringUtils.hasText(username) && StringUtils.hasText(password)) { - return DataSourceBuilder.derivedFrom(dataSource) - .username(username) - .password(password) - .type(SimpleDriverDataSource.class) - .build(); - } - return dataSource; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/R2dbcInitializationConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/R2dbcInitializationConfiguration.java deleted file mode 100644 index 9e5c048941b4..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/R2dbcInitializationConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.sql.init; - -import io.r2dbc.spi.ConnectionFactory; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.r2dbc.ConnectionFactoryBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.r2dbc.connection.init.DatabasePopulator; -import org.springframework.util.StringUtils; - -/** - * Configuration for initializing an SQL database accessed through an R2DBC - * {@link ConnectionFactory}. - * - * @author Andy Wilkinson - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ ConnectionFactory.class, DatabasePopulator.class }) -@ConditionalOnSingleCandidate(ConnectionFactory.class) -@ConditionalOnMissingBean({ SqlR2dbcScriptDatabaseInitializer.class, SqlDataSourceScriptDatabaseInitializer.class }) -class R2dbcInitializationConfiguration { - - @Bean - SqlR2dbcScriptDatabaseInitializer r2dbcScriptDatabaseInitializer(ConnectionFactory connectionFactory, - SqlInitializationProperties properties) { - return new SqlR2dbcScriptDatabaseInitializer( - determineConnectionFactory(connectionFactory, properties.getUsername(), properties.getPassword()), - properties); - } - - private static ConnectionFactory determineConnectionFactory(ConnectionFactory connectionFactory, String username, - String password) { - if (StringUtils.hasText(username) && StringUtils.hasText(password)) { - return ConnectionFactoryBuilder.derivedFrom(connectionFactory) - .username(username) - .password(password) - .build(); - } - return connectionFactory; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlDataSourceScriptDatabaseInitializer.java deleted file mode 100644 index fbcc54aa1a1e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlDataSourceScriptDatabaseInitializer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.sql.init; - -import javax.sql.DataSource; - -import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; -import org.springframework.boot.sql.init.DatabaseInitializationSettings; -import org.springframework.context.annotation.ImportRuntimeHints; - -/** - * {@link DataSourceScriptDatabaseInitializer} for the primary SQL database. May be - * registered as a bean to override auto-configuration. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @since 2.6.0 - */ -@ImportRuntimeHints(SqlInitializationScriptsRuntimeHints.class) -public class SqlDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer { - - /** - * Create a new {@link SqlDataSourceScriptDatabaseInitializer} instance. - * @param dataSource the primary SQL data source - * @param properties the SQL initialization properties - * @see #getSettings - */ - public SqlDataSourceScriptDatabaseInitializer(DataSource dataSource, SqlInitializationProperties properties) { - this(dataSource, getSettings(properties)); - } - - /** - * Create a new {@link SqlDataSourceScriptDatabaseInitializer} instance. - * @param dataSource the primary SQL data source - * @param settings the database initialization settings - * @see #getSettings - */ - public SqlDataSourceScriptDatabaseInitializer(DataSource dataSource, DatabaseInitializationSettings settings) { - super(dataSource, settings); - } - - /** - * Adapts {@link SqlInitializationProperties SQL initialization properties} to - * {@link DatabaseInitializationSettings}. - * @param properties the SQL initialization properties - * @return a new {@link DatabaseInitializationSettings} instance - * @see #SqlDataSourceScriptDatabaseInitializer(DataSource, - * DatabaseInitializationSettings) - */ - public static DatabaseInitializationSettings getSettings(SqlInitializationProperties properties) { - return SettingsCreator.createFrom(properties); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfiguration.java deleted file mode 100644 index 49993d012f88..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfiguration.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.sql.init; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration.SqlInitializationModeCondition; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for initializing an SQL database. - * - * @author Andy Wilkinson - * @since 2.5.0 - */ -@AutoConfiguration -@EnableConfigurationProperties(SqlInitializationProperties.class) -@Import({ DatabaseInitializationDependencyConfigurer.class, R2dbcInitializationConfiguration.class, - DataSourceInitializationConfiguration.class }) -@ConditionalOnBooleanProperty(name = "spring.sql.init.enabled", matchIfMissing = true) -@Conditional(SqlInitializationModeCondition.class) -public class SqlInitializationAutoConfiguration { - - static class SqlInitializationModeCondition extends NoneNestedConditions { - - SqlInitializationModeCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnProperty(name = "spring.sql.init.mode", havingValue = "never") - static class ModeIsNever { - - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlR2dbcScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlR2dbcScriptDatabaseInitializer.java deleted file mode 100644 index 52c3d6a37141..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlR2dbcScriptDatabaseInitializer.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.sql.init; - -import io.r2dbc.spi.ConnectionFactory; - -import org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializer; -import org.springframework.boot.sql.init.DatabaseInitializationSettings; -import org.springframework.context.annotation.ImportRuntimeHints; - -/** - * {@link R2dbcScriptDatabaseInitializer} for the primary SQL database. May be registered - * as a bean to override auto-configuration. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @since 2.6.0 - */ -@ImportRuntimeHints(SqlInitializationScriptsRuntimeHints.class) -public class SqlR2dbcScriptDatabaseInitializer extends R2dbcScriptDatabaseInitializer { - - /** - * Create a new {@code SqlR2dbcScriptDatabaseInitializer} instance. - * @param connectionFactory the primary SQL connection factory - * @param properties the SQL initialization properties - * @see #getSettings - */ - public SqlR2dbcScriptDatabaseInitializer(ConnectionFactory connectionFactory, - SqlInitializationProperties properties) { - super(connectionFactory, getSettings(properties)); - } - - /** - * Create a new {@code SqlR2dbcScriptDatabaseInitializer} instance. - * @param connectionFactory the primary SQL connection factory - * @param settings the database initialization settings - * @see #getSettings - */ - public SqlR2dbcScriptDatabaseInitializer(ConnectionFactory connectionFactory, - DatabaseInitializationSettings settings) { - super(connectionFactory, settings); - } - - /** - * Adapts {@link SqlInitializationProperties SQL initialization properties} to - * {@link DatabaseInitializationSettings}. - * @param properties the SQL initialization properties - * @return a new {@link DatabaseInitializationSettings} instance - * @see #SqlR2dbcScriptDatabaseInitializer(ConnectionFactory, - * DatabaseInitializationSettings) - */ - public static DatabaseInitializationSettings getSettings(SqlInitializationProperties properties) { - return SettingsCreator.createFrom(properties); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/package-info.java deleted file mode 100644 index a81e188df10f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for basic script-based initialization of an SQL database. - */ -package org.springframework.boot.autoconfigure.sql.init; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/template/AbstractTemplateViewResolverProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/template/AbstractTemplateViewResolverProperties.java deleted file mode 100644 index 8f81cc5d9250..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/template/AbstractTemplateViewResolverProperties.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.template; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.Ordered; -import org.springframework.util.Assert; -import org.springframework.web.servlet.view.AbstractTemplateViewResolver; - -/** - * Base class for {@link ConfigurationProperties @ConfigurationProperties} of a - * {@link AbstractTemplateViewResolver}. - * - * @author Andy Wilkinson - * @since 1.1.0 - */ -public abstract class AbstractTemplateViewResolverProperties extends AbstractViewResolverProperties { - - /** - * Prefix that gets prepended to view names when building a URL. - */ - private String prefix; - - /** - * Suffix that gets appended to view names when building a URL. - */ - private String suffix; - - /** - * Name of the RequestContext attribute for all views. - */ - private String requestContextAttribute; - - /** - * Whether all request attributes should be added to the model prior to merging with - * the template. - */ - private boolean exposeRequestAttributes = false; - - /** - * Whether all HttpSession attributes should be added to the model prior to merging - * with the template. - */ - private boolean exposeSessionAttributes = false; - - /** - * Whether HttpServletRequest attributes are allowed to override (hide) controller - * generated model attributes of the same name. - */ - private boolean allowRequestOverride = false; - - /** - * Whether to expose a RequestContext for use by Spring's macro library, under the - * name "springMacroRequestContext". - */ - private boolean exposeSpringMacroHelpers = true; - - /** - * Whether HttpSession attributes are allowed to override (hide) controller generated - * model attributes of the same name. - */ - private boolean allowSessionOverride = false; - - protected AbstractTemplateViewResolverProperties(String defaultPrefix, String defaultSuffix) { - this.prefix = defaultPrefix; - this.suffix = defaultSuffix; - } - - public String getPrefix() { - return this.prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getSuffix() { - return this.suffix; - } - - public void setSuffix(String suffix) { - this.suffix = suffix; - } - - public String getRequestContextAttribute() { - return this.requestContextAttribute; - } - - public void setRequestContextAttribute(String requestContextAttribute) { - this.requestContextAttribute = requestContextAttribute; - } - - public boolean isExposeRequestAttributes() { - return this.exposeRequestAttributes; - } - - public void setExposeRequestAttributes(boolean exposeRequestAttributes) { - this.exposeRequestAttributes = exposeRequestAttributes; - } - - public boolean isExposeSessionAttributes() { - return this.exposeSessionAttributes; - } - - public void setExposeSessionAttributes(boolean exposeSessionAttributes) { - this.exposeSessionAttributes = exposeSessionAttributes; - } - - public boolean isAllowRequestOverride() { - return this.allowRequestOverride; - } - - public void setAllowRequestOverride(boolean allowRequestOverride) { - this.allowRequestOverride = allowRequestOverride; - } - - public boolean isAllowSessionOverride() { - return this.allowSessionOverride; - } - - public void setAllowSessionOverride(boolean allowSessionOverride) { - this.allowSessionOverride = allowSessionOverride; - } - - public boolean isExposeSpringMacroHelpers() { - return this.exposeSpringMacroHelpers; - } - - public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) { - this.exposeSpringMacroHelpers = exposeSpringMacroHelpers; - } - - /** - * Apply the given properties to a {@link AbstractTemplateViewResolver}. Use Object in - * signature to avoid runtime dependency on MVC, which means that the template engine - * can be used in a non-web application. - * @param viewResolver the resolver to apply the properties to. - */ - public void applyToMvcViewResolver(Object viewResolver) { - Assert.isInstanceOf(AbstractTemplateViewResolver.class, viewResolver, - () -> "ViewResolver is not an instance of AbstractTemplateViewResolver :" + viewResolver); - AbstractTemplateViewResolver resolver = (AbstractTemplateViewResolver) viewResolver; - resolver.setPrefix(getPrefix()); - resolver.setSuffix(getSuffix()); - resolver.setCache(isCache()); - if (getContentType() != null) { - resolver.setContentType(getContentType().toString()); - } - resolver.setViewNames(getViewNames()); - resolver.setExposeRequestAttributes(isExposeRequestAttributes()); - resolver.setAllowRequestOverride(isAllowRequestOverride()); - resolver.setAllowSessionOverride(isAllowSessionOverride()); - resolver.setExposeSessionAttributes(isExposeSessionAttributes()); - resolver.setExposeSpringMacroHelpers(isExposeSpringMacroHelpers()); - resolver.setRequestContextAttribute(getRequestContextAttribute()); - // The resolver usually acts as a fallback resolver (e.g. like a - // InternalResourceViewResolver) so it needs to have low precedence - resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/template/AbstractViewResolverProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/template/AbstractViewResolverProperties.java deleted file mode 100644 index a4ddfc3c6ef4..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/template/AbstractViewResolverProperties.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.template; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.MimeType; -import org.springframework.web.servlet.ViewResolver; - -/** - * Base class for {@link ConfigurationProperties @ConfigurationProperties} of a - * {@link ViewResolver}. - * - * @author Andy Wilkinson - * @author Stephane Nicoll - * @since 1.2.0 - * @see AbstractTemplateViewResolverProperties - */ -public abstract class AbstractViewResolverProperties { - - private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html"); - - private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; - - /** - * Whether to enable MVC view resolution for this technology. - */ - private boolean enabled = true; - - /** - * Whether to enable template caching. - */ - private boolean cache; - - /** - * Content-Type value. - */ - private MimeType contentType = DEFAULT_CONTENT_TYPE; - - /** - * Template encoding. - */ - private Charset charset = DEFAULT_CHARSET; - - /** - * View names that can be resolved. - */ - private String[] viewNames; - - /** - * Whether to check that the templates location exists. - */ - private boolean checkTemplateLocation = true; - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setCheckTemplateLocation(boolean checkTemplateLocation) { - this.checkTemplateLocation = checkTemplateLocation; - } - - public boolean isCheckTemplateLocation() { - return this.checkTemplateLocation; - } - - public String[] getViewNames() { - return this.viewNames; - } - - public void setViewNames(String[] viewNames) { - this.viewNames = viewNames; - } - - public boolean isCache() { - return this.cache; - } - - public void setCache(boolean cache) { - this.cache = cache; - } - - public MimeType getContentType() { - if (this.contentType.getCharset() == null) { - Map parameters = new LinkedHashMap<>(); - parameters.put("charset", this.charset.name()); - parameters.putAll(this.contentType.getParameters()); - return new MimeType(this.contentType, parameters); - } - return this.contentType; - } - - public void setContentType(MimeType contentType) { - this.contentType = contentType; - } - - public Charset getCharset() { - return this.charset; - } - - public String getCharsetName() { - return (this.charset != null) ? this.charset.name() : null; - } - - public void setCharset(Charset charset) { - this.charset = charset; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/package-info.java deleted file mode 100644 index 80934f9610a0..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Thymeleaf. - */ -package org.springframework.boot.autoconfigure.thymeleaf; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfiguration.java deleted file mode 100644 index f77664b501c9..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.transaction.jta; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration; -import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for JTA. - * - * @author Josh Long - * @author Phillip Webb - * @author Nishant Raut - * @since 1.2.0 - */ -@AutoConfiguration(before = { XADataSourceAutoConfiguration.class, ActiveMQAutoConfiguration.class, - ArtemisAutoConfiguration.class, HibernateJpaAutoConfiguration.class, TransactionAutoConfiguration.class, - TransactionManagerCustomizationAutoConfiguration.class }) -@ConditionalOnClass(jakarta.transaction.Transaction.class) -@ConditionalOnBooleanProperty(name = "spring.jta.enabled", matchIfMissing = true) -@Import(JndiJtaConfiguration.class) -public class JtaAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/package-info.java deleted file mode 100644 index 62273ad6060d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for JTA. - */ -package org.springframework.boot.autoconfigure.transaction.jta; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/package-info.java deleted file mode 100644 index c5ec9c971822..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for transaction support. - */ -package org.springframework.boot.autoconfigure.transaction; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/package-info.java deleted file mode 100644 index 6c82b8eb8153..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for (JSR-303) Validation. - */ -package org.springframework.boot.autoconfigure.validation; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java deleted file mode 100644 index ad83593dbabd..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ /dev/null @@ -1,2019 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web; - -import java.io.File; -import java.net.InetAddress; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import io.undertow.UndertowOptions; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; -import org.springframework.boot.context.properties.NestedConfigurationProperty; -import org.springframework.boot.convert.DurationUnit; -import org.springframework.boot.web.server.Compression; -import org.springframework.boot.web.server.Cookie; -import org.springframework.boot.web.server.Http2; -import org.springframework.boot.web.server.MimeMappings; -import org.springframework.boot.web.server.Shutdown; -import org.springframework.boot.web.server.Ssl; -import org.springframework.boot.web.servlet.server.Jsp; -import org.springframework.boot.web.servlet.server.Session; -import org.springframework.util.StringUtils; -import org.springframework.util.unit.DataSize; - -/** - * {@link ConfigurationProperties @ConfigurationProperties} for a web server (e.g. port - * and path settings). - * - * @author Dave Syer - * @author Stephane Nicoll - * @author Andy Wilkinson - * @author Ivan Sopov - * @author Marcos Barbero - * @author Eddú Meléndez - * @author Quinten De Swaef - * @author Venil Noronha - * @author Aurélien Leboulanger - * @author Brian Clozel - * @author Olivier Lamy - * @author Chentao Qu - * @author Artsiom Yudovin - * @author Andrew McGhie - * @author Rafiullah Hamedy - * @author Dirk Deyne - * @author HaiTao Zhang - * @author Victor Mandujano - * @author Chris Bono - * @author Parviz Rozikov - * @author Florian Storz - * @author Michael Weidmann - * @author Lasse Wulff - * @since 1.0.0 - */ -@ConfigurationProperties("server") -public class ServerProperties { - - /** - * Server HTTP port. - */ - private Integer port; - - /** - * Network address to which the server should bind. - */ - private InetAddress address; - - @NestedConfigurationProperty - private final ErrorProperties error = new ErrorProperties(); - - /** - * Strategy for handling X-Forwarded-* headers. - */ - private ForwardHeadersStrategy forwardHeadersStrategy; - - /** - * Value to use for the Server response header (if empty, no header is sent). - */ - private String serverHeader; - - /** - * Maximum size of the HTTP request header. Refer to the documentation for your chosen - * embedded server for details of exactly how this limit is applied. For example, - * Netty applies the limit separately to each individual header in the request whereas - * Tomcat applies the limit to the combined size of the request line and all of the - * header names and values in the request. - */ - private DataSize maxHttpRequestHeaderSize = DataSize.ofKilobytes(8); - - /** - * Type of shutdown that the server will support. - */ - private Shutdown shutdown = Shutdown.GRACEFUL; - - @NestedConfigurationProperty - private Ssl ssl; - - @NestedConfigurationProperty - private final Compression compression = new Compression(); - - /** - * Custom MIME mappings in addition to the default MIME mappings. - */ - private final MimeMappings mimeMappings = new MimeMappings(); - - @NestedConfigurationProperty - private final Http2 http2 = new Http2(); - - private final Servlet servlet = new Servlet(); - - private final Reactive reactive = new Reactive(); - - private final Tomcat tomcat = new Tomcat(); - - private final Jetty jetty = new Jetty(); - - private final Netty netty = new Netty(); - - private final Undertow undertow = new Undertow(); - - public Integer getPort() { - return this.port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public InetAddress getAddress() { - return this.address; - } - - public void setAddress(InetAddress address) { - this.address = address; - } - - public String getServerHeader() { - return this.serverHeader; - } - - public void setServerHeader(String serverHeader) { - this.serverHeader = serverHeader; - } - - public DataSize getMaxHttpRequestHeaderSize() { - return this.maxHttpRequestHeaderSize; - } - - public void setMaxHttpRequestHeaderSize(DataSize maxHttpRequestHeaderSize) { - this.maxHttpRequestHeaderSize = maxHttpRequestHeaderSize; - } - - public Shutdown getShutdown() { - return this.shutdown; - } - - public void setShutdown(Shutdown shutdown) { - this.shutdown = shutdown; - } - - public ErrorProperties getError() { - return this.error; - } - - public Ssl getSsl() { - return this.ssl; - } - - public void setSsl(Ssl ssl) { - this.ssl = ssl; - } - - public Compression getCompression() { - return this.compression; - } - - public MimeMappings getMimeMappings() { - return this.mimeMappings; - } - - public void setMimeMappings(Map customMappings) { - customMappings.forEach(this.mimeMappings::add); - } - - public Http2 getHttp2() { - return this.http2; - } - - public Servlet getServlet() { - return this.servlet; - } - - public Reactive getReactive() { - return this.reactive; - } - - public Tomcat getTomcat() { - return this.tomcat; - } - - public Jetty getJetty() { - return this.jetty; - } - - public Netty getNetty() { - return this.netty; - } - - public Undertow getUndertow() { - return this.undertow; - } - - public ForwardHeadersStrategy getForwardHeadersStrategy() { - return this.forwardHeadersStrategy; - } - - public void setForwardHeadersStrategy(ForwardHeadersStrategy forwardHeadersStrategy) { - this.forwardHeadersStrategy = forwardHeadersStrategy; - } - - /** - * Servlet server properties. - */ - public static class Servlet { - - /** - * Servlet context init parameters. - */ - private final Map contextParameters = new HashMap<>(); - - /** - * Context path of the application. - */ - private String contextPath; - - /** - * Display name of the application. - */ - private String applicationDisplayName = "application"; - - /** - * Whether to register the default Servlet with the container. - */ - private boolean registerDefaultServlet = false; - - private final Encoding encoding = new Encoding(); - - @NestedConfigurationProperty - private final Jsp jsp = new Jsp(); - - @NestedConfigurationProperty - private final Session session = new Session(); - - public String getContextPath() { - return this.contextPath; - } - - public void setContextPath(String contextPath) { - this.contextPath = cleanContextPath(contextPath); - } - - private String cleanContextPath(String contextPath) { - String candidate = null; - if (StringUtils.hasLength(contextPath)) { - candidate = contextPath.strip(); - } - if (StringUtils.hasText(candidate) && candidate.endsWith("/")) { - return candidate.substring(0, candidate.length() - 1); - } - return candidate; - } - - public String getApplicationDisplayName() { - return this.applicationDisplayName; - } - - public void setApplicationDisplayName(String displayName) { - this.applicationDisplayName = displayName; - } - - public boolean isRegisterDefaultServlet() { - return this.registerDefaultServlet; - } - - public void setRegisterDefaultServlet(boolean registerDefaultServlet) { - this.registerDefaultServlet = registerDefaultServlet; - } - - public Map getContextParameters() { - return this.contextParameters; - } - - public Encoding getEncoding() { - return this.encoding; - } - - public Jsp getJsp() { - return this.jsp; - } - - public Session getSession() { - return this.session; - } - - } - - /** - * Reactive server properties. - */ - public static class Reactive { - - private final Session session = new Session(); - - public Session getSession() { - return this.session; - } - - public static class Session { - - /** - * Session timeout. If a duration suffix is not specified, seconds will be - * used. - */ - @DurationUnit(ChronoUnit.SECONDS) - private Duration timeout = Duration.ofMinutes(30); - - /** - * Maximum number of sessions that can be stored. - */ - private int maxSessions = 10000; - - @NestedConfigurationProperty - private final Cookie cookie = new Cookie(); - - public Duration getTimeout() { - return this.timeout; - } - - public void setTimeout(Duration timeout) { - this.timeout = timeout; - } - - public int getMaxSessions() { - return this.maxSessions; - } - - public void setMaxSessions(int maxSessions) { - this.maxSessions = maxSessions; - } - - public Cookie getCookie() { - return this.cookie; - } - - } - - } - - /** - * Tomcat properties. - */ - public static class Tomcat { - - /** - * Access log configuration. - */ - private final Accesslog accesslog = new Accesslog(); - - /** - * Thread related configuration. - */ - private final Threads threads = new Threads(); - - /** - * Tomcat base directory. If not specified, a temporary directory is used. - */ - private File basedir; - - /** - * Delay between the invocation of backgroundProcess methods. If a duration suffix - * is not specified, seconds will be used. - */ - @DurationUnit(ChronoUnit.SECONDS) - private Duration backgroundProcessorDelay = Duration.ofSeconds(10); - - /** - * Maximum size of the form content in any HTTP post request. - */ - private DataSize maxHttpFormPostSize = DataSize.ofMegabytes(2); - - /** - * Maximum per-part header size permitted in a multipart/form-data request. - * Requests that exceed this limit will be rejected. A value of less than 0 means - * no limit. - */ - private DataSize maxPartHeaderSize = DataSize.ofBytes(512); - - /** - * Maximum total number of parts permitted in a multipart/form-data request. - * Requests that exceed this limit will be rejected. A value of less than 0 means - * no limit. - */ - private int maxPartCount = 10; - - /** - * Maximum amount of request body to swallow. - */ - private DataSize maxSwallowSize = DataSize.ofMegabytes(2); - - /** - * Whether requests to the context root should be redirected by appending a / to - * the path. When using SSL terminated at a proxy, this property should be set to - * false. - */ - private Boolean redirectContextRoot = true; - - /** - * Whether HTTP 1.1 and later location headers generated by a call to sendRedirect - * will use relative or absolute redirects. - */ - private boolean useRelativeRedirects; - - /** - * Character encoding to use to decode the URI. - */ - private Charset uriEncoding = StandardCharsets.UTF_8; - - /** - * Maximum number of connections that the server accepts and processes at any - * given time. Once the limit has been reached, the operating system may still - * accept connections based on the "acceptCount" property. - */ - private int maxConnections = 8192; - - /** - * Maximum queue length for incoming connection requests when all possible request - * processing threads are in use. - */ - private int acceptCount = 100; - - /** - * Maximum number of idle processors that will be retained in the cache and reused - * with a subsequent request. When set to -1 the cache will be unlimited with a - * theoretical maximum size equal to the maximum number of connections. - */ - private int processorCache = 200; - - /** - * Time to wait for another HTTP request before the connection is closed. When not - * set the connectionTimeout is used. When set to -1 there will be no timeout. - */ - private Duration keepAliveTimeout; - - /** - * Maximum number of HTTP requests that can be pipelined before the connection is - * closed. When set to 0 or 1, keep-alive and pipelining are disabled. When set to - * -1, an unlimited number of pipelined or keep-alive requests are allowed. - */ - private int maxKeepAliveRequests = 100; - - /** - * List of additional patterns that match jars to ignore for TLD scanning. The - * special '?' and '*' characters can be used in the pattern to match one and only - * one character and zero or more characters respectively. - */ - private List additionalTldSkipPatterns = new ArrayList<>(); - - /** - * List of additional unencoded characters that should be allowed in URI paths. - * Only "< > [ \ ] ^ ` { | }" are allowed. - */ - private List relaxedPathChars = new ArrayList<>(); - - /** - * List of additional unencoded characters that should be allowed in URI query - * strings. Only "< > [ \ ] ^ ` { | }" are allowed. - */ - private List relaxedQueryChars = new ArrayList<>(); - - /** - * Amount of time the connector will wait, after accepting a connection, for the - * request URI line to be presented. - */ - private Duration connectionTimeout; - - /** - * Static resource configuration. - */ - private final Resource resource = new Resource(); - - /** - * Modeler MBean Registry configuration. - */ - private final Mbeanregistry mbeanregistry = new Mbeanregistry(); - - /** - * Remote Ip Valve configuration. - */ - private final Remoteip remoteip = new Remoteip(); - - /** - * Maximum size of the HTTP response header. - */ - private DataSize maxHttpResponseHeaderSize = DataSize.ofKilobytes(8); - - /** - * Maximum number of parameters (GET plus POST) that will be automatically parsed - * by the container. A value of less than 0 means no limit. - */ - private int maxParameterCount = 1000; - - /** - * Whether to use APR. - */ - private UseApr useApr = UseApr.NEVER; - - public DataSize getMaxPartHeaderSize() { - return this.maxPartHeaderSize; - } - - public void setMaxPartHeaderSize(DataSize maxPartHeaderSize) { - this.maxPartHeaderSize = maxPartHeaderSize; - } - - public int getMaxPartCount() { - return this.maxPartCount; - } - - public void setMaxPartCount(int maxPartCount) { - this.maxPartCount = maxPartCount; - } - - public Accesslog getAccesslog() { - return this.accesslog; - } - - public Threads getThreads() { - return this.threads; - } - - public Duration getBackgroundProcessorDelay() { - return this.backgroundProcessorDelay; - } - - public void setBackgroundProcessorDelay(Duration backgroundProcessorDelay) { - this.backgroundProcessorDelay = backgroundProcessorDelay; - } - - public File getBasedir() { - return this.basedir; - } - - public void setBasedir(File basedir) { - this.basedir = basedir; - } - - public Boolean getRedirectContextRoot() { - return this.redirectContextRoot; - } - - public void setRedirectContextRoot(Boolean redirectContextRoot) { - this.redirectContextRoot = redirectContextRoot; - } - - public boolean isUseRelativeRedirects() { - return this.useRelativeRedirects; - } - - public void setUseRelativeRedirects(boolean useRelativeRedirects) { - this.useRelativeRedirects = useRelativeRedirects; - } - - public Charset getUriEncoding() { - return this.uriEncoding; - } - - public void setUriEncoding(Charset uriEncoding) { - this.uriEncoding = uriEncoding; - } - - public int getMaxConnections() { - return this.maxConnections; - } - - public void setMaxConnections(int maxConnections) { - this.maxConnections = maxConnections; - } - - public DataSize getMaxSwallowSize() { - return this.maxSwallowSize; - } - - public void setMaxSwallowSize(DataSize maxSwallowSize) { - this.maxSwallowSize = maxSwallowSize; - } - - public int getAcceptCount() { - return this.acceptCount; - } - - public void setAcceptCount(int acceptCount) { - this.acceptCount = acceptCount; - } - - public int getProcessorCache() { - return this.processorCache; - } - - public void setProcessorCache(int processorCache) { - this.processorCache = processorCache; - } - - public Duration getKeepAliveTimeout() { - return this.keepAliveTimeout; - } - - public void setKeepAliveTimeout(Duration keepAliveTimeout) { - this.keepAliveTimeout = keepAliveTimeout; - } - - public int getMaxKeepAliveRequests() { - return this.maxKeepAliveRequests; - } - - public void setMaxKeepAliveRequests(int maxKeepAliveRequests) { - this.maxKeepAliveRequests = maxKeepAliveRequests; - } - - public List getAdditionalTldSkipPatterns() { - return this.additionalTldSkipPatterns; - } - - public void setAdditionalTldSkipPatterns(List additionalTldSkipPatterns) { - this.additionalTldSkipPatterns = additionalTldSkipPatterns; - } - - public List getRelaxedPathChars() { - return this.relaxedPathChars; - } - - public void setRelaxedPathChars(List relaxedPathChars) { - this.relaxedPathChars = relaxedPathChars; - } - - public List getRelaxedQueryChars() { - return this.relaxedQueryChars; - } - - public void setRelaxedQueryChars(List relaxedQueryChars) { - this.relaxedQueryChars = relaxedQueryChars; - } - - public Duration getConnectionTimeout() { - return this.connectionTimeout; - } - - public void setConnectionTimeout(Duration connectionTimeout) { - this.connectionTimeout = connectionTimeout; - } - - public Resource getResource() { - return this.resource; - } - - public Mbeanregistry getMbeanregistry() { - return this.mbeanregistry; - } - - public Remoteip getRemoteip() { - return this.remoteip; - } - - public DataSize getMaxHttpResponseHeaderSize() { - return this.maxHttpResponseHeaderSize; - } - - public void setMaxHttpResponseHeaderSize(DataSize maxHttpResponseHeaderSize) { - this.maxHttpResponseHeaderSize = maxHttpResponseHeaderSize; - } - - public DataSize getMaxHttpFormPostSize() { - return this.maxHttpFormPostSize; - } - - public void setMaxHttpFormPostSize(DataSize maxHttpFormPostSize) { - this.maxHttpFormPostSize = maxHttpFormPostSize; - } - - public int getMaxParameterCount() { - return this.maxParameterCount; - } - - public void setMaxParameterCount(int maxParameterCount) { - this.maxParameterCount = maxParameterCount; - } - - public UseApr getUseApr() { - return this.useApr; - } - - public void setUseApr(UseApr useApr) { - this.useApr = useApr; - } - - /** - * Tomcat access log properties. - */ - public static class Accesslog { - - /** - * Enable access log. - */ - private boolean enabled = false; - - /** - * Whether logging of the request will only be enabled if - * "ServletRequest.getAttribute(conditionIf)" does not yield null. - */ - private String conditionIf; - - /** - * Whether logging of the request will only be enabled if - * "ServletRequest.getAttribute(conditionUnless)" yield null. - */ - private String conditionUnless; - - /** - * Format pattern for access logs. - */ - private String pattern = "common"; - - /** - * Directory in which log files are created. Can be absolute or relative to - * the Tomcat base dir. - */ - private String directory = "logs"; - - /** - * Log file name prefix. - */ - protected String prefix = "access_log"; - - /** - * Log file name suffix. - */ - private String suffix = ".log"; - - /** - * Character set used by the log file. Default to the system default character - * set. - */ - private String encoding; - - /** - * Locale used to format timestamps in log entries and in log file name - * suffix. Default to the default locale of the Java process. - */ - private String locale; - - /** - * Whether to check for log file existence so it can be recreated if an - * external process has renamed it. - */ - private boolean checkExists = false; - - /** - * Whether to enable access log rotation. - */ - private boolean rotate = true; - - /** - * Whether to defer inclusion of the date stamp in the file name until rotate - * time. - */ - private boolean renameOnRotate = false; - - /** - * Number of days to retain the access log files before they are removed. - */ - private int maxDays = -1; - - /** - * Date format to place in the log file name. - */ - private String fileDateFormat = ".yyyy-MM-dd"; - - /** - * Whether to use IPv6 canonical representation format as defined by RFC 5952. - */ - private boolean ipv6Canonical = false; - - /** - * Set request attributes for the IP address, Hostname, protocol, and port - * used for the request. - */ - private boolean requestAttributesEnabled = false; - - /** - * Whether to buffer output such that it is flushed only periodically. - */ - private boolean buffered = true; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public String getConditionIf() { - return this.conditionIf; - } - - public void setConditionIf(String conditionIf) { - this.conditionIf = conditionIf; - } - - public String getConditionUnless() { - return this.conditionUnless; - } - - public void setConditionUnless(String conditionUnless) { - this.conditionUnless = conditionUnless; - } - - public String getPattern() { - return this.pattern; - } - - public void setPattern(String pattern) { - this.pattern = pattern; - } - - public String getDirectory() { - return this.directory; - } - - public void setDirectory(String directory) { - this.directory = directory; - } - - public String getPrefix() { - return this.prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getSuffix() { - return this.suffix; - } - - public void setSuffix(String suffix) { - this.suffix = suffix; - } - - public String getEncoding() { - return this.encoding; - } - - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - public String getLocale() { - return this.locale; - } - - public void setLocale(String locale) { - this.locale = locale; - } - - public boolean isCheckExists() { - return this.checkExists; - } - - public void setCheckExists(boolean checkExists) { - this.checkExists = checkExists; - } - - public boolean isRotate() { - return this.rotate; - } - - public void setRotate(boolean rotate) { - this.rotate = rotate; - } - - public boolean isRenameOnRotate() { - return this.renameOnRotate; - } - - public void setRenameOnRotate(boolean renameOnRotate) { - this.renameOnRotate = renameOnRotate; - } - - public int getMaxDays() { - return this.maxDays; - } - - public void setMaxDays(int maxDays) { - this.maxDays = maxDays; - } - - public String getFileDateFormat() { - return this.fileDateFormat; - } - - public void setFileDateFormat(String fileDateFormat) { - this.fileDateFormat = fileDateFormat; - } - - public boolean isIpv6Canonical() { - return this.ipv6Canonical; - } - - public void setIpv6Canonical(boolean ipv6Canonical) { - this.ipv6Canonical = ipv6Canonical; - } - - public boolean isRequestAttributesEnabled() { - return this.requestAttributesEnabled; - } - - public void setRequestAttributesEnabled(boolean requestAttributesEnabled) { - this.requestAttributesEnabled = requestAttributesEnabled; - } - - public boolean isBuffered() { - return this.buffered; - } - - public void setBuffered(boolean buffered) { - this.buffered = buffered; - } - - } - - /** - * Tomcat thread properties. - */ - public static class Threads { - - /** - * Maximum amount of worker threads. Doesn't have an effect if virtual threads - * are enabled. - */ - private int max = 200; - - /** - * Minimum amount of worker threads. Doesn't have an effect if virtual threads - * are enabled. - */ - private int minSpare = 10; - - /** - * Maximum capacity of the thread pool's backing queue. This setting only has - * an effect if the value is greater than 0. - */ - private int maxQueueCapacity = 2147483647; - - public int getMax() { - return this.max; - } - - public void setMax(int max) { - this.max = max; - } - - public int getMinSpare() { - return this.minSpare; - } - - public void setMinSpare(int minSpare) { - this.minSpare = minSpare; - } - - public int getMaxQueueCapacity() { - return this.maxQueueCapacity; - } - - public void setMaxQueueCapacity(int maxQueueCapacity) { - this.maxQueueCapacity = maxQueueCapacity; - } - - } - - /** - * Tomcat static resource properties. - */ - public static class Resource { - - /** - * Whether static resource caching is permitted for this web application. - */ - private boolean allowCaching = true; - - /** - * Time-to-live of the static resource cache. - */ - private Duration cacheTtl; - - public boolean isAllowCaching() { - return this.allowCaching; - } - - public void setAllowCaching(boolean allowCaching) { - this.allowCaching = allowCaching; - } - - public Duration getCacheTtl() { - return this.cacheTtl; - } - - public void setCacheTtl(Duration cacheTtl) { - this.cacheTtl = cacheTtl; - } - - } - - public static class Mbeanregistry { - - /** - * Whether Tomcat's MBean Registry should be enabled. - */ - private boolean enabled; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - } - - public static class Remoteip { - - /** - * Regular expression that matches proxies that are to be trusted. - */ - private String internalProxies = "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 10/8 - + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" // 192.168/16 - + "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" // 169.254/16 - + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 127/8 - + "100\\.6[4-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 - + "100\\.[7-9]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 - + "100\\.1[0-1]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 - + "100\\.12[0-7]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 - + "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 - + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 - + "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 - + "0:0:0:0:0:0:0:1|" // 0:0:0:0:0:0:0:1 - + "::1|" // ::1 - + "fe[89ab]\\p{XDigit}:.*|" // - + "f[cd]\\p{XDigit}{2}+:.*"; - - /** - * Header that holds the incoming protocol, usually named "X-Forwarded-Proto". - */ - private String protocolHeader; - - /** - * Value of the protocol header indicating whether the incoming request uses - * SSL. - */ - private String protocolHeaderHttpsValue = "https"; - - /** - * Name of the HTTP header from which the remote host is extracted. - */ - private String hostHeader = "X-Forwarded-Host"; - - /** - * Name of the HTTP header used to override the original port value. - */ - private String portHeader = "X-Forwarded-Port"; - - /** - * Name of the HTTP header from which the remote IP is extracted. For - * instance, 'X-FORWARDED-FOR'. - */ - private String remoteIpHeader; - - /** - * Regular expression defining proxies that are trusted when they appear in - * the "remote-ip-header" header. - */ - private String trustedProxies; - - public String getInternalProxies() { - return this.internalProxies; - } - - public void setInternalProxies(String internalProxies) { - this.internalProxies = internalProxies; - } - - public String getProtocolHeader() { - return this.protocolHeader; - } - - public void setProtocolHeader(String protocolHeader) { - this.protocolHeader = protocolHeader; - } - - public String getProtocolHeaderHttpsValue() { - return this.protocolHeaderHttpsValue; - } - - public String getHostHeader() { - return this.hostHeader; - } - - public void setHostHeader(String hostHeader) { - this.hostHeader = hostHeader; - } - - public void setProtocolHeaderHttpsValue(String protocolHeaderHttpsValue) { - this.protocolHeaderHttpsValue = protocolHeaderHttpsValue; - } - - public String getPortHeader() { - return this.portHeader; - } - - public void setPortHeader(String portHeader) { - this.portHeader = portHeader; - } - - public String getRemoteIpHeader() { - return this.remoteIpHeader; - } - - public void setRemoteIpHeader(String remoteIpHeader) { - this.remoteIpHeader = remoteIpHeader; - } - - public String getTrustedProxies() { - return this.trustedProxies; - } - - public void setTrustedProxies(String trustedProxies) { - this.trustedProxies = trustedProxies; - } - - } - - /** - * When to use APR. - */ - public enum UseApr { - - /** - * Always use APR and fail if it's not available. - */ - ALWAYS, - - /** - * Use APR if it is available. - */ - WHEN_AVAILABLE, - - /** - * Never use APR. - */ - NEVER - - } - - } - - /** - * Jetty properties. - */ - public static class Jetty { - - /** - * Access log configuration. - */ - private final Accesslog accesslog = new Accesslog(); - - /** - * Thread related configuration. - */ - private final Threads threads = new Threads(); - - /** - * Maximum size of the form content in any HTTP post request. - */ - private DataSize maxHttpFormPostSize = DataSize.ofBytes(200000); - - /** - * Maximum number of form keys. - */ - private int maxFormKeys = 1000; - - /** - * Time that the connection can be idle before it is closed. - */ - private Duration connectionIdleTimeout; - - /** - * Maximum size of the HTTP response header. - */ - private DataSize maxHttpResponseHeaderSize = DataSize.ofKilobytes(8); - - /** - * Maximum number of connections that the server accepts and processes at any - * given time. - */ - private int maxConnections = -1; - - public Accesslog getAccesslog() { - return this.accesslog; - } - - public Threads getThreads() { - return this.threads; - } - - public DataSize getMaxHttpFormPostSize() { - return this.maxHttpFormPostSize; - } - - public void setMaxHttpFormPostSize(DataSize maxHttpFormPostSize) { - this.maxHttpFormPostSize = maxHttpFormPostSize; - } - - public int getMaxFormKeys() { - return this.maxFormKeys; - } - - public void setMaxFormKeys(int maxFormKeys) { - this.maxFormKeys = maxFormKeys; - } - - public Duration getConnectionIdleTimeout() { - return this.connectionIdleTimeout; - } - - public void setConnectionIdleTimeout(Duration connectionIdleTimeout) { - this.connectionIdleTimeout = connectionIdleTimeout; - } - - public DataSize getMaxHttpResponseHeaderSize() { - return this.maxHttpResponseHeaderSize; - } - - public void setMaxHttpResponseHeaderSize(DataSize maxHttpResponseHeaderSize) { - this.maxHttpResponseHeaderSize = maxHttpResponseHeaderSize; - } - - public int getMaxConnections() { - return this.maxConnections; - } - - public void setMaxConnections(int maxConnections) { - this.maxConnections = maxConnections; - } - - /** - * Jetty access log properties. - */ - public static class Accesslog { - - /** - * Enable access log. - */ - private boolean enabled = false; - - /** - * Log format. - */ - private Format format = Format.NCSA; - - /** - * Custom log format, see org.eclipse.jetty.server.CustomRequestLog. If - * defined, overrides the "format" configuration key. - */ - private String customFormat; - - /** - * Log filename. If not specified, logs redirect to "System.err". - */ - private String filename; - - /** - * Date format to place in log file name. - */ - private String fileDateFormat; - - /** - * Number of days before rotated log files are deleted. - */ - private int retentionPeriod = 31; // no days - - /** - * Append to log. - */ - private boolean append; - - /** - * Request paths that should not be logged. - */ - private List ignorePaths; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public Format getFormat() { - return this.format; - } - - public void setFormat(Format format) { - this.format = format; - } - - public String getCustomFormat() { - return this.customFormat; - } - - public void setCustomFormat(String customFormat) { - this.customFormat = customFormat; - } - - public String getFilename() { - return this.filename; - } - - public void setFilename(String filename) { - this.filename = filename; - } - - public String getFileDateFormat() { - return this.fileDateFormat; - } - - public void setFileDateFormat(String fileDateFormat) { - this.fileDateFormat = fileDateFormat; - } - - public int getRetentionPeriod() { - return this.retentionPeriod; - } - - public void setRetentionPeriod(int retentionPeriod) { - this.retentionPeriod = retentionPeriod; - } - - public boolean isAppend() { - return this.append; - } - - public void setAppend(boolean append) { - this.append = append; - } - - public List getIgnorePaths() { - return this.ignorePaths; - } - - public void setIgnorePaths(List ignorePaths) { - this.ignorePaths = ignorePaths; - } - - /** - * Log format for Jetty access logs. - */ - public enum Format { - - /** - * NCSA format, as defined in CustomRequestLog#NCSA_FORMAT. - */ - NCSA, - - /** - * Extended NCSA format, as defined in - * CustomRequestLog#EXTENDED_NCSA_FORMAT. - */ - EXTENDED_NCSA - - } - - } - - /** - * Jetty thread properties. - */ - public static class Threads { - - /** - * Number of acceptor threads to use. When the value is -1, the default, the - * number of acceptors is derived from the operating environment. - */ - private Integer acceptors = -1; - - /** - * Number of selector threads to use. When the value is -1, the default, the - * number of selectors is derived from the operating environment. - */ - private Integer selectors = -1; - - /** - * Maximum number of threads. Doesn't have an effect if virtual threads are - * enabled. - */ - private Integer max = 200; - - /** - * Minimum number of threads. Doesn't have an effect if virtual threads are - * enabled. - */ - private Integer min = 8; - - /** - * Maximum capacity of the thread pool's backing queue. A default is computed - * based on the threading configuration. - */ - private Integer maxQueueCapacity; - - /** - * Maximum thread idle time. - */ - private Duration idleTimeout = Duration.ofMillis(60000); - - public Integer getAcceptors() { - return this.acceptors; - } - - public void setAcceptors(Integer acceptors) { - this.acceptors = acceptors; - } - - public Integer getSelectors() { - return this.selectors; - } - - public void setSelectors(Integer selectors) { - this.selectors = selectors; - } - - public void setMin(Integer min) { - this.min = min; - } - - public Integer getMin() { - return this.min; - } - - public void setMax(Integer max) { - this.max = max; - } - - public Integer getMax() { - return this.max; - } - - public Integer getMaxQueueCapacity() { - return this.maxQueueCapacity; - } - - public void setMaxQueueCapacity(Integer maxQueueCapacity) { - this.maxQueueCapacity = maxQueueCapacity; - } - - public void setIdleTimeout(Duration idleTimeout) { - this.idleTimeout = idleTimeout; - } - - public Duration getIdleTimeout() { - return this.idleTimeout; - } - - } - - } - - /** - * Netty properties. - */ - public static class Netty { - - /** - * Connection timeout of the Netty channel. - */ - private Duration connectionTimeout; - - /** - * Maximum content length of an H2C upgrade request. - */ - private DataSize h2cMaxContentLength = DataSize.ofBytes(0); - - /** - * Initial buffer size for HTTP request decoding. - */ - private DataSize initialBufferSize = DataSize.ofBytes(128); - - /** - * Maximum length that can be decoded for an HTTP request's initial line. - */ - private DataSize maxInitialLineLength = DataSize.ofKilobytes(4); - - /** - * Maximum number of requests that can be made per connection. By default, a - * connection serves unlimited number of requests. - */ - private Integer maxKeepAliveRequests; - - /** - * Whether to validate headers when decoding requests. - */ - private boolean validateHeaders = true; - - /** - * Idle timeout of the Netty channel. When not specified, an infinite timeout is - * used. - */ - private Duration idleTimeout; - - public Duration getConnectionTimeout() { - return this.connectionTimeout; - } - - public void setConnectionTimeout(Duration connectionTimeout) { - this.connectionTimeout = connectionTimeout; - } - - public DataSize getH2cMaxContentLength() { - return this.h2cMaxContentLength; - } - - public void setH2cMaxContentLength(DataSize h2cMaxContentLength) { - this.h2cMaxContentLength = h2cMaxContentLength; - } - - public DataSize getInitialBufferSize() { - return this.initialBufferSize; - } - - public void setInitialBufferSize(DataSize initialBufferSize) { - this.initialBufferSize = initialBufferSize; - } - - public DataSize getMaxInitialLineLength() { - return this.maxInitialLineLength; - } - - public void setMaxInitialLineLength(DataSize maxInitialLineLength) { - this.maxInitialLineLength = maxInitialLineLength; - } - - public Integer getMaxKeepAliveRequests() { - return this.maxKeepAliveRequests; - } - - public void setMaxKeepAliveRequests(Integer maxKeepAliveRequests) { - this.maxKeepAliveRequests = maxKeepAliveRequests; - } - - public boolean isValidateHeaders() { - return this.validateHeaders; - } - - public void setValidateHeaders(boolean validateHeaders) { - this.validateHeaders = validateHeaders; - } - - public Duration getIdleTimeout() { - return this.idleTimeout; - } - - public void setIdleTimeout(Duration idleTimeout) { - this.idleTimeout = idleTimeout; - } - - } - - /** - * Undertow properties. - */ - public static class Undertow { - - /** - * Maximum size of the HTTP post content. When the value is -1, the default, the - * size is unlimited. - */ - private DataSize maxHttpPostSize = DataSize.ofBytes(-1); - - /** - * Size of each buffer. The default is derived from the maximum amount of memory - * that is available to the JVM. - */ - private DataSize bufferSize; - - /** - * Whether to allocate buffers outside the Java heap. The default is derived from - * the maximum amount of memory that is available to the JVM. - */ - private Boolean directBuffers; - - /** - * Whether servlet filters should be initialized on startup. - */ - private boolean eagerFilterInit = true; - - /** - * Maximum number of query or path parameters that are allowed. This limit exists - * to prevent hash collision based DOS attacks. - */ - private int maxParameters = UndertowOptions.DEFAULT_MAX_PARAMETERS; - - /** - * Maximum number of headers that are allowed. This limit exists to prevent hash - * collision based DOS attacks. - */ - private int maxHeaders = UndertowOptions.DEFAULT_MAX_HEADERS; - - /** - * Maximum number of cookies that are allowed. This limit exists to prevent hash - * collision based DOS attacks. - */ - private int maxCookies = 200; - - /** - * Whether the server should decode percent encoded slash characters. Enabling - * encoded slashes can have security implications due to different servers - * interpreting the slash differently. Only enable this if you have a legacy - * application that requires it. Has no effect when server.undertow.decode-slash - * is set. - */ - private boolean allowEncodedSlash = false; - - /** - * Whether encoded slash characters (%2F) should be decoded. Decoding can cause - * security problems if a front-end proxy does not perform the same decoding. Only - * enable this if you have a legacy application that requires it. When set, - * server.undertow.allow-encoded-slash has no effect. - */ - private Boolean decodeSlash; - - /** - * Whether the URL should be decoded. When disabled, percent-encoded characters in - * the URL will be left as-is. - */ - private boolean decodeUrl = true; - - /** - * Charset used to decode URLs. - */ - private Charset urlCharset = StandardCharsets.UTF_8; - - /** - * Whether the 'Connection: keep-alive' header should be added to all responses, - * even if not required by the HTTP specification. - */ - private boolean alwaysSetKeepAlive = true; - - /** - * Amount of time a connection can sit idle without processing a request, before - * it is closed by the server. - */ - private Duration noRequestTimeout; - - /** - * Whether to preserve the path of a request when it is forwarded. - */ - private boolean preservePathOnForward = false; - - private final Accesslog accesslog = new Accesslog(); - - /** - * Thread related configuration. - */ - private final Threads threads = new Threads(); - - private final Options options = new Options(); - - public DataSize getMaxHttpPostSize() { - return this.maxHttpPostSize; - } - - public void setMaxHttpPostSize(DataSize maxHttpPostSize) { - this.maxHttpPostSize = maxHttpPostSize; - } - - public DataSize getBufferSize() { - return this.bufferSize; - } - - public void setBufferSize(DataSize bufferSize) { - this.bufferSize = bufferSize; - } - - public Boolean getDirectBuffers() { - return this.directBuffers; - } - - public void setDirectBuffers(Boolean directBuffers) { - this.directBuffers = directBuffers; - } - - public boolean isEagerFilterInit() { - return this.eagerFilterInit; - } - - public void setEagerFilterInit(boolean eagerFilterInit) { - this.eagerFilterInit = eagerFilterInit; - } - - public int getMaxParameters() { - return this.maxParameters; - } - - public void setMaxParameters(Integer maxParameters) { - this.maxParameters = maxParameters; - } - - public int getMaxHeaders() { - return this.maxHeaders; - } - - public void setMaxHeaders(int maxHeaders) { - this.maxHeaders = maxHeaders; - } - - public Integer getMaxCookies() { - return this.maxCookies; - } - - public void setMaxCookies(Integer maxCookies) { - this.maxCookies = maxCookies; - } - - @DeprecatedConfigurationProperty(replacement = "server.undertow.decode-slash", since = "3.0.3") - @Deprecated(forRemoval = true, since = "3.0.3") - public boolean isAllowEncodedSlash() { - return this.allowEncodedSlash; - } - - @Deprecated(forRemoval = true, since = "3.0.3") - public void setAllowEncodedSlash(boolean allowEncodedSlash) { - this.allowEncodedSlash = allowEncodedSlash; - } - - public Boolean getDecodeSlash() { - return this.decodeSlash; - } - - public void setDecodeSlash(Boolean decodeSlash) { - this.decodeSlash = decodeSlash; - } - - public boolean isDecodeUrl() { - return this.decodeUrl; - } - - public void setDecodeUrl(Boolean decodeUrl) { - this.decodeUrl = decodeUrl; - } - - public Charset getUrlCharset() { - return this.urlCharset; - } - - public void setUrlCharset(Charset urlCharset) { - this.urlCharset = urlCharset; - } - - public boolean isAlwaysSetKeepAlive() { - return this.alwaysSetKeepAlive; - } - - public void setAlwaysSetKeepAlive(boolean alwaysSetKeepAlive) { - this.alwaysSetKeepAlive = alwaysSetKeepAlive; - } - - public Duration getNoRequestTimeout() { - return this.noRequestTimeout; - } - - public void setNoRequestTimeout(Duration noRequestTimeout) { - this.noRequestTimeout = noRequestTimeout; - } - - public boolean isPreservePathOnForward() { - return this.preservePathOnForward; - } - - public void setPreservePathOnForward(boolean preservePathOnForward) { - this.preservePathOnForward = preservePathOnForward; - } - - public Accesslog getAccesslog() { - return this.accesslog; - } - - public Threads getThreads() { - return this.threads; - } - - public Options getOptions() { - return this.options; - } - - /** - * Undertow access log properties. - */ - public static class Accesslog { - - /** - * Whether to enable the access log. - */ - private boolean enabled = false; - - /** - * Format pattern for access logs. - */ - private String pattern = "common"; - - /** - * Log file name prefix. - */ - protected String prefix = "access_log."; - - /** - * Log file name suffix. - */ - private String suffix = "log"; - - /** - * Undertow access log directory. - */ - private File dir = new File("logs"); - - /** - * Whether to enable access log rotation. - */ - private boolean rotate = true; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public String getPattern() { - return this.pattern; - } - - public void setPattern(String pattern) { - this.pattern = pattern; - } - - public String getPrefix() { - return this.prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getSuffix() { - return this.suffix; - } - - public void setSuffix(String suffix) { - this.suffix = suffix; - } - - public File getDir() { - return this.dir; - } - - public void setDir(File dir) { - this.dir = dir; - } - - public boolean isRotate() { - return this.rotate; - } - - public void setRotate(boolean rotate) { - this.rotate = rotate; - } - - } - - /** - * Undertow thread properties. - */ - public static class Threads { - - /** - * Number of I/O threads to create for the worker. The default is derived from - * the number of available processors. - */ - private Integer io; - - /** - * Number of worker threads. The default is 8 times the number of I/O threads. - */ - private Integer worker; - - public Integer getIo() { - return this.io; - } - - public void setIo(Integer io) { - this.io = io; - } - - public Integer getWorker() { - return this.worker; - } - - public void setWorker(Integer worker) { - this.worker = worker; - } - - } - - public static class Options { - - /** - * Socket options as defined in org.xnio.Options. - */ - private final Map socket = new LinkedHashMap<>(); - - /** - * Server options as defined in io.undertow.UndertowOptions. - */ - private final Map server = new LinkedHashMap<>(); - - public Map getServer() { - return this.server; - } - - public Map getSocket() { - return this.socket; - } - - } - - } - - /** - * Strategies for supporting forward headers. - */ - public enum ForwardHeadersStrategy { - - /** - * Use the underlying container's native support for forwarded headers. - */ - NATIVE, - - /** - * Use Spring's support for handling forwarded headers. - */ - FRAMEWORK, - - /** - * Ignore X-Forwarded-* headers. - */ - NONE - - } - - public static class Encoding { - - /** - * Mapping of locale to charset for response encoding. - */ - private Map mapping; - - public Map getMapping() { - return this.mapping; - } - - public void setMapping(Map mapping) { - this.mapping = mapping; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/NotReactiveWebApplicationCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/NotReactiveWebApplicationCondition.java deleted file mode 100644 index 647649a4e878..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/NotReactiveWebApplicationCondition.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.client; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; - -/** - * {@link SpringBootCondition} that applies only when running in a non-reactive web - * application. - * - * @author Phillip Webb - */ -class NotReactiveWebApplicationCondition extends NoneNestedConditions { - - NotReactiveWebApplicationCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - private static final class ReactiveWebApplication { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/package-info.java deleted file mode 100644 index f18fd767aae6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for web clients. - */ -package org.springframework.boot.autoconfigure.web.client; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration.java deleted file mode 100644 index 00e73ab6fbab..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.embedded; - -import io.undertow.Undertow; -import org.apache.catalina.startup.Tomcat; -import org.apache.coyote.UpgradeProtocol; -import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.Loader; -import org.xnio.SslClientAuthMode; -import reactor.netty.http.server.HttpServer; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; -import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.thread.Threading; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.core.task.VirtualThreadTaskExecutor; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for embedded servlet and reactive - * web servers customizations. - * - * @author Phillip Webb - * @author Moritz Halbritter - * @since 2.0.0 - */ -@AutoConfiguration -@ConditionalOnNotWarDeployment -@ConditionalOnWebApplication -@EnableConfigurationProperties(ServerProperties.class) -public class EmbeddedWebServerFactoryCustomizerAutoConfiguration { - - /** - * Nested configuration if Tomcat is being used. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class }) - public static class TomcatWebServerFactoryCustomizerConfiguration { - - @Bean - public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, - ServerProperties serverProperties) { - return new TomcatWebServerFactoryCustomizer(environment, serverProperties); - } - - @Bean - @ConditionalOnThreading(Threading.VIRTUAL) - TomcatVirtualThreadsWebServerFactoryCustomizer tomcatVirtualThreadsProtocolHandlerCustomizer() { - return new TomcatVirtualThreadsWebServerFactoryCustomizer(); - } - - } - - /** - * Nested configuration if Jetty is being used. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class }) - public static class JettyWebServerFactoryCustomizerConfiguration { - - @Bean - public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment, - ServerProperties serverProperties) { - return new JettyWebServerFactoryCustomizer(environment, serverProperties); - } - - @Bean - @ConditionalOnThreading(Threading.VIRTUAL) - JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer( - ServerProperties serverProperties) { - return new JettyVirtualThreadsWebServerFactoryCustomizer(serverProperties); - } - - } - - /** - * Nested configuration if Undertow is being used. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ Undertow.class, SslClientAuthMode.class }) - public static class UndertowWebServerFactoryCustomizerConfiguration { - - @Bean - public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment, - ServerProperties serverProperties) { - return new UndertowWebServerFactoryCustomizer(environment, serverProperties); - } - - @Bean - @ConditionalOnThreading(Threading.VIRTUAL) - UndertowDeploymentInfoCustomizer virtualThreadsUndertowDeploymentInfoCustomizer() { - return (deploymentInfo) -> deploymentInfo.setExecutor(new VirtualThreadTaskExecutor("undertow-")); - } - - } - - /** - * Nested configuration if Netty is being used. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(HttpServer.class) - public static class NettyWebServerFactoryCustomizerConfiguration { - - @Bean - public NettyWebServerFactoryCustomizer nettyWebServerFactoryCustomizer(Environment environment, - ServerProperties serverProperties) { - return new NettyWebServerFactoryCustomizer(environment, serverProperties); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyVirtualThreadsWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyVirtualThreadsWebServerFactoryCustomizer.java deleted file mode 100644 index 512a19f333d9..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyVirtualThreadsWebServerFactoryCustomizer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.embedded; - -import org.eclipse.jetty.util.VirtualThreads; -import org.eclipse.jetty.util.thread.QueuedThreadPool; - -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; -import org.springframework.util.Assert; - -/** - * Activates virtual threads on the {@link ConfigurableJettyWebServerFactory}. - * - * @author Moritz Halbritter - * @since 3.2.0 - */ -public class JettyVirtualThreadsWebServerFactoryCustomizer - implements WebServerFactoryCustomizer, Ordered { - - private final ServerProperties serverProperties; - - public JettyVirtualThreadsWebServerFactoryCustomizer(ServerProperties serverProperties) { - this.serverProperties = serverProperties; - } - - @Override - public void customize(ConfigurableJettyWebServerFactory factory) { - Assert.state(VirtualThreads.areSupported(), "Virtual threads are not supported"); - QueuedThreadPool threadPool = JettyThreadPool.create(this.serverProperties.getJetty().getThreads()); - threadPool.setVirtualThreadsExecutor(VirtualThreads.getNamedVirtualThreadsExecutor("jetty-")); - factory.setThreadPool(threadPool); - } - - @Override - public int getOrder() { - return JettyWebServerFactoryCustomizer.ORDER + 1; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizer.java deleted file mode 100644 index e053ff2591e1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizer.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.embedded; - -import java.time.Duration; - -import io.netty.channel.ChannelOption; - -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.cloud.CloudPlatform; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; -import org.springframework.core.env.Environment; - -/** - * Customization for Netty-specific features. - * - * @author Brian Clozel - * @author Chentao Qu - * @author Artsiom Yudovin - * @since 2.1.0 - */ -public class NettyWebServerFactoryCustomizer - implements WebServerFactoryCustomizer, Ordered { - - private final Environment environment; - - private final ServerProperties serverProperties; - - public NettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { - this.environment = environment; - this.serverProperties = serverProperties; - } - - @Override - public int getOrder() { - return 0; - } - - @Override - public void customize(NettyReactiveWebServerFactory factory) { - factory.setUseForwardHeaders(getOrDeduceUseForwardHeaders()); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - ServerProperties.Netty nettyProperties = this.serverProperties.getNetty(); - map.from(nettyProperties::getConnectionTimeout) - .to((connectionTimeout) -> customizeConnectionTimeout(factory, connectionTimeout)); - map.from(nettyProperties::getIdleTimeout).to((idleTimeout) -> customizeIdleTimeout(factory, idleTimeout)); - map.from(nettyProperties::getMaxKeepAliveRequests) - .to((maxKeepAliveRequests) -> customizeMaxKeepAliveRequests(factory, maxKeepAliveRequests)); - if (this.serverProperties.getHttp2() != null && this.serverProperties.getHttp2().isEnabled()) { - map.from(this.serverProperties.getMaxHttpRequestHeaderSize()) - .to((size) -> customizeHttp2MaxHeaderSize(factory, size.toBytes())); - } - customizeRequestDecoder(factory, map); - } - - private boolean getOrDeduceUseForwardHeaders() { - if (this.serverProperties.getForwardHeadersStrategy() == null) { - CloudPlatform platform = CloudPlatform.getActive(this.environment); - return platform != null && platform.isUsingForwardHeaders(); - } - return this.serverProperties.getForwardHeadersStrategy().equals(ServerProperties.ForwardHeadersStrategy.NATIVE); - } - - private void customizeConnectionTimeout(NettyReactiveWebServerFactory factory, Duration connectionTimeout) { - factory.addServerCustomizers((httpServer) -> httpServer.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, - (int) connectionTimeout.toMillis())); - } - - private void customizeRequestDecoder(NettyReactiveWebServerFactory factory, PropertyMapper propertyMapper) { - factory.addServerCustomizers((httpServer) -> httpServer.httpRequestDecoder((httpRequestDecoderSpec) -> { - propertyMapper.from(this.serverProperties.getMaxHttpRequestHeaderSize()) - .to((maxHttpRequestHeader) -> httpRequestDecoderSpec - .maxHeaderSize((int) maxHttpRequestHeader.toBytes())); - ServerProperties.Netty nettyProperties = this.serverProperties.getNetty(); - propertyMapper.from(nettyProperties.getMaxInitialLineLength()) - .to((maxInitialLineLength) -> httpRequestDecoderSpec - .maxInitialLineLength((int) maxInitialLineLength.toBytes())); - propertyMapper.from(nettyProperties.getH2cMaxContentLength()) - .to((h2cMaxContentLength) -> httpRequestDecoderSpec - .h2cMaxContentLength((int) h2cMaxContentLength.toBytes())); - propertyMapper.from(nettyProperties.getInitialBufferSize()) - .to((initialBufferSize) -> httpRequestDecoderSpec.initialBufferSize((int) initialBufferSize.toBytes())); - propertyMapper.from(nettyProperties.isValidateHeaders()).to(httpRequestDecoderSpec::validateHeaders); - return httpRequestDecoderSpec; - })); - } - - private void customizeIdleTimeout(NettyReactiveWebServerFactory factory, Duration idleTimeout) { - factory.addServerCustomizers((httpServer) -> httpServer.idleTimeout(idleTimeout)); - } - - private void customizeMaxKeepAliveRequests(NettyReactiveWebServerFactory factory, int maxKeepAliveRequests) { - factory.addServerCustomizers((httpServer) -> httpServer.maxKeepAliveRequests(maxKeepAliveRequests)); - } - - private void customizeHttp2MaxHeaderSize(NettyReactiveWebServerFactory factory, long size) { - factory.addServerCustomizers( - ((httpServer) -> httpServer.http2Settings((settings) -> settings.maxHeaderListSize(size)))); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/package-info.java deleted file mode 100644 index 1a852a41bd54..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Configuration for embedded reactive and servlet web servers. - */ -package org.springframework.boot.autoconfigure.web.embedded; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/WebConversionService.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/WebConversionService.java index da49d73686e4..186bd586d105 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/WebConversionService.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/WebConversionService.java @@ -33,10 +33,6 @@ /** * {@link org.springframework.format.support.FormattingConversionService} dedicated to web * applications for formatting and converting values to/from the web. - *

- * This service replaces the default implementations provided by - * {@link org.springframework.web.servlet.config.annotation.EnableWebMvc @EnableWebMvc} - * and {@link org.springframework.web.reactive.config.EnableWebFlux @EnableWebFlux}. * * @author Brian Clozel * @since 2.0.0 diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ProblemDetailsExceptionHandler.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ProblemDetailsExceptionHandler.java deleted file mode 100644 index d9084727b566..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ProblemDetailsExceptionHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive; - -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.reactive.result.method.annotation.ResponseEntityExceptionHandler; - -/** - * {@code @ControllerAdvice} annotated {@link ResponseEntityExceptionHandler} that is - * auto-configured for problem details support. - * - * @author Brian Clozel - */ -@ControllerAdvice -class ProblemDetailsExceptionHandler extends ResponseEntityExceptionHandler { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfiguration.java deleted file mode 100644 index cf65651fee36..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfiguration.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigureOrder; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.Ordered; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.http.ReactiveHttpInputMessage; -import org.springframework.util.ObjectUtils; -import org.springframework.web.server.adapter.ForwardedHeaderTransformer; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for a reactive web server. - * - * @author Brian Clozel - * @author Scott Frederick - * @since 2.0.0 - */ -@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) -@AutoConfiguration -@ConditionalOnClass(ReactiveHttpInputMessage.class) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@EnableConfigurationProperties(ServerProperties.class) -@Import({ ReactiveWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, - ReactiveWebServerFactoryConfiguration.EmbeddedTomcat.class, - ReactiveWebServerFactoryConfiguration.EmbeddedJetty.class, - ReactiveWebServerFactoryConfiguration.EmbeddedUndertow.class, - ReactiveWebServerFactoryConfiguration.EmbeddedNetty.class }) -public class ReactiveWebServerFactoryAutoConfiguration { - - @Bean - public ReactiveWebServerFactoryCustomizer reactiveWebServerFactoryCustomizer(ServerProperties serverProperties, - ObjectProvider sslBundles) { - return new ReactiveWebServerFactoryCustomizer(serverProperties, sslBundles.getIfAvailable()); - } - - @Bean - @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat") - public TomcatReactiveWebServerFactoryCustomizer tomcatReactiveWebServerFactoryCustomizer( - ServerProperties serverProperties) { - return new TomcatReactiveWebServerFactoryCustomizer(serverProperties); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty(name = "server.forward-headers-strategy", havingValue = "framework") - public ForwardedHeaderTransformer forwardedHeaderTransformer() { - return new ForwardedHeaderTransformer(); - } - - /** - * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via - * {@link ImportBeanDefinitionRegistrar} for early registration. - */ - public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { - - private ConfigurableListableBeanFactory beanFactory; - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - if (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) { - this.beanFactory = listableBeanFactory; - } - } - - @Override - public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, - BeanDefinitionRegistry registry) { - if (this.beanFactory == null) { - return; - } - registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor", - WebServerFactoryCustomizerBeanPostProcessor.class); - } - - private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, - Class beanClass) { - if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) { - RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass); - beanDefinition.setSynthetic(true); - registry.registerBeanDefinition(name, beanDefinition); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java deleted file mode 100644 index a71494bc0175..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive; - -import io.undertow.Undertow; -import org.eclipse.jetty.ee10.servlet.ServletHolder; -import reactor.netty.http.server.HttpServer; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigurations; -import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.netty.NettyRouteProvider; -import org.springframework.boot.web.embedded.netty.NettyServerCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.client.ReactorResourceFactory; - -/** - * Configuration classes for reactive web servers - *

- * Those should be {@code @Import} in a regular auto-configuration class to guarantee - * their order of execution. - * - * @author Brian Clozel - * @author Raheela Aslam - * @author Sergey Serdyuk - */ -abstract class ReactiveWebServerFactoryConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(ReactiveWebServerFactory.class) - @ConditionalOnClass({ HttpServer.class }) - @Import(ReactorNettyConfigurations.ReactorResourceFactoryConfiguration.class) - static class EmbeddedNetty { - - @Bean - NettyReactiveWebServerFactory nettyReactiveWebServerFactory(ReactorResourceFactory resourceFactory, - ObjectProvider routes, ObjectProvider serverCustomizers) { - NettyReactiveWebServerFactory serverFactory = new NettyReactiveWebServerFactory(); - serverFactory.setResourceFactory(resourceFactory); - routes.orderedStream().forEach(serverFactory::addRouteProviders); - serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList()); - return serverFactory; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(ReactiveWebServerFactory.class) - @ConditionalOnClass({ org.apache.catalina.startup.Tomcat.class }) - static class EmbeddedTomcat { - - @Bean - TomcatReactiveWebServerFactory tomcatReactiveWebServerFactory( - ObjectProvider connectorCustomizers, - ObjectProvider contextCustomizers, - ObjectProvider> protocolHandlerCustomizers) { - TomcatReactiveWebServerFactory factory = new TomcatReactiveWebServerFactory(); - factory.getTomcatConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList()); - factory.getTomcatContextCustomizers().addAll(contextCustomizers.orderedStream().toList()); - factory.getTomcatProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList()); - return factory; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(ReactiveWebServerFactory.class) - @ConditionalOnClass({ org.eclipse.jetty.server.Server.class, ServletHolder.class }) - static class EmbeddedJetty { - - @Bean - JettyReactiveWebServerFactory jettyReactiveWebServerFactory( - ObjectProvider serverCustomizers) { - JettyReactiveWebServerFactory serverFactory = new JettyReactiveWebServerFactory(); - serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList()); - return serverFactory; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(ReactiveWebServerFactory.class) - @ConditionalOnClass({ Undertow.class }) - static class EmbeddedUndertow { - - @Bean - UndertowReactiveWebServerFactory undertowReactiveWebServerFactory( - ObjectProvider builderCustomizers) { - UndertowReactiveWebServerFactory factory = new UndertowReactiveWebServerFactory(); - factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList()); - return factory; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/TomcatReactiveWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/TomcatReactiveWebServerFactoryCustomizer.java deleted file mode 100644 index 1d9d30c5810f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/TomcatReactiveWebServerFactoryCustomizer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive; - -import org.apache.catalina.core.AprLifecycleListener; - -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat; -import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.UseApr; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.util.Assert; - -/** - * {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} to Tomcat reactive - * web servers. - * - * @author Andy Wilkinson - * @since 2.2.0 - */ -public class TomcatReactiveWebServerFactoryCustomizer - implements WebServerFactoryCustomizer { - - private final ServerProperties serverProperties; - - public TomcatReactiveWebServerFactoryCustomizer(ServerProperties serverProperties) { - this.serverProperties = serverProperties; - } - - @Override - public void customize(TomcatReactiveWebServerFactory factory) { - Tomcat tomcatProperties = this.serverProperties.getTomcat(); - factory.setDisableMBeanRegistry(!tomcatProperties.getMbeanregistry().isEnabled()); - factory.setUseApr(getUseApr(tomcatProperties.getUseApr())); - } - - private boolean getUseApr(UseApr useApr) { - return switch (useApr) { - case ALWAYS -> { - Assert.state(isAprAvailable(), "APR has been configured to 'ALWAYS', but it's not available"); - yield true; - } - case WHEN_AVAILABLE -> isAprAvailable(); - case NEVER -> false; - }; - } - - private boolean isAprAvailable() { - // At least one instance of AprLifecycleListener has to be created for - // isAprAvailable() to work - new AprLifecycleListener(); - return AprLifecycleListener.isAprAvailable(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/package-info.java deleted file mode 100644 index 8e1fa66f76e7..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring WebFlux error handling. - */ -package org.springframework.boot.autoconfigure.web.reactive.error; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.java deleted file mode 100644 index 87663ef25c07..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive.function.client; - -import java.util.List; - -import reactor.netty.http.client.HttpClient; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorBuilderCustomizer; -import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigurations.ReactorResourceFactoryConfiguration; -import org.springframework.boot.http.client.reactive.ReactorClientHttpConnectorBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.annotation.Order; -import org.springframework.http.client.ReactorResourceFactory; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * Deprecated {@link EnableAutoConfiguration Auto-configuration} for - * {@link ReactorNettyHttpClientMapper}. - * - * @author Brian Clozel - * @author Phillip Webb - * @since 2.1.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorAutoConfiguration} - * and to align with the deprecation of {@link ReactorNettyHttpClientMapper} - */ -@AutoConfiguration -@ConditionalOnClass(WebClient.class) -@Deprecated(since = "3.5.0", forRemoval = true) -public class ClientHttpConnectorAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(HttpClient.class) - @Import(ReactorResourceFactoryConfiguration.class) - @SuppressWarnings("removal") - static class ReactorNetty { - - @Bean - @Order(0) - ClientHttpConnectorBuilderCustomizer reactorNettyHttpClientMapperClientHttpConnectorBuilderCustomizer( - ReactorResourceFactory reactorResourceFactory, - ObjectProvider mapperProvider) { - return applyMappers(mapperProvider.orderedStream().toList()); - } - - private ClientHttpConnectorBuilderCustomizer applyMappers( - List mappers) { - return (builder) -> { - for (ReactorNettyHttpClientMapper mapper : mappers) { - builder = builder.withHttpClientCustomizer(mapper::configure); - } - return builder; - }; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ReactorNettyHttpClientMapper.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ReactorNettyHttpClientMapper.java deleted file mode 100644 index 2cdb04199123..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ReactorNettyHttpClientMapper.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive.function.client; - -import java.util.Collection; - -import reactor.netty.http.client.HttpClient; - -import org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorBuilderCustomizer; -import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; -import org.springframework.http.client.reactive.ReactorClientHttpConnector; -import org.springframework.util.Assert; - -/** - * Mapper that allows for custom modification of a {@link HttpClient} before it is used as - * the basis for a {@link ReactorClientHttpConnector}. - * - * @author Brian Clozel - * @author Phillip Webb - * @since 2.3.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link ClientHttpConnectorBuilderCustomizer} or declaring a pre-configured - * {@link ClientHttpConnectorBuilder} bean - */ -@FunctionalInterface -@Deprecated(since = "3.5.0", forRemoval = true) -public interface ReactorNettyHttpClientMapper { - - /** - * Configure the given {@link HttpClient} and return the newly created instance. - * @param httpClient the client to configure - * @return the new client instance - */ - HttpClient configure(HttpClient httpClient); - - /** - * Return a new {@link ReactorNettyHttpClientMapper} composed of the given mappers. - * @param mappers the mappers to compose - * @return a composed {@link ReactorNettyHttpClientMapper} instance - * @since 3.1.1 - */ - static ReactorNettyHttpClientMapper of(Collection mappers) { - Assert.notNull(mappers, "'mappers' must not be null"); - return of(mappers.toArray(ReactorNettyHttpClientMapper[]::new)); - } - - /** - * Return a new {@link ReactorNettyHttpClientMapper} composed of the given mappers. - * @param mappers the mappers to compose - * @return a composed {@link ReactorNettyHttpClientMapper} instance - * @since 3.1.1 - */ - static ReactorNettyHttpClientMapper of(ReactorNettyHttpClientMapper... mappers) { - Assert.notNull(mappers, "'mappers' must not be null"); - return (httpClient) -> { - for (ReactorNettyHttpClientMapper mapper : mappers) { - httpClient = mapper.configure(httpClient); - } - return httpClient; - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/package-info.java deleted file mode 100644 index 0db79b1d63b6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Framework's functional web client. - */ -package org.springframework.boot.autoconfigure.web.reactive.function.client; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/package-info.java deleted file mode 100644 index a09faba055fc..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for reactive web servers and Spring WebFlux. - */ -package org.springframework.boot.autoconfigure.web.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ProblemDetailsExceptionHandler.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ProblemDetailsExceptionHandler.java deleted file mode 100644 index f4b50df055cb..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ProblemDetailsExceptionHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; - -/** - * {@code @ControllerAdvice} annotated {@link ResponseEntityExceptionHandler} that is - * auto-configured for problem details support. - * - * @author Brian Clozel - */ -@ControllerAdvice -class ProblemDetailsExceptionHandler extends ResponseEntityExceptionHandler { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfiguration.java deleted file mode 100644 index 9e91644c3433..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfiguration.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import jakarta.servlet.DispatcherType; -import jakarta.servlet.ServletRequest; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigureOrder; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor; -import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.WebListenerRegistrar; -import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.Ordered; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.ObjectUtils; -import org.springframework.web.filter.ForwardedHeaderFilter; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for servlet web servers. - * - * @author Phillip Webb - * @author Dave Syer - * @author Ivan Sopov - * @author Brian Clozel - * @author Stephane Nicoll - * @author Scott Frederick - * @since 2.0.0 - */ -@AutoConfiguration(after = SslAutoConfiguration.class) -@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) -@ConditionalOnClass(ServletRequest.class) -@ConditionalOnWebApplication(type = Type.SERVLET) -@EnableConfigurationProperties(ServerProperties.class) -@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, - ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, - ServletWebServerFactoryConfiguration.EmbeddedJetty.class, - ServletWebServerFactoryConfiguration.EmbeddedUndertow.class }) -public class ServletWebServerFactoryAutoConfiguration { - - @Bean - public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties, - ObjectProvider webListenerRegistrars, - ObjectProvider cookieSameSiteSuppliers, ObjectProvider sslBundles) { - return new ServletWebServerFactoryCustomizer(serverProperties, webListenerRegistrars.orderedStream().toList(), - cookieSameSiteSuppliers.orderedStream().toList(), sslBundles.getIfAvailable()); - } - - @Bean - @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat") - public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer( - ServerProperties serverProperties) { - return new TomcatServletWebServerFactoryCustomizer(serverProperties); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(name = "server.forward-headers-strategy", havingValue = "framework") - @ConditionalOnMissingFilterBean(ForwardedHeaderFilter.class) - static class ForwardedHeaderFilterConfiguration { - - @Bean - @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat") - ForwardedHeaderFilterCustomizer tomcatForwardedHeaderFilterCustomizer(ServerProperties serverProperties) { - return (filter) -> filter.setRelativeRedirects(serverProperties.getTomcat().isUseRelativeRedirects()); - } - - @Bean - FilterRegistrationBean forwardedHeaderFilter( - ObjectProvider customizerProvider) { - ForwardedHeaderFilter filter = new ForwardedHeaderFilter(); - customizerProvider.ifAvailable((customizer) -> customizer.customize(filter)); - FilterRegistrationBean registration = new FilterRegistrationBean<>(filter); - registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR); - registration.setOrder(Ordered.HIGHEST_PRECEDENCE); - return registration; - } - - } - - interface ForwardedHeaderFilterCustomizer { - - void customize(ForwardedHeaderFilter filter); - - } - - /** - * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via - * {@link ImportBeanDefinitionRegistrar} for early registration. - */ - public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { - - private ConfigurableListableBeanFactory beanFactory; - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - if (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) { - this.beanFactory = listableBeanFactory; - } - } - - @Override - public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, - BeanDefinitionRegistry registry) { - if (this.beanFactory == null) { - return; - } - registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor", - WebServerFactoryCustomizerBeanPostProcessor.class); - registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor", - ErrorPageRegistrarBeanPostProcessor.class); - } - - private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, - Class beanClass) { - if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) { - RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass); - beanDefinition.setSynthetic(true); - registry.registerBeanDefinition(name, beanDefinition); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java deleted file mode 100644 index e85aecfe314d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import io.undertow.Undertow; -import jakarta.servlet.Servlet; -import org.apache.catalina.startup.Tomcat; -import org.apache.coyote.UpgradeProtocol; -import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.Loader; -import org.xnio.SslClientAuthMode; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.SearchStrategy; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Configuration classes for servlet web servers - *

- * Those should be {@code @Import} in a regular auto-configuration class to guarantee - * their order of execution. - * - * @author Phillip Webb - * @author Dave Syer - * @author Ivan Sopov - * @author Brian Clozel - * @author Stephane Nicoll - * @author Raheela Asalm - * @author Sergey Serdyuk - */ -@Configuration(proxyBeanMethods = false) -class ServletWebServerFactoryConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class }) - @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT) - static class EmbeddedTomcat { - - @Bean - TomcatServletWebServerFactory tomcatServletWebServerFactory( - ObjectProvider connectorCustomizers, - ObjectProvider contextCustomizers, - ObjectProvider> protocolHandlerCustomizers) { - TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); - factory.getTomcatConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList()); - factory.getTomcatContextCustomizers().addAll(contextCustomizers.orderedStream().toList()); - factory.getTomcatProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList()); - return factory; - } - - } - - /** - * Nested configuration if Jetty is being used. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class }) - @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT) - static class EmbeddedJetty { - - @Bean - JettyServletWebServerFactory jettyServletWebServerFactory( - ObjectProvider serverCustomizers) { - JettyServletWebServerFactory factory = new JettyServletWebServerFactory(); - factory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList()); - return factory; - } - - } - - /** - * Nested configuration if Undertow is being used. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class }) - @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT) - static class EmbeddedUndertow { - - @Bean - UndertowServletWebServerFactory undertowServletWebServerFactory( - ObjectProvider deploymentInfoCustomizers, - ObjectProvider builderCustomizers) { - UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(); - factory.getDeploymentInfoCustomizers().addAll(deploymentInfoCustomizers.orderedStream().toList()); - factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList()); - return factory; - } - - @Bean - UndertowServletWebServerFactoryCustomizer undertowServletWebServerFactoryCustomizer( - ServerProperties serverProperties) { - return new UndertowServletWebServerFactoryCustomizer(serverProperties); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/TomcatServletWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/TomcatServletWebServerFactoryCustomizer.java deleted file mode 100644 index 22aedd6302a1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/TomcatServletWebServerFactoryCustomizer.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import org.apache.catalina.core.AprLifecycleListener; - -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.UseApr; -import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; - -/** - * {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} to Tomcat web - * servers. - * - * @author Brian Clozel - * @author Phillip Webb - * @since 2.0.0 - */ -public class TomcatServletWebServerFactoryCustomizer - implements WebServerFactoryCustomizer, Ordered { - - private final ServerProperties serverProperties; - - public TomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) { - this.serverProperties = serverProperties; - } - - @Override - public int getOrder() { - return 0; - } - - @Override - public void customize(TomcatServletWebServerFactory factory) { - ServerProperties.Tomcat tomcatProperties = this.serverProperties.getTomcat(); - if (!ObjectUtils.isEmpty(tomcatProperties.getAdditionalTldSkipPatterns())) { - factory.getTldSkipPatterns().addAll(tomcatProperties.getAdditionalTldSkipPatterns()); - } - if (tomcatProperties.getRedirectContextRoot() != null) { - customizeRedirectContextRoot(factory, tomcatProperties.getRedirectContextRoot()); - } - customizeUseRelativeRedirects(factory, tomcatProperties.isUseRelativeRedirects()); - factory.setDisableMBeanRegistry(!tomcatProperties.getMbeanregistry().isEnabled()); - factory.setUseApr(getUseApr(tomcatProperties.getUseApr())); - } - - private void customizeRedirectContextRoot(ConfigurableTomcatWebServerFactory factory, boolean redirectContextRoot) { - factory.addContextCustomizers((context) -> context.setMapperContextRootRedirectEnabled(redirectContextRoot)); - } - - private void customizeUseRelativeRedirects(ConfigurableTomcatWebServerFactory factory, - boolean useRelativeRedirects) { - factory.addContextCustomizers((context) -> context.setUseRelativeRedirects(useRelativeRedirects)); - } - - private boolean getUseApr(UseApr useApr) { - return switch (useApr) { - case ALWAYS -> { - Assert.state(isAprAvailable(), "APR has been configured to 'ALWAYS', but it's not available"); - yield true; - } - case WHEN_AVAILABLE -> isAprAvailable(); - case NEVER -> false; - }; - } - - private boolean isAprAvailable() { - // At least one instance of AprLifecycleListener has to be created for - // isAprAvailable() to work - new AprLifecycleListener(); - return AprLifecycleListener.isAprAvailable(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/UndertowServletWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/UndertowServletWebServerFactoryCustomizer.java deleted file mode 100644 index a53702814a11..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/UndertowServletWebServerFactoryCustomizer.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; - -/** - * {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} to Undertow - * Servlet web servers. - * - * @author Andy Wilkinson - * @since 2.1.7 - */ -public class UndertowServletWebServerFactoryCustomizer - implements WebServerFactoryCustomizer { - - private final ServerProperties serverProperties; - - public UndertowServletWebServerFactoryCustomizer(ServerProperties serverProperties) { - this.serverProperties = serverProperties; - } - - @Override - public void customize(UndertowServletWebServerFactory factory) { - factory.setEagerFilterInit(this.serverProperties.getUndertow().isEagerFilterInit()); - factory.setPreservePathOnForward(this.serverProperties.getUndertow().isPreservePathOnForward()); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/package-info.java deleted file mode 100644 index 7cb8b6a9b55d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring MVC error handling. - */ -package org.springframework.boot.autoconfigure.web.servlet.error; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/package-info.java deleted file mode 100644 index 17f6102a429f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for servlet web servers and Spring MVC. - */ -package org.springframework.boot.autoconfigure.web.servlet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/client/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/client/package-info.java deleted file mode 100644 index ea002ccffa62..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Web Services Clients. - */ -package org.springframework.boot.autoconfigure.webservices.client; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/package-info.java deleted file mode 100644 index 2b6728fcdcae..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Spring Web Services. - */ -package org.springframework.boot.autoconfigure.webservices; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/JettyWebSocketReactiveWebServerCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/JettyWebSocketReactiveWebServerCustomizer.java deleted file mode 100644 index af90dc20a6d6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/JettyWebSocketReactiveWebServerCustomizer.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.reactive; - -import jakarta.servlet.ServletContext; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.websocket.jakarta.server.JakartaWebSocketServerContainer; -import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer; -import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.websocket.core.server.WebSocketMappings; -import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents; - -import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; - -/** - * WebSocket customizer for {@link JettyReactiveWebServerFactory}. - * - * @author Andy Wilkinson - * @since 3.0.8 - */ -public class JettyWebSocketReactiveWebServerCustomizer - implements WebServerFactoryCustomizer, Ordered { - - @Override - public void customize(JettyReactiveWebServerFactory factory) { - factory.addServerCustomizers((server) -> { - ServletContextHandler servletContextHandler = findServletContextHandler(server); - if (servletContextHandler != null) { - ServletContext servletContext = servletContextHandler.getServletContext(); - if (JettyWebSocketServerContainer.getContainer(servletContext) == null) { - WebSocketServerComponents.ensureWebSocketComponents(server, servletContextHandler); - JettyWebSocketServerContainer.ensureContainer(servletContext); - } - if (JakartaWebSocketServerContainer.getContainer(servletContext) == null) { - WebSocketServerComponents.ensureWebSocketComponents(server, servletContextHandler); - WebSocketUpgradeFilter.ensureFilter(servletContext); - WebSocketMappings.ensureMappings(servletContextHandler); - JakartaWebSocketServerContainer.ensureContainer(servletContext); - } - } - }); - } - - private ServletContextHandler findServletContextHandler(Handler handler) { - if (handler instanceof ServletContextHandler servletContextHandler) { - return servletContextHandler; - } - if (handler instanceof Handler.Wrapper handlerWrapper) { - return findServletContextHandler(handlerWrapper.getHandler()); - } - if (handler instanceof Handler.Collection handlerCollection) { - for (Handler contained : handlerCollection.getHandlers()) { - ServletContextHandler servletContextHandler = findServletContextHandler(contained); - if (servletContextHandler != null) { - return servletContextHandler; - } - } - } - return null; - } - - @Override - public int getOrder() { - return 0; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/TomcatWebSocketReactiveWebServerCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/TomcatWebSocketReactiveWebServerCustomizer.java deleted file mode 100644 index f085c72a8c0c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/TomcatWebSocketReactiveWebServerCustomizer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.reactive; - -import org.apache.tomcat.websocket.server.WsSci; - -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; - -/** - * WebSocket customizer for {@link TomcatReactiveWebServerFactory}. - * - * @author Brian Clozel - * @since 2.0.0 - */ -public class TomcatWebSocketReactiveWebServerCustomizer - implements WebServerFactoryCustomizer, Ordered { - - @Override - public void customize(TomcatReactiveWebServerFactory factory) { - factory.addContextCustomizers((context) -> context.addServletContainerInitializer(new WsSci(), null)); - } - - @Override - public int getOrder() { - return 0; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/WebSocketReactiveAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/WebSocketReactiveAutoConfiguration.java deleted file mode 100644 index d64171a5e78b..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/WebSocketReactiveAutoConfiguration.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.reactive; - -import jakarta.servlet.Servlet; -import jakarta.websocket.server.ServerContainer; -import org.apache.catalina.startup.Tomcat; -import org.apache.tomcat.websocket.server.WsSci; -import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Auto-configuration for WebSocket reactive server in Tomcat, Jetty or Undertow. Requires - * the appropriate WebSocket modules to be on the classpath. - *

- * If Tomcat's WebSocket support is detected on the classpath we add a customizer that - * installs the Tomcat WebSocket initializer. - * - * @author Brian Clozel - * @since 2.0.0 - */ -@AutoConfiguration(before = ReactiveWebServerFactoryAutoConfiguration.class) -@ConditionalOnClass({ Servlet.class, ServerContainer.class }) -@ConditionalOnWebApplication(type = Type.REACTIVE) -public class WebSocketReactiveAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ Tomcat.class, WsSci.class }) - static class TomcatWebSocketConfiguration { - - @Bean - @ConditionalOnMissingBean(name = "websocketReactiveWebServerCustomizer") - TomcatWebSocketReactiveWebServerCustomizer websocketReactiveWebServerCustomizer() { - return new TomcatWebSocketReactiveWebServerCustomizer(); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(JakartaWebSocketServletContainerInitializer.class) - static class JettyWebSocketConfiguration { - - @Bean - @ConditionalOnMissingBean(name = "websocketReactiveWebServerCustomizer") - JettyWebSocketReactiveWebServerCustomizer websocketServletWebServerCustomizer() { - return new JettyWebSocketReactiveWebServerCustomizer(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/package-info.java deleted file mode 100644 index d37852807173..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for WebSocket support in reactive web servers. - */ -package org.springframework.boot.autoconfigure.websocket.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/JettyWebSocketServletWebServerCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/JettyWebSocketServletWebServerCustomizer.java deleted file mode 100644 index 9e97e2da910e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/JettyWebSocketServletWebServerCustomizer.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.servlet; - -import org.eclipse.jetty.ee10.webapp.AbstractConfiguration; -import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.eclipse.jetty.ee10.websocket.jakarta.server.JakartaWebSocketServerContainer; -import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer; -import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter; -import org.eclipse.jetty.websocket.core.server.WebSocketMappings; -import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents; - -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; - -/** - * WebSocket customizer for {@link JettyServletWebServerFactory}. - * - * @author Dave Syer - * @author Phillip Webb - * @author Andy Wilkinson - * @since 2.0.0 - */ -public class JettyWebSocketServletWebServerCustomizer - implements WebServerFactoryCustomizer, Ordered { - - @Override - public void customize(JettyServletWebServerFactory factory) { - factory.addConfigurations(new AbstractConfiguration(new AbstractConfiguration.Builder()) { - - @Override - public void configure(WebAppContext context) throws Exception { - if (JettyWebSocketServerContainer.getContainer(context.getServletContext()) == null) { - WebSocketServerComponents.ensureWebSocketComponents(context.getServer(), - context.getContext().getContextHandler()); - JettyWebSocketServerContainer.ensureContainer(context.getServletContext()); - } - if (JakartaWebSocketServerContainer.getContainer(context.getServletContext()) == null) { - WebSocketServerComponents.ensureWebSocketComponents(context.getServer(), - context.getContext().getContextHandler()); - WebSocketUpgradeFilter.ensureFilter(context.getServletContext()); - WebSocketMappings.ensureMappings(context.getContext().getContextHandler()); - JakartaWebSocketServerContainer.ensureContainer(context.getServletContext()); - } - } - - }); - } - - @Override - public int getOrder() { - return 0; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/TomcatWebSocketServletWebServerCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/TomcatWebSocketServletWebServerCustomizer.java deleted file mode 100644 index 8e4608ca5d3f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/TomcatWebSocketServletWebServerCustomizer.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.servlet; - -import org.apache.tomcat.websocket.server.WsSci; - -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; - -/** - * WebSocket customizer for {@link TomcatServletWebServerFactory}. - * - * @author Dave Syer - * @author Phillip Webb - * @author Andy Wilkinson - * @since 2.0.0 - */ -public class TomcatWebSocketServletWebServerCustomizer - implements WebServerFactoryCustomizer, Ordered { - - @Override - public void customize(TomcatServletWebServerFactory factory) { - factory.addContextCustomizers((context) -> context.addServletContainerInitializer(new WsSci(), null)); - } - - @Override - public int getOrder() { - return 0; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/UndertowWebSocketServletWebServerCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/UndertowWebSocketServletWebServerCustomizer.java deleted file mode 100644 index 289546dc8b0b..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/UndertowWebSocketServletWebServerCustomizer.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.servlet; - -import io.undertow.servlet.api.DeploymentInfo; -import io.undertow.websockets.jsr.WebSocketDeploymentInfo; - -import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.core.Ordered; - -/** - * WebSocket customizer for {@link UndertowServletWebServerFactory}. - * - * @author Phillip Webb - * @since 2.0.0 - */ -public class UndertowWebSocketServletWebServerCustomizer - implements WebServerFactoryCustomizer, Ordered { - - @Override - public void customize(UndertowServletWebServerFactory factory) { - WebsocketDeploymentInfoCustomizer customizer = new WebsocketDeploymentInfoCustomizer(); - factory.addDeploymentInfoCustomizers(customizer); - } - - @Override - public int getOrder() { - return 0; - } - - private static final class WebsocketDeploymentInfoCustomizer implements UndertowDeploymentInfoCustomizer { - - @Override - public void customize(DeploymentInfo deploymentInfo) { - WebSocketDeploymentInfo info = new WebSocketDeploymentInfo(); - deploymentInfo.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, info); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration.java deleted file mode 100644 index e14d4ad1072e..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.servlet; - -import java.util.EnumSet; - -import jakarta.servlet.DispatcherType; -import jakarta.servlet.FilterRegistration.Dynamic; -import jakarta.servlet.Servlet; -import jakarta.websocket.server.ServerContainer; -import org.apache.catalina.startup.Tomcat; -import org.apache.tomcat.websocket.server.WsSci; -import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer; -import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; - -/** - * Auto configuration for WebSocket servlet server in embedded Tomcat, Jetty or Undertow. - * Requires the appropriate WebSocket modules to be on the classpath. - *

- * If Tomcat's WebSocket support is detected on the classpath we add a customizer that - * installs the Tomcat WebSocket initializer. In a non-embedded server it should already - * be there. - *

- * If Jetty's WebSocket support is detected on the classpath we add a configuration that - * configures the context with WebSocket support. In a non-embedded server it should - * already be there. - *

- * If Undertow's WebSocket support is detected on the classpath we add a customizer that - * installs the Undertow WebSocket DeploymentInfo Customizer. In a non-embedded server it - * should already be there. - * - * @author Dave Syer - * @author Phillip Webb - * @author Andy Wilkinson - * @since 1.0.0 - */ -@AutoConfiguration(before = ServletWebServerFactoryAutoConfiguration.class) -@ConditionalOnClass({ Servlet.class, ServerContainer.class }) -@ConditionalOnWebApplication(type = Type.SERVLET) -public class WebSocketServletAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ Tomcat.class, WsSci.class }) - static class TomcatWebSocketConfiguration { - - @Bean - @ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer") - TomcatWebSocketServletWebServerCustomizer websocketServletWebServerCustomizer() { - return new TomcatWebSocketServletWebServerCustomizer(); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(JakartaWebSocketServletContainerInitializer.class) - static class JettyWebSocketConfiguration { - - @Bean - @ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer") - JettyWebSocketServletWebServerCustomizer websocketServletWebServerCustomizer() { - return new JettyWebSocketServletWebServerCustomizer(); - } - - @Bean - @ConditionalOnNotWarDeployment - @Order(Ordered.LOWEST_PRECEDENCE) - @ConditionalOnMissingBean(name = "websocketUpgradeFilterWebServerCustomizer") - WebServerFactoryCustomizer websocketUpgradeFilterWebServerCustomizer() { - return (factory) -> { - factory.addInitializers((servletContext) -> { - Dynamic registration = servletContext.addFilter(WebSocketUpgradeFilter.class.getName(), - new WebSocketUpgradeFilter()); - registration.setAsyncSupported(true); - registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*"); - }); - }; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(io.undertow.websockets.jsr.Bootstrap.class) - static class UndertowWebSocketConfiguration { - - @Bean - @ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer") - UndertowWebSocketServletWebServerCustomizer websocketServletWebServerCustomizer() { - return new UndertowWebSocketServletWebServerCustomizer(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/package-info.java deleted file mode 100644 index 497bf89b3287..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for WebSocket support in servlet web servers. - */ -package org.springframework.boot.autoconfigure.websocket.servlet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 4359aaa9caab..1ebc87bf4e87 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -2,3004 +2,274 @@ "groups": [], "properties": [ { - "name": "server.connection-timeout", - "type": "java.time.Duration", - "deprecation": { - "reason": "Each server behaves differently. Use server specific properties instead.", - "level": "error" - } + "name": "spring.aop.auto", + "type": "java.lang.Boolean", + "description": "Add @EnableAspectJAutoProxy.", + "defaultValue": true }, { - "name": "server.jetty.accesslog.date-format", - "deprecation": { - "replacement": "server.jetty.accesslog.custom-format", - "level": "error" - } + "name": "spring.aop.proxy-target-class", + "type": "java.lang.Boolean", + "description": "Whether subclass-based (CGLIB) proxies are to be created (true), as opposed to standard Java interface-based proxies (false).", + "defaultValue": true }, { - "name": "server.jetty.accesslog.extended-format", - "deprecation": { - "replacement": "server.jetty.accesslog.format", - "level": "error" - } + "name": "spring.application.admin.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable admin features for the application.", + "defaultValue": false }, { - "name": "server.jetty.accesslog.locale", - "deprecation": { - "replacement": "server.jetty.accesslog.custom-format", - "level": "error" - } + "name": "spring.application.admin.jmx-name", + "type": "java.lang.String", + "description": "JMX name of the application admin MBean.", + "defaultValue": "org.springframework.boot:type=Admin,name=SpringApplication" }, { - "name": "server.jetty.accesslog.log-cookies", - "deprecation": { - "replacement": "server.jetty.accesslog.custom-format", - "level": "error" - } + "name": "spring.autoconfigure.exclude", + "type": "java.util.List", + "description": "Auto-configuration classes to exclude." }, { - "name": "server.jetty.accesslog.log-latency", + "name": "spring.git.properties", + "type": "java.lang.String", + "description": "Resource reference to a generated git info properties file.", "deprecation": { - "replacement": "server.jetty.accesslog.custom-format", + "replacement": "spring.info.git.location", "level": "error" } }, { - "name": "server.jetty.accesslog.log-server", - "deprecation": { - "replacement": "server.jetty.accesslog.custom-format", - "level": "error" - } + "name": "spring.info.build.location", + "defaultValue": "classpath:META-INF/build-info.properties" }, { - "name": "server.jetty.accesslog.time-zone", - "deprecation": { - "replacement": "server.jetty.accesslog.custom-format", - "level": "error" - } + "name": "spring.info.git.location", + "defaultValue": "classpath:git.properties" }, { - "name": "server.jetty.max-http-post-size", - "type": "org.springframework.util.unit.DataSize", - "deprecation": { - "replacement": "server.jetty.max-http-form-post-size", - "level": "error" - } + "name": "spring.messages.basename", + "defaultValue": [ + "messages" + ] }, - { - "name": "server.max-http-header-size", + { + "name": "spring.resources.add-mappings", + "type": "java.lang.Boolean", "deprecation": { - "replacement": "server.max-http-request-header-size", + "replacement": "spring.web.resources.add-mappings", "level": "error" } }, { - "name": "server.max-http-post-size", - "type": "java.lang.Integer", - "description": "Maximum size in bytes of the HTTP post content.", - "defaultValue": 0, + "name": "spring.resources.cache.cachecontrol.cache-private", + "type": "java.lang.Boolean", "deprecation": { - "reason": "Use dedicated property for each container.", + "replacement": "spring.web.resources.cache.cachecontrol.cache-private", "level": "error" } }, { - "name": "server.netty.max-chunk-size", + "name": "spring.resources.cache.cachecontrol.cache-public", + "type": "java.lang.Boolean", "deprecation": { - "reason": "Deprecated for removal in Reactor Netty.", + "replacement": "spring.web.resources.cache.cachecontrol.cache-public", "level": "error" } }, { - "name": "server.port", - "defaultValue": 8080 - }, - { - "name": "server.reactive.session.cookie.domain", - "description": "Domain for the cookie." - }, - { - "name": "server.reactive.session.cookie.http-only", - "description": "Whether to use \"HttpOnly\" cookies for the cookie." - }, - { - "name": "server.reactive.session.cookie.max-age", - "description": "Maximum age of the cookie. If a duration suffix is not specified, seconds will be used. A positive value indicates when the cookie expires relative to the current time. A value of 0 means the cookie should expire immediately. A negative value means no \"Max-Age\"." - }, - { - "name": "server.reactive.session.cookie.name", - "description": "Name for the cookie." - }, - { - "name": "server.reactive.session.cookie.partitioned", - "description": "Whether the generated cookie carries the Partitioned attribute." - }, - { - "name": "server.reactive.session.cookie.path", - "description": "Path of the cookie." - }, - { - "name": "server.reactive.session.cookie.same-site", - "description": "SameSite setting for the cookie." - }, - { - "name": "server.reactive.session.cookie.secure", - "description": "Whether to always mark the cookie as secure." - }, - { - "name": "server.servlet.encoding.charset", - "type": "java.nio.charset.Charset", - "description": "Charset of HTTP requests and responses. Added to the Content-Type header if not set explicitly.", + "name": "spring.resources.cache.cachecontrol.max-age", + "type": "java.time.Duration", "deprecation": { - "replacement": "spring.servlet.encoding.charset", + "replacement": "spring.web.resources.cache.cachecontrol.max-age", "level": "error" } }, { - "name": "server.servlet.encoding.enabled", + "name": "spring.resources.cache.cachecontrol.must-revalidate", "type": "java.lang.Boolean", - "description": "Whether to enable http encoding support.", - "defaultValue": true, "deprecation": { - "replacement": "spring.servlet.encoding.enabled", + "replacement": "spring.web.resources.cache.cachecontrol.must-revalidate", "level": "error" } }, { - "name": "server.servlet.encoding.force", + "name": "spring.resources.cache.cachecontrol.no-cache", "type": "java.lang.Boolean", - "description": "Whether to force the encoding to the configured charset on HTTP requests and responses.", - "defaultValue": false, "deprecation": { - "replacement": "spring.servlet.encoding.force", + "replacement": "spring.web.resources.cache.cachecontrol.no-cache", "level": "error" } }, { - "name": "server.servlet.encoding.force-request", + "name": "spring.resources.cache.cachecontrol.no-store", "type": "java.lang.Boolean", - "description": "Whether to force the encoding to the configured charset on HTTP requests. Defaults to true when force has not been specified.", - "defaultValue": true, "deprecation": { - "replacement": "spring.servlet.encoding.force-request", + "replacement": "spring.web.resources.cache.cachecontrol.no-store", "level": "error" } }, { - "name": "server.servlet.encoding.force-response", + "name": "spring.resources.cache.cachecontrol.no-transform", "type": "java.lang.Boolean", - "description": "Whether to force the encoding to the configured charset on HTTP responses.", - "defaultValue": false, "deprecation": { - "replacement": "spring.servlet.encoding.force-response", + "replacement": "spring.web.resources.cache.cachecontrol.no-transform", "level": "error" } }, { - "name": "server.servlet.jsp.class-name", - "description": "Class name of the servlet to use for JSPs. If registered is true and this class\n\t * is on the classpath then it will be registered.", - "defaultValue": "org.apache.jasper.servlet.JspServlet" - }, - { - "name": "server.servlet.jsp.init-parameters", - "description": "Init parameters used to configure the JSP servlet." - }, - { - "name": "server.servlet.path", - "type": "java.lang.String", - "description": "Path of the main dispatcher servlet.", - "defaultValue": "/", + "name": "spring.resources.cache.cachecontrol.proxy-revalidate", + "type": "java.lang.Boolean", "deprecation": { - "replacement": "spring.mvc.servlet.path", + "replacement": "spring.web.resources.cache.cachecontrol.proxy-revalidate", "level": "error" } }, { - "name": "server.servlet.session.cookie.comment", - "description": "Comment for the cookie.", + "name": "spring.resources.cache.cachecontrol.s-max-age", + "type": "java.time.Duration", "deprecation": { + "replacement": "spring.web.resources.cache.cachecontrol.s-max-age", "level": "error" } }, { - "name": "server.tomcat.max-http-post-size", - "type": "org.springframework.util.unit.DataSize", + "name": "spring.resources.cache.cachecontrol.stale-if-error", + "type": "java.time.Duration", "deprecation": { - "replacement": "server.tomcat.max-http-form-post-size", + "replacement": "spring.web.resources.cache.cachecontrol.stale-if-error", "level": "error" } }, { - "name": "server.tomcat.reject-illegal-header", + "name": "spring.resources.cache.cachecontrol.stale-while-revalidate", + "type": "java.time.Duration", "deprecation": { + "replacement": "spring.web.resources.cache.cachecontrol.stale-while-revalidate", "level": "error" } }, { - "name": "server.undertow.buffers-per-region", - "type": "java.lang.Integer", - "description": "Number of buffer per region.", + "name": "spring.resources.cache.period", + "type": "java.time.Duration", "deprecation": { + "replacement": "spring.web.resources.cache.period", "level": "error" } }, { - "name": "server.use-forward-headers", + "name": "spring.resources.cache.use-last-modified", "type": "java.lang.Boolean", "deprecation": { - "reason": "Replaced to support additional strategies.", - "replacement": "server.forward-headers-strategy", + "replacement": "spring.web.resources.cache.use-last-modified", "level": "error" } }, { - "name": "spring.activemq.pool.create-connection-on-startup", + "name": "spring.resources.chain.cache", "type": "java.lang.Boolean", - "description": "Whether to create a connection on startup. Can be used to warm up the pool on startup.", - "defaultValue": true, - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.activemq.pool.expiry-timeout", - "type": "java.time.Duration", - "description": "Connection expiration timeout.", - "defaultValue": "0ms", "deprecation": { + "replacement": "spring.web.resources.chain.cache", "level": "error" } }, { - "name": "spring.activemq.pool.maximum-active-session-per-connection", - "deprecation": { - "replacement": "spring.activemq.pool.max-sessions-per-connection" - } - }, - { - "name": "spring.activemq.pool.reconnect-on-exception", + "name": "spring.resources.chain.compressed", "type": "java.lang.Boolean", - "description": "Reset the connection when a \"JMSException\" occurs.", - "defaultValue": true, "deprecation": { + "replacement": "spring.web.resources.chain.compressed", "level": "error" } }, { - "name": "spring.aop.auto", - "type": "java.lang.Boolean", - "description": "Add @EnableAspectJAutoProxy.", - "defaultValue": true - }, - { - "name": "spring.aop.proxy-target-class", - "type": "java.lang.Boolean", - "description": "Whether subclass-based (CGLIB) proxies are to be created (true), as opposed to standard Java interface-based proxies (false).", - "defaultValue": true - }, - { - "name": "spring.application.admin.enabled", + "name": "spring.resources.chain.enabled", "type": "java.lang.Boolean", - "description": "Whether to enable admin features for the application.", - "defaultValue": false - }, - { - "name": "spring.application.admin.jmx-name", - "type": "java.lang.String", - "description": "JMX name of the application admin MBean.", - "defaultValue": "org.springframework.boot:type=Admin,name=SpringApplication" - }, - { - "name": "spring.artemis.broker-url", - "defaultValue": "tcp://localhost:61616" - }, - { - "name": "spring.artemis.host", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.artemis.broker-url", - "level": "error" - } - }, - { - "name": "spring.artemis.pool.maximum-active-session-per-connection", - "deprecation": { - "replacement": "spring.artemis.pool.max-sessions-per-connection" - } - }, - { - "name": "spring.artemis.port", - "type": "java.lang.Integer", "deprecation": { - "replacement": "spring.artemis.broker-url", + "replacement": "spring.web.resources.chain.enabled", "level": "error" } }, { - "name": "spring.autoconfigure.exclude", - "type": "java.util.List", - "description": "Auto-configuration classes to exclude." - }, - { - "name": "spring.batch.initialize-schema", - "type": "org.springframework.boot.sql.init.DatabaseInitializationMode", + "name": "spring.resources.chain.gzipped", + "type": "java.lang.Boolean", "deprecation": { - "replacement": "spring.batch.jdbc.initialize-schema", + "replacement": "spring.web.resources.chain.compressed", "level": "error" } }, { - "name": "spring.batch.initializer.enabled", + "name": "spring.resources.chain.html-application-cache", "type": "java.lang.Boolean", - "description": "Create the required batch tables on startup if necessary. Enabled automatically\n if no custom table prefix is set or if a custom schema is configured.", "deprecation": { - "replacement": "spring.batch.jdbc.initialize-schema", "level": "error" } }, { - "name": "spring.batch.job.enabled", + "name": "spring.resources.chain.strategy.content.enabled", "type": "java.lang.Boolean", - "description": "Execute all Spring Batch jobs in the context on startup.", - "defaultValue": true - }, - { - "name": "spring.batch.schema", - "type": "java.lang.String", "deprecation": { - "replacement": "spring.batch.jdbc.schema", + "replacement": "spring.web.resources.chain.strategy.content.enabled", "level": "error" } }, { - "name": "spring.batch.table-prefix", - "type": "java.lang.String", + "name": "spring.resources.chain.strategy.content.paths", + "type": "java.lang.String[]", "deprecation": { - "replacement": "spring.batch.jdbc.table-prefix", + "replacement": "spring.web.resources.chain.strategy.content.paths", "level": "error" } }, { - "name": "spring.cassandra.compression", - "defaultValue": "none" - }, - { - "name": "spring.cassandra.connection.connect-timeout", - "defaultValue": "5s" - }, - { - "name": "spring.cassandra.connection.init-query-timeout", - "defaultValue": "5s" - }, - { - "name": "spring.cassandra.contact-points", - "defaultValue": [ - "127.0.0.1:9042" - ] - }, - { - "name": "spring.cassandra.controlconnection.timeout", - "defaultValue": "5s" - }, - { - "name": "spring.cassandra.pool.heartbeat-interval", - "defaultValue": "30s" - }, - { - "name": "spring.cassandra.pool.idle-timeout", - "defaultValue": "5s" - }, - { - "name": "spring.cassandra.request.page-size", - "defaultValue": 5000 - }, - { - "name": "spring.cassandra.request.throttler.type", - "defaultValue": "none" - }, - { - "name": "spring.cassandra.request.timeout", - "defaultValue": "2s" - }, - { - "name": "spring.cassandra.ssl", + "name": "spring.resources.chain.strategy.fixed.enabled", "type": "java.lang.Boolean", "deprecation": { - "replacement": "spring.cassandra.ssl.enabled", - "level": "error" - } - }, - { - "name": "spring.couchbase.bootstrap-hosts", - "type": "java.util.List", - "description": "Couchbase nodes (host or IP address) to bootstrap from.", - "deprecation": { - "replacement": "spring.couchbase.connection-string", + "replacement": "spring.web.resources.chain.strategy.fixed.enabled", "level": "error" } }, { - "name": "spring.couchbase.bucket.name", - "type": "java.lang.String", - "description": "Name of the bucket to connect to.", + "name": "spring.resources.chain.strategy.fixed.paths", + "type": "java.lang.String[]", "deprecation": { - "reason": "A bucket is no longer auto-configured.", + "replacement": "spring.web.resources.chain.strategy.fixed.paths", "level": "error" } }, { - "name": "spring.couchbase.bucket.password", + "name": "spring.resources.chain.strategy.fixed.version", "type": "java.lang.String", - "description": "Password of the bucket.", - "deprecation": { - "reason": "A bucket is no longer auto-configured.", - "level": "error" - } - }, - { - "name": "spring.couchbase.env.bootstrap.http-direct-port", - "type": "java.lang.Integer", - "description": "Port for the HTTP bootstrap.", "deprecation": { + "replacement": "spring.web.resources.chain.strategy.fixed.version", "level": "error" } }, { - "name": "spring.couchbase.env.bootstrap.http-ssl-port", - "type": "java.lang.Integer", - "description": "Port for the HTTPS bootstrap.", + "name": "spring.resources.static-locations", + "type": "java.lang.String[]", "deprecation": { + "replacement": "spring.web.resources.static-locations", "level": "error" } }, { - "name": "spring.couchbase.env.endpoints.key-value", - "type": "java.lang.Integer", - "description": "Number of sockets per node against the key/value service.", - "deprecation": { - "level": "error" - } - }, + "name": "spring.threads.virtual.enabled", + "type": "java.lang.Boolean", + "description": "Whether to use virtual threads.", + "defaultValue": false + } + ], + "hints": [ { - "name": "spring.couchbase.env.endpoints.query", - "type": "java.lang.Integer", - "description": "Number of sockets per node against the query (N1QL) service.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.couchbase.env.endpoints.queryservice.max-endpoints", - "type": "java.lang.Integer", - "description": "Maximum number of sockets per node.", - "deprecation": { - "replacement": "spring.couchbase.env.io.max-endpoints", - "level": "error" - } - }, - { - "name": "spring.couchbase.env.endpoints.queryservice.min-endpoints", - "type": "java.lang.Integer", - "description": "Minimum number of sockets per node.", - "deprecation": { - "replacement": "spring.couchbase.env.io.min-endpoints", - "level": "error" - } - }, - { - "name": "spring.couchbase.env.endpoints.view", - "type": "java.lang.Integer", - "description": "Number of sockets per node against the view service.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.couchbase.env.endpoints.viewservice.max-endpoints", - "type": "java.lang.Integer", - "description": "Maximum number of sockets per node.", - "deprecation": { - "replacement": "spring.couchbase.env.io.max-endpoints", - "level": "error" - } - }, - { - "name": "spring.couchbase.env.endpoints.viewservice.min-endpoints", - "type": "java.lang.Integer", - "description": "Minimum number of sockets per node.", - "deprecation": { - "replacement": "spring.couchbase.env.io.min-endpoints", - "level": "error" - } - }, - { - "name": "spring.couchbase.env.ssl.key-store", - "type": "java.lang.String", - "description": "Path to the JVM key store that holds the certificates.", - "deprecation": { - "replacement": "spring.couchbase.env.ssl.bundle", - "level": "error", - "since": "3.1.0" - } - }, - { - "name": "spring.couchbase.env.ssl.key-store-password", - "type": "java.lang.String", - "description": "Password used to access the key store.", - "deprecation": { - "replacement": "spring.couchbase.env.ssl.bundle", - "level": "error", - "since": "3.1.0" - } - }, - { - "name": "spring.couchbase.env.timeouts.socket-connect", - "type": "java.time.Duration", - "description": "Socket connect connections timeout.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.dao.exceptiontranslation.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable the PersistenceExceptionTranslationPostProcessor.", - "defaultValue": true - }, - { - "name": "spring.data.cassandra.compression", - "defaultValue": "none", - "deprecation": { - "replacement": "spring.cassandra.compression", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.config", - "type": "org.springframework.core.io.Resource", - "deprecation": { - "replacement": "spring.cassandra.config", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.connection.connect-timeout", - "defaultValue": "5s", - "deprecation": { - "replacement": "spring.cassandra.connection.connect-timeout", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.connection.init-query-timeout", - "defaultValue": "5s", - "deprecation": { - "replacement": "spring.cassandra.connection.init-query-timeout", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.contact-points", - "defaultValue": [ - "127.0.0.1:9042" - ], - "deprecation": { - "replacement": "spring.cassandra.contact-points", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.controlconnection.timeout", - "defaultValue": "5s", - "deprecation": { - "replacement": "spring.cassandra.controlconnection.timeout", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.jmx-enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable JMX reporting. Default to false as Cassandra JMX reporting is not compatible with Dropwizard Metrics.", - "deprecation": { - "reason": "Cassandra no longer provides JMX metrics.", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.keyspace-name", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.cassandra.keyspace-name", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.load-balancing-policy", - "type": "java.lang.Class", - "description": "Class name of the load balancing policy. The class must have a default constructor.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.data.cassandra.local-datacenter", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.cassandra.local-datacenter", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.password", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.cassandra.password", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.pool.heartbeat-interval", - "defaultValue": "30s", - "deprecation": { - "replacement": "spring.cassandra.pool.heartbeat-interval", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.pool.idle-timeout", - "defaultValue": "5s", - "deprecation": { - "replacement": "spring.cassandra.pool.idle-timeout", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.pool.max-queue-size", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.cassandra.request.throttler.max-queue-size", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.pool.pool-timeout", - "type": "java.time.Duration", - "description": "Pool timeout when trying to acquire a connection from a host's pool.", - "deprecation": { - "reason": "No longer available.", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.port", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.cassandra.port", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.reconnection-policy", - "type": "java.lang.Class", - "description": "Class name of the reconnection policy. The class must have a default constructor.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.data.cassandra.repositories.type", - "type": "org.springframework.boot.autoconfigure.data.RepositoryType", - "description": "Type of Cassandra repositories to enable.", - "defaultValue": "auto" - }, - { - "name": "spring.data.cassandra.request.consistency", - "type": "com.datastax.oss.driver.api.core.DefaultConsistencyLevel", - "deprecation": { - "replacement": "spring.cassandra.request.consistency", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.request.page-size", - "defaultValue": 5000, - "deprecation": { - "replacement": "spring.cassandra.request.page-size", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.request.serial-consistency", - "type": "com.datastax.oss.driver.api.core.DefaultConsistencyLevel", - "deprecation": { - "replacement": "spring.cassandra.request.serial-consistency", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.request.throttler.drain-interval", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.cassandra.request.throttler.drain-interval", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.request.throttler.max-concurrent-requests", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.cassandra.request.throttler.max-concurrent-requests", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.request.throttler.max-queue-size", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.cassandra.request.throttler.max-queue-size", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.request.throttler.max-requests-per-second", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.cassandra.request.throttler.max-requests-per-second", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.request.throttler.type", - "defaultValue": "none", - "deprecation": { - "replacement": "spring.cassandra.request.throttler.type", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.request.timeout", - "defaultValue": "2s", - "deprecation": { - "replacement": "spring.cassandra.request.timeout", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.retry-policy", - "type": "java.lang.Class", - "description": "Class name of the retry policy. The class must have a default constructor.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.data.cassandra.schema-action", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.cassandra.schema-action", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.session-name", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.cassandra.session-name", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.ssl", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.cassandra.ssl.enabled", - "level": "error" - } - }, - { - "name": "spring.data.cassandra.username", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.cassandra.username", - "level": "error" - } - }, - { - "name": "spring.data.couchbase.consistency", - "type": "org.springframework.data.couchbase.core.query.Consistency", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.data.couchbase.repositories.type", - "type": "org.springframework.boot.autoconfigure.data.RepositoryType", - "description": "Type of Couchbase repositories to enable.", - "defaultValue": "auto" - }, - { - "name": "spring.data.elasticsearch.cluster-name", - "type": "java.lang.String", - "description": "Elasticsearch cluster name.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.data.elasticsearch.cluster-nodes", - "type": "java.lang.String", - "description": "Comma-separated list of cluster node addresses.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.data.elasticsearch.properties", - "type": "java.util.Map", - "description": "Additional properties used to configure the client.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.data.elasticsearch.repositories.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Elasticsearch repositories.", - "defaultValue": true - }, - { - "name": "spring.data.jdbc.repositories.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable JDBC repositories.", - "defaultValue": true - }, - { - "name": "spring.data.jpa.repositories.bootstrap-mode", - "type": "org.springframework.data.repository.config.BootstrapMode", - "description": "Bootstrap mode for JPA repositories.", - "defaultValue": "default" - }, - { - "name": "spring.data.jpa.repositories.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable JPA repositories.", - "defaultValue": true - }, - { - "name": "spring.data.ldap.repositories.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable LDAP repositories.", - "defaultValue": true - }, - { - "name": "spring.data.mongodb.grid-fs-database", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.mongodb.gridfs.database", - "level": "error" - } - }, - { - "name": "spring.data.mongodb.repositories.type", - "type": "org.springframework.boot.autoconfigure.data.RepositoryType", - "description": "Type of Mongo repositories to enable.", - "defaultValue": "auto" - }, - { - "name": "spring.data.mongodb.uri", - "defaultValue": "mongodb://localhost/test" - }, - { - "name": "spring.data.neo4j.auto-index", - "description": "Auto index mode.", - "defaultValue": "none", - "deprecation": { - "reason": "Automatic index creation is no longer supported.", - "level": "error" - } - }, - { - "name": "spring.data.neo4j.embedded.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable embedded mode if the embedded driver is available.", - "deprecation": { - "reason": "Embedded mode is no longer supported, please use Testcontainers instead.", - "level": "error" - } - }, - { - "name": "spring.data.neo4j.open-in-view", - "type": "java.lang.Boolean", - "description": "Register OpenSessionInViewInterceptor that binds a Neo4j Session to the thread for the entire processing of the request.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.data.neo4j.password", - "type": "java.lang.String", - "description": "Login password of the server.", - "deprecation": { - "replacement": "spring.neo4j.authentication.password", - "level": "error" - } - }, - { - "name": "spring.data.neo4j.repositories.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Neo4j repositories.", - "defaultValue": true, - "deprecation": { - "replacement": "spring.data.neo4j.repositories.type", - "level": "error" - } - }, - { - "name": "spring.data.neo4j.repositories.type", - "type": "org.springframework.boot.autoconfigure.data.RepositoryType", - "description": "Type of Neo4j repositories to enable.", - "defaultValue": "auto" - }, - { - "name": "spring.data.neo4j.uri", - "type": "java.lang.String", - "description": "URI used by the driver. Auto-detected by default.", - "deprecation": { - "replacement": "spring.neo4j.uri", - "level": "error" - } - }, - { - "name": "spring.data.neo4j.use-native-types", - "type": "java.lang.Boolean", - "description": "Whether to use Neo4j native types wherever possible.", - "deprecation": { - "reason": "Native type support is now built-in.", - "level": "error" - } - }, - { - "name": "spring.data.neo4j.username", - "type": "java.lang.String", - "description": "Login user of the server.", - "deprecation": { - "replacement": "spring.neo4j.authentication.username", - "level": "error" - } - }, - { - "name": "spring.data.r2dbc.repositories.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable R2DBC repositories.", - "defaultValue": true - }, - { - "name": "spring.data.redis.repositories.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Redis repositories.", - "defaultValue": true - }, - { - "name": "spring.data.redis.ssl", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.data.redis.ssl.enabled", - "level": "error" - } - }, - { - "name" : "spring.datasource.continue-on-error", - "type" : "java.lang.Boolean", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.continue-on-error" - } - }, { - "name" : "spring.datasource.data", - "type" : "java.util.List", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.data-locations" - } - }, { - "name" : "spring.datasource.data-password", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.password" - } - }, { - "name" : "spring.datasource.data-username", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.username" - } - }, { - "name" : "spring.datasource.initialization-mode", - "type" : "org.springframework.boot.jdbc.DataSourceInitializationMode", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.mode" - } - }, { - "name": "spring.datasource.jmx-enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable JMX support (if provided by the underlying pool).", - "defaultValue": false, - "deprecation": { - "level": "error", - "replacement": "spring.datasource.tomcat.jmx-enabled" - } - }, { - "name" : "spring.datasource.platform", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.platform" - } - }, { - "name" : "spring.datasource.schema", - "type" : "java.util.List", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.schema-locations" - } - }, { - "name" : "spring.datasource.schema-password", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.password" - } - }, { - "name" : "spring.datasource.schema-username", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.username" - } - }, { - "name" : "spring.datasource.separator", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.separator" - } - }, { - "name" : "spring.datasource.sql-script-encoding", - "type" : "java.nio.charset.Charset", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.encoding" - } - }, { - "name": "spring.elasticsearch.jest.connection-timeout", - "type": "java.time.Duration", - "description": "Connection timeout.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.elasticsearch.jest.multi-threaded", - "type": "java.lang.Boolean", - "description": "Whether to enable connection requests from multiple execution threads.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.elasticsearch.jest.password", - "type": "java.lang.String", - "description": "Login password.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.elasticsearch.jest.proxy.host", - "type": "java.lang.String", - "description": "Proxy host the HTTP client should use.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.elasticsearch.jest.proxy.port", - "type": "java.lang.Integer", - "description": "Proxy port the HTTP client should use.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.elasticsearch.jest.read-timeout", - "type": "java.time.Duration", - "description": "Read timeout.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.elasticsearch.jest.uris", - "type": "java.util.List", - "description": "Comma-separated list of the Elasticsearch instances to use.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.elasticsearch.jest.username", - "type": "java.lang.String", - "description": "Login username.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.elasticsearch.uris", - "defaultValue": [ - "http://localhost:9200" - ] - }, - { - "name": "spring.elasticsearch.webclient.max-in-memory-size", - "type": "org.springframework.util.unit.DataSize", - "description": "Limit on the number of bytes that can be buffered whenever the input stream needs to be aggregated.", - "deprecation": { - "level": "error", - "reason": "Reactive Elasticsearch client no longer uses WebClient." - } - }, - { - "name": "spring.flyway.baseline-migration-prefix", - "defaultValue": "B", - "description": "Filename prefix for baseline migrations. Requires Flyway Teams.", - "deprecation": { - "level": "error", - "reason": "Removed in Flyway 9.0" - } - }, - { - "name": "spring.flyway.check-location", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.flyway.fail-on-missing-locations", - "level": "error" - } - }, - { - "name": "spring.flyway.cherry-pick", - "description": "Migrations that Flyway should consider when migrating or undoing. When empty all available migrations are considered. Requires Flyway Teams.", - "deprecation": { - "level": "error", - "reason": "Removed in Flyway 10" - } - },{ - "name": "spring.flyway.community-db-support-enabled", - "defaultValue": false - }, - { - "name": "spring.flyway.dry-run-output", - "type": "java.io.OutputStream", - "deprecation": { - "level": "error", - "reason": "Flyway Teams only." - } - }, - { - "name": "spring.flyway.error-handlers", - "type": "org.flywaydb.core.api.errorhandler.ErrorHandler[]", - "deprecation": { - "level": "error", - "reason": "Flyway Teams only." - } - }, - { - "name": "spring.flyway.ignore-future-migrations", - "type": "java.lang.Boolean", - "description": "Whether to ignore future migrations when reading the schema history table.", - "deprecation": { - "level": "error", - "reason": "Removed in Flyway 9.0", - "replacement": "spring.flyway.ignore-migration-patterns" - } - }, - { - "name": "spring.flyway.ignore-ignored-migrations", - "type": "java.lang.Boolean", - "description": "Whether to ignore ignored migrations when reading the schema history table.", - "deprecation": { - "level": "error", - "reason": "Removed in Flyway 9.0", - "replacement": "spring.flyway.ignore-migration-patterns" - } - }, - { - "name": "spring.flyway.ignore-missing-migrations", - "type": "java.lang.Boolean", - "description": "Whether to ignore missing migrations when reading the schema history table.", - "deprecation": { - "level": "error", - "reason": "Removed in Flyway 9.0", - "replacement": "spring.flyway.ignore-migration-patterns" - } - }, - { - "name": "spring.flyway.ignore-pending-migrations", - "type": "java.lang.Boolean", - "description": "Whether to ignore pending migrations when reading the schema history table.", - "deprecation": { - "level": "error", - "reason": "Removed in Flyway 9.0", - "replacement": "spring.flyway.ignore-migration-patterns" - } - }, - { - "name": "spring.flyway.license-key", - "description": "License key for Flyway Teams.", - "deprecation": { - "level": "error", - "reason": "Removed in Flyway 10" - } - }, - { - "name": "spring.flyway.locations", - "sourceType": "org.springframework.boot.autoconfigure.flyway.FlywayProperties", - "defaultValue": [ - "classpath:db/migration" - ] - }, - { - "name": "spring.flyway.oracle-kerberos-config-file", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.flyway.kerberos-config-file", - "level": "error" - } - }, - { - "name": "spring.flyway.sql-migration-suffix", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.flyway.sql-migration-suffixes", - "level": "error" - } - }, - { - "name": "spring.flyway.sql-migration-suffixes", - "sourceType": "org.springframework.boot.autoconfigure.flyway.FlywayProperties", - "defaultValue": [ - ".sql" - ] - }, - { - "name": "spring.flyway.undo-sql-migration-prefix", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "reason": "Removed in Flyway 10" - } - }, - { - "name": "spring.flyway.vault-secrets", - "type": "java.util.List", - "deprecation": { - "level": "error", - "reason": "Removed in the open source release of Flyway 7.12." - } - }, - { - "name": "spring.flyway.vault-token", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "reason": "Removed in the open source release of Flyway 7.12." - } - }, - { - "name": "spring.flyway.vault-url", - "type": "java.lang.String", - "deprecation": { - "level": "error", - "reason": "Removed in the open source release of Flyway 7.12." - } - }, - { - "name": "spring.freemarker.allow-request-override", - "description": "Whether HttpServletRequest attributes are allowed to override (hide) controller generated model attributes of the same name. Only supported with Spring MVC." - }, - { - "name": "spring.freemarker.allow-session-override", - "description": "Whether HttpSession attributes are allowed to override (hide) controller generated model attributes of the same name. Only supported with Spring MVC." - }, - { - "name": "spring.freemarker.cache", - "description": "Whether to enable template caching. Only supported with Spring MVC." - }, - { - "name": "spring.freemarker.content-type", - "description": "Content-Type value. Only supported with Spring MVC." - }, - { - "name": "spring.freemarker.expose-request-attributes", - "description": "Whether all request attributes should be added to the model prior to merging with the template. Only supported with Spring MVC." - }, - { - "name": "spring.freemarker.expose-session-attributes", - "description": "Whether all HttpSession attributes should be added to the model prior to merging with the template. Only supported with Spring MVC." - }, - { - "name": "spring.freemarker.expose-spring-macro-helpers", - "description": "Whether to expose a RequestContext for use by Spring's macro library, under the name \"springMacroRequestContext\". Only supported with Spring MVC." - }, - { - "name": "spring.freemarker.prefix", - "defaultValue": "" - }, - { - "name": "spring.freemarker.suffix", - "defaultValue": ".ftlh" - }, - { - "name": "spring.git.properties", - "type": "java.lang.String", - "description": "Resource reference to a generated git info properties file.", - "deprecation": { - "replacement": "spring.info.git.location", - "level": "error" - } - }, - { - "name": "spring.graphql.schema.file-extensions", - "defaultValue": ".graphqls,.gqls" - }, - { - "name": "spring.graphql.schema.locations", - "defaultValue": "classpath:graphql/**/" - }, - { - "name": "spring.groovy.template.configuration.auto-escape", - "deprecation": { - "replacement": "spring.groovy.template.auto-escape", - "level": "warning" - } - }, - { - "name": "spring.groovy.template.configuration.auto-indent", - "deprecation": { - "replacement": "spring.groovy.template.auto-indent", - "level": "warning" - } - }, - { - "name": "spring.groovy.template.configuration.auto-indent-string", - "deprecation": { - "replacement": "spring.groovy.template.auto-indent-string", - "level": "warning" - } - }, - { - "name": "spring.groovy.template.configuration.auto-new-line", - "deprecation": { - "replacement": "spring.groovy.template.auto-new-line", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.configuration.base-template-class", - "deprecation": { - "replacement": "spring.groovy.template.base-template-class", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.configuration.cache-templates", - "deprecation": { - "replacement": "spring.groovy.template.cache", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.configuration.declaration-encoding", - "deprecation": { - "replacement": "spring.groovy.template.declaration-encoding", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.configuration.expand-empty-elements", - "deprecation": { - "replacement": "spring.groovy.template.expand-empty-elements", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.configuration.locale", - "deprecation": { - "replacement": "spring.groovy.template.locale", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.configuration.new-line-string", - "deprecation": { - "replacement": "spring.groovy.template.new-line-string", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.configuration.resource-loader-path", - "deprecation": { - "replacement": "spring.groovy.template.resource-loader-path", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.configuration.use-double-quotes", - "deprecation": { - "replacement": "spring.groovy.template.use-double-quotes", - "level": "warning", - "since": "3.5.0" - } - }, - { - "name": "spring.groovy.template.prefix", - "defaultValue": "" - }, - { - "name": "spring.groovy.template.suffix", - "defaultValue": ".tpl" - }, - { - "name": "spring.http.converters.preferred-json-mapper", - "type": "java.lang.String", - "defaultValue": "jackson", - "description": "Preferred JSON mapper to use for HTTP message conversion. By default, auto-detected according to the environment. Supported values are 'jackson', 'gson', and 'jsonb'. When other json mapping libraries (such as kotlinx.serialization) are present, use a custom HttpMessageConverters bean to control the preferred mapper." - }, - { - "name": "spring.http.encoding.charset", - "type": "java.nio.charset.Charset", - "description": "Charset of HTTP requests and responses. Added to the Content-Type header if not set explicitly.", - "deprecation": { - "replacement": "server.servlet.encoding.charset", - "level": "error" - } - }, - { - "name": "spring.http.encoding.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable http encoding support.", - "defaultValue": true, - "deprecation": { - "replacement": "server.servlet.encoding.enabled", - "level": "error" - } - }, - { - "name": "spring.http.encoding.force", - "type": "java.lang.Boolean", - "description": "Whether to force the encoding to the configured charset on HTTP requests and responses.", - "defaultValue": false, - "deprecation": { - "replacement": "server.servlet.encoding.force", - "level": "error" - } - }, - { - "name": "spring.http.encoding.force-request", - "type": "java.lang.Boolean", - "description": "Whether to force the encoding to the configured charset on HTTP requests. Defaults to true when force has not been specified.", - "defaultValue": true, - "deprecation": { - "replacement": "server.servlet.encoding.force-request", - "level": "error" - } - }, - { - "name": "spring.http.encoding.force-response", - "type": "java.lang.Boolean", - "description": "Whether to force the encoding to the configured charset on HTTP responses.", - "defaultValue": false, - "deprecation": { - "replacement": "server.servlet.encoding.force-response", - "level": "error" - } - }, - { - "name": "spring.http.encoding.mapping", - "type": "java.util.Map", - "description": "Locale in which to encode mapping.", - "deprecation": { - "replacement": "server.servlet.encoding.mapping", - "level": "error" - } - }, - { - "name": "spring.http.log-request-details", - "type": "java.lang.Boolean", - "description": "Whether logging of (potentially sensitive) request details at DEBUG and TRACE level is allowed.", - "defaultValue": false, - "deprecation": { - "replacement": "spring.mvc.log-request-details", - "level": "error" - } - }, - { - "name": "spring.influx.password", - "deprecation": { - "level": "error", - "reason": "The new InfluxDb Java client provides Spring Boot integration." - } - }, - { - "name": "spring.influx.url", - "deprecation": { - "level": "error", - "reason": "The new InfluxDb Java client provides Spring Boot integration." - } - }, - { - "name": "spring.influx.user", - "deprecation": { - "level": "error", - "reason": "The new InfluxDb Java client provides Spring Boot integration." - } - }, - { - "name": "spring.info.build.location", - "defaultValue": "classpath:META-INF/build-info.properties" - }, - { - "name": "spring.info.git.location", - "defaultValue": "classpath:git.properties" - }, - { - "name": "spring.jackson.constructor-detector", - "defaultValue": "default" - }, - { - "name": "spring.jackson.datatype.enum", - "description": "Jackson on/off features for enums." - }, - { - "name": "spring.jackson.joda-date-time-format", - "type": "java.lang.String", - "description": "Joda date time format string. If not configured, \"date-format\" is used as a fallback if it is configured with a format string.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.jpa.hibernate.use-new-id-generator-mappings", - "type": "java.lang.Boolean", - "description": "Whether to use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE. This is actually a shortcut for the \"hibernate.id.new_generator_mappings\" property. When not specified will default to \"true\".", - "deprecation": { - "level": "error", - "reason": "Hibernate no longer supports disabling the use of new ID generator mappings." - } - }, - { - "name": "spring.jpa.open-in-view", - "defaultValue": true - }, - { - "name": "spring.jta.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable JTA support.", - "defaultValue": true - }, - { - "name": "spring.jta.narayana.default-timeout", - "type": "java.time.Duration", - "description": "Transaction timeout. If a duration suffix is not specified, seconds will be used.", - "defaultValue": "60s", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.expiry-scanners", - "type": "java.util.List", - "description": "Comma-separated list of expiry scanners.", - "defaultValue": [ - "com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner" - ], - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.log-dir", - "type": "java.lang.String", - "description": "Transaction object store directory.", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.one-phase-commit", - "type": "java.lang.Boolean", - "description": "Whether to enable one phase commit optimization.", - "defaultValue": true, - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.periodic-recovery-period", - "type": "java.time.Duration", - "description": "Interval in which periodic recovery scans are performed. If a duration suffix is not specified, seconds will be used.", - "defaultValue": "120s", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.recovery-backoff-period", - "type": "java.time.Duration", - "description": "Back off period between first and second phases of the recovery scan. If a duration suffix is not specified, seconds will be used.", - "defaultValue": "10s", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.recovery-db-pass", - "type": "java.lang.String", - "description": "Database password to be used by the recovery manager.", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.recovery-db-user", - "type": "java.lang.String", - "description": "Database username to be used by the recovery manager.", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.recovery-jms-pass", - "type": "java.lang.String", - "description": "JMS password to be used by the recovery manager.", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.recovery-jms-user", - "type": "java.lang.String", - "description": "JMS username to be used by the recovery manager.", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.recovery-modules", - "type": "java.util.List", - "description": "Comma-separated list of recovery modules.", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.transaction-manager-id", - "type": "java.lang.String", - "description": "Unique transaction manager id.", - "defaultValue": "1", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.jta.narayana.xa-resource-orphan-filters", - "type": "java.util.List", - "description": "Comma-separated list of orphan filters.", - "deprecation": { - "level": "error", - "reason": "Narayana support has moved to third party starter." - } - }, - { - "name": "spring.kafka.admin.ssl.keystore-location", - "type": "org.springframework.core.io.Resource", - "description": "Location of the key store file.", - "deprecation": { - "replacement": "spring.kafka.admin.ssl.key-store-location", - "level": "error" - } - }, - { - "name": "spring.kafka.admin.ssl.keystore-password", - "type": "java.lang.String", - "description": "Store password for the key store file.", - "deprecation": { - "replacement": "spring.kafka.admin.ssl.key-store-password", - "level": "error" - } - }, - { - "name": "spring.kafka.admin.ssl.truststore-location", - "type": "org.springframework.core.io.Resource", - "description": "Location of the trust store file.", - "deprecation": { - "replacement": "spring.kafka.admin.ssl.trust-store-location", - "level": "error" - } - }, - { - "name": "spring.kafka.admin.ssl.truststore-password", - "type": "java.lang.String", - "description": "Store password for the trust store file.", - "deprecation": { - "replacement": "spring.kafka.admin.ssl.trust-store-password", - "level": "error" - } - }, - { - "name": "spring.kafka.consumer.ssl.keystore-location", - "type": "org.springframework.core.io.Resource", - "description": "Location of the key store file.", - "deprecation": { - "replacement": "spring.kafka.consumer.ssl.key-store-location", - "level": "error" - } - }, - { - "name": "spring.kafka.consumer.ssl.keystore-password", - "type": "java.lang.String", - "description": "Store password for the key store file.", - "deprecation": { - "replacement": "spring.kafka.consumer.ssl.key-store-password", - "level": "error" - } - }, - { - "name": "spring.kafka.consumer.ssl.truststore-location", - "type": "org.springframework.core.io.Resource", - "description": "Location of the trust store file.", - "deprecation": { - "replacement": "spring.kafka.consumer.ssl.trust-store-location", - "level": "error" - } - }, - { - "name": "spring.kafka.consumer.ssl.truststore-password", - "type": "java.lang.String", - "description": "Store password for the trust store file.", - "deprecation": { - "replacement": "spring.kafka.consumer.ssl.trust-store-password", - "level": "error" - } - }, - { - "name": "spring.kafka.listener.only-log-record-metadata", - "type": "java.lang.Boolean", - "defaultValue": true, - "description": "Whether to suppress the entire record from being written to the log when retries are being attempted.", - "deprecation": { - "reason": "Use KafkaUtils#setConsumerRecordFormatter instead.", - "level": "error" - } - }, - { - "name": "spring.kafka.producer.ssl.keystore-location", - "type": "org.springframework.core.io.Resource", - "description": "Location of the key store file.", - "deprecation": { - "replacement": "spring.kafka.producer.ssl.key-store-location", - "level": "error" - } - }, - { - "name": "spring.kafka.producer.ssl.keystore-password", - "type": "java.lang.String", - "description": "Store password for the key store file.", - "deprecation": { - "replacement": "spring.kafka.producer.ssl.key-store-password", - "level": "error" - } - }, - { - "name": "spring.kafka.producer.ssl.truststore-location", - "type": "org.springframework.core.io.Resource", - "description": "Location of the trust store file.", - "deprecation": { - "replacement": "spring.kafka.producer.ssl.trust-store-location", - "level": "error" - } - }, - { - "name": "spring.kafka.producer.ssl.truststore-password", - "type": "java.lang.String", - "description": "Store password for the trust store file.", - "deprecation": { - "replacement": "spring.kafka.producer.ssl.trust-store-password", - "level": "error" - } - }, - { - "name": "spring.kafka.ssl.keystore-location", - "type": "org.springframework.core.io.Resource", - "description": "Location of the key store file.", - "deprecation": { - "replacement": "spring.kafka.ssl.key-store-location", - "level": "error" - } - }, - { - "name": "spring.kafka.ssl.keystore-password", - "type": "java.lang.String", - "description": "Store password for the key store file.", - "deprecation": { - "replacement": "spring.kafka.ssl.key-store-password", - "level": "error" - } - }, - { - "name": "spring.kafka.ssl.truststore-location", - "type": "org.springframework.core.io.Resource", - "description": "Location of the trust store file.", - "deprecation": { - "replacement": "spring.kafka.ssl.trust-store-location", - "level": "error" - } - }, - { - "name": "spring.kafka.ssl.truststore-password", - "type": "java.lang.String", - "description": "Store password for the trust store file.", - "deprecation": { - "replacement": "spring.kafka.ssl.trust-store-password", - "level": "error" - } - }, - { - "name": "spring.kafka.streams.cache-max-bytes-buffering", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.kafka.streams.state-store-cache-max-size", - "level": "error" - } - }, - { - "name": "spring.kafka.streams.cache-max-size-buffering", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.kafka.streams.state-store-cache-max-size", - "level": "error", - "since": "3.1.0" - } - }, - { - "name": "spring.liquibase.check-change-log-location", - "type": "java.lang.Boolean", - "description": "Check the change log location exists.", - "defaultValue": true, - "deprecation": { - "reason": "Liquibase has its own check that checks if the change log location exists making this property redundant.", - "level": "error" - } - }, - { - "name": "spring.liquibase.labels", - "deprecation": { - "replacement": "spring.liquibase.label-filter", - "level": "error" - } - }, - { - "name": "spring.liquibase.show-summary", - "defaultValue": "summary" - }, - { - "name": "spring.liquibase.show-summary-output", - "defaultValue": "log" - }, - { - "name": "spring.liquibase.ui-service", - "defaultValue": "logger" - }, - { - "name": "spring.mail.test-connection", - "description": "Whether to test that the mail server is available on startup.", - "sourceType": "org.springframework.boot.autoconfigure.mail.MailProperties", - "type": "java.lang.Boolean", - "defaultValue": false - }, - { - "name": "spring.messages.basename", - "defaultValue": [ - "messages" - ] - }, - { - "name": "spring.mustache.prefix", - "defaultValue": "classpath:/templates/" - }, - { - "name": "spring.mustache.reactive.media-types", - "defaultValue": "text/html;charset=UTF-8" - }, - { - "name": "spring.mustache.suffix", - "defaultValue": ".mustache" - }, - { - "name": "spring.mvc.converters.preferred-json-mapper", - "type": "java.lang.String", - "defaultValue": "jackson", - "description": "Preferred JSON mapper to use for HTTP message conversion. By default, auto-detected according to the environment. Supported values are 'jackson', 'gson', and 'jsonb'. When other json mapping libraries (such as kotlinx.serialization) are present, use a custom HttpMessageConverters bean to control the preferred mapper.", - "deprecation": { - "replacement": "spring.http.converters.preferred-json-mapper", - "level": "error" - } - }, - { - "name": "spring.mvc.date-format", - "type": "java.lang.String", - "description": "Date format to use, for example 'dd/MM/yyyy'.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.mvc.favicon.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable resolution of favicon.ico.", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.mvc.formcontent.filter.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Spring's FormContentFilter.", - "defaultValue": true - }, - { - "name": "spring.mvc.formcontent.putfilter.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Spring's HttpPutFormContentFilter.", - "defaultValue": true, - "deprecation": { - "replacement": "spring.mvc.formcontent.filter.enabled", - "level": "error" - } - }, - { - "name": "spring.mvc.hiddenmethod.filter.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Spring's HiddenHttpMethodFilter.", - "defaultValue": false - }, - { - "name": "spring.mvc.ignore-default-model-on-redirect", - "deprecation": { - "reason": "Deprecated for removal in Spring MVC.", - "level": "error" - } - }, - { - "name": "spring.mvc.locale", - "type": "java.util.Locale", - "deprecation": { - "replacement": "spring.web.locale", - "level": "error" - } - }, - { - "name": "spring.mvc.locale-resolver", - "type": "org.springframework.boot.autoconfigure.web.WebProperties$LocaleResolver", - "deprecation": { - "replacement": "spring.web.locale-resolver", - "level": "error" - } - }, - { - "name": "spring.mvc.throw-exception-if-no-handler-found", - "deprecation": { - "reason": "DispatcherServlet property is deprecated for removal and should no longer need to be configured.", - "level": "error" - } - }, - { - "name": "spring.neo4j.uri", - "defaultValue": "bolt://localhost:7687" - }, - { - "name": "spring.pulsar.defaults.topic.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable default tenant and namespace support for topics.", - "defaultValue": true - }, - { - "name": "spring.pulsar.function.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable function support.", - "defaultValue": true - }, - { - "name": "spring.pulsar.producer.cache.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable caching in the PulsarProducerFactory.", - "defaultValue": true - }, - { - "name": "spring.quartz.jdbc.comment-prefix", - "defaultValue": [ - "#", - "--" - ] - }, - { - "name": "spring.quartz.scheduler-name", - "defaultValue": "quartzScheduler" - }, - { - "name": "spring.rabbitmq.dynamic", - "type": "java.lang.Boolean", - "description": "Whether to create an AmqpAdmin bean.", - "defaultValue": true - }, - { - "name": "spring.rabbitmq.listener.simple.transaction-size", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.rabbitmq.publisher-confirms", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.rabbitmq.template.queue", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.rabbitmq.template.default-receive-queue", - "level": "error" - } - }, - { - "name": "spring.reactor.stacktrace-mode.enabled", - "description": "Whether Reactor should collect stacktrace information at runtime.", - "defaultValue": false, - "deprecation": { - "replacement": "spring.reactor.debug-agent.enabled" - } - }, - { - "name": "spring.redis.client-name", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.redis.client-name", - "level": "error" - } - }, - { - "name": "spring.redis.client-type", - "type": "org.springframework.boot.autoconfigure.data.redis.RedisProperties$ClientType", - "deprecation": { - "replacement": "spring.data.redis.client-type", - "level": "error" - } - }, - { - "name": "spring.redis.cluster.max-redirects", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.data.redis.cluster.max-redirects", - "level": "error" - } - }, - { - "name": "spring.redis.cluster.nodes", - "type": "java.util.List", - "deprecation": { - "replacement": "spring.data.redis.cluster.nodes", - "level": "error" - } - }, - { - "name": "spring.redis.connect-timeout", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.data.redis.connect-timeout", - "level": "error" - } - }, - { - "name": "spring.redis.database", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.data.redis.database", - "level": "error" - } - }, - { - "name": "spring.redis.host", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.redis.host", - "level": "error" - } - }, - { - "name": "spring.redis.jedis.pool.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.jedis.pool.max-active", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.jedis.pool.max-idle", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.jedis.pool.max-wait", - "type": "java.time.Duration", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.jedis.pool.min-idle", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.jedis.pool.time-between-eviction-runs", - "type": "java.time.Duration", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.cluster.refresh.adaptive", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.data.redis.lettuce.cluster.refresh.adaptive", - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.cluster.refresh.dynamic-refresh-sources", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.data.redis.lettuce.cluster.refresh.dynamic-refresh-sources", - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.cluster.refresh.period", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.data.redis.lettuce.cluster.refresh.period", - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.pool.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.pool.max-active", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.pool.max-idle", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.pool.max-wait", - "type": "java.time.Duration", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.pool.min-idle", - "type": "java.lang.Integer", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.pool.time-between-eviction-runs", - "type": "java.time.Duration", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.redis.lettuce.shutdown-timeout", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.data.redis.lettuce.shutdown-timeout", - "level": "error" - } - }, - { - "name": "spring.redis.password", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.redis.password", - "level": "error" - } - }, - { - "name": "spring.redis.port", - "type": "java.lang.Integer", - "deprecation": { - "replacement": "spring.data.redis.port", - "level": "error" - } - }, - { - "name": "spring.redis.sentinel.master", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.redis.sentinel.master", - "level": "error" - } - }, - { - "name": "spring.redis.sentinel.nodes", - "type": "java.util.List", - "deprecation": { - "replacement": "spring.data.redis.sentinel.nodes", - "level": "error" - } - }, - { - "name": "spring.redis.sentinel.password", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.redis.sentinel.password", - "level": "error" - } - }, - { - "name": "spring.redis.sentinel.username", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.redis.sentinel.username", - "level": "error" - } - }, - { - "name": "spring.redis.ssl", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.data.redis.ssl", - "level": "error" - } - }, - { - "name": "spring.redis.timeout", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.data.redis.timeout", - "level": "error" - } - }, - { - "name": "spring.redis.url", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.redis.url", - "level": "error" - } - }, - { - "name": "spring.redis.username", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.data.redis.username", - "level": "error" - } - }, - { - "name": "spring.resources.add-mappings", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.add-mappings", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.cache-private", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.cache-private", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.cache-public", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.cache-public", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.max-age", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.max-age", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.must-revalidate", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.must-revalidate", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.no-cache", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.no-cache", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.no-store", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.no-store", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.no-transform", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.no-transform", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.proxy-revalidate", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.proxy-revalidate", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.s-max-age", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.s-max-age", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.stale-if-error", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.stale-if-error", - "level": "error" - } - }, - { - "name": "spring.resources.cache.cachecontrol.stale-while-revalidate", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.web.resources.cache.cachecontrol.stale-while-revalidate", - "level": "error" - } - }, - { - "name": "spring.resources.cache.period", - "type": "java.time.Duration", - "deprecation": { - "replacement": "spring.web.resources.cache.period", - "level": "error" - } - }, - { - "name": "spring.resources.cache.use-last-modified", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.cache.use-last-modified", - "level": "error" - } - }, - { - "name": "spring.resources.chain.cache", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.chain.cache", - "level": "error" - } - }, - { - "name": "spring.resources.chain.compressed", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.chain.compressed", - "level": "error" - } - }, - { - "name": "spring.resources.chain.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.chain.enabled", - "level": "error" - } - }, - { - "name": "spring.resources.chain.gzipped", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.chain.compressed", - "level": "error" - } - }, - { - "name": "spring.resources.chain.html-application-cache", - "type": "java.lang.Boolean", - "deprecation": { - "level": "error" - } - }, - { - "name": "spring.resources.chain.strategy.content.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.chain.strategy.content.enabled", - "level": "error" - } - }, - { - "name": "spring.resources.chain.strategy.content.paths", - "type": "java.lang.String[]", - "deprecation": { - "replacement": "spring.web.resources.chain.strategy.content.paths", - "level": "error" - } - }, - { - "name": "spring.resources.chain.strategy.fixed.enabled", - "type": "java.lang.Boolean", - "deprecation": { - "replacement": "spring.web.resources.chain.strategy.fixed.enabled", - "level": "error" - } - }, - { - "name": "spring.resources.chain.strategy.fixed.paths", - "type": "java.lang.String[]", - "deprecation": { - "replacement": "spring.web.resources.chain.strategy.fixed.paths", - "level": "error" - } - }, - { - "name": "spring.resources.chain.strategy.fixed.version", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.web.resources.chain.strategy.fixed.version", - "level": "error" - } - }, - { - "name": "spring.resources.static-locations", - "type": "java.lang.String[]", - "deprecation": { - "replacement": "spring.web.resources.static-locations", - "level": "error" - } - }, - { - "name": "spring.security.filter.dispatcher-types", - "defaultValue": [ - "async", - "error", - "forward", - "include", - "request" - ] - }, - { - "name": "spring.security.filter.order", - "defaultValue": -100 - }, - { - "name": "spring.security.oauth2.resourceserver.jwt.jws-algorithm", - "type": "java.lang.String", - "deprecation": { - "replacement": "spring.security.oauth2.resourceserver.jwt.jws-algorithms", - "level": "error" - } - }, - { - "name": "spring.servlet.encoding.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Servlet HTTP encoding support.", - "defaultValue": true - }, - { - "name": "spring.session.redis.cleanup-cron", - "defaultValue": "0 * * * * *" - }, - { - "name": "spring.session.servlet.filter-dispatcher-types", - "defaultValue": [ - "async", - "error", - "request" - ] - }, - { - "name": "spring.sql.init.enabled", - "type": "java.lang.Boolean", - "description": "Whether basic script-based initialization of an SQL database is enabled.", - "defaultValue": true, - "deprecation": { - "replacement": "spring.sql.init.mode", - "level": "warning" - } - }, - { - "name": "spring.threads.virtual.enabled", - "type": "java.lang.Boolean", - "description": "Whether to use virtual threads.", - "defaultValue": false - }, - { - "name": "spring.thymeleaf.prefix", - "defaultValue": "classpath:/templates/" - }, - { - "name": "spring.thymeleaf.reactive.media-types", - "defaultValue": [ - "text/html", - "application/xhtml+xml", - "application/xml", - "text/xml", - "application/rss+xml", - "application/atom+xml", - "application/javascript", - "application/ecmascript", - "text/javascript", - "text/ecmascript", - "application/json", - "text/css", - "text/plain", - "text/event-stream" - ] - }, - { - "name": "spring.thymeleaf.suffix", - "defaultValue": ".html" - }, - { - "name": "spring.validation.method.adapt-constraint-violations", - "type": "java.lang.Boolean", - "description": "Whether to adapt ConstraintViolations to MethodValidationResult.", - "defaultValue": false - }, - { - "name": "spring.webflux.hiddenmethod.filter.enabled", - "type": "java.lang.Boolean", - "description": "Whether to enable Spring's HiddenHttpMethodFilter.", - "defaultValue": false - }, - { - "name": "spring.webflux.multipart.streaming", - "type": "java.lang.Boolean", - "deprecation": { - "reason": "Replaced by the PartEventHttpMessageReader and the PartEvent API.", - "level": "error" - } - }, - { - "name": "spring.webservices.wsdl-locations", - "type": "java.util.List", - "description": "Comma-separated list of locations of WSDLs and accompanying XSDs to be exposed as beans." - } - ], - "hints": [ - { - "name": "server.servlet.jsp.class-name", - "providers": [ - { - "name": "class-reference", - "parameters": { - "target": "jakarta.servlet.http.HttpServlet" - } - } - ] - }, - { - "name": "server.tomcat.accesslog.encoding", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "java.nio.charset.Charset" - } - } - ] - }, - { - "name": "server.tomcat.accesslog.locale", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "java.util.Locale" - } - } - ] - }, - { - "name": "server.tomcat.relaxed-path-chars", - "values": [ - { - "value": "<" - }, - { - "value": ">" - }, - { - "value": "[" - }, - { - "value": "\\" - }, - { - "value": "]" - }, - { - "value": "^" - }, - { - "value": "`" - }, - { - "value": "{" - }, - { - "value": "|" - }, - { - "value": "}" - } - ] - }, - { - "name": "server.tomcat.relaxed-query-chars", - "values": [ - { - "value": "<" - }, - { - "value": ">" - }, - { - "value": "[" - }, - { - "value": "\\" - }, - { - "value": "]" - }, - { - "value": "^" - }, - { - "value": "`" - }, - { - "value": "{" - }, - { - "value": "|" - }, - { - "value": "}" - } - ] - }, - { - "name": "spring.cache.jcache.provider", - "providers": [ - { - "name": "class-reference", - "parameters": { - "target": "javax.cache.spi.CachingProvider" - } - } - ] - }, - { - "name": "spring.cassandra.schema-action", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "org.springframework.data.cassandra.config.SchemaAction" - } - } - ] - }, - { - "name": "spring.data.mongodb.field-naming-strategy", - "providers": [ - { - "name": "class-reference", - "parameters": { - "target": "org.springframework.data.mapping.model.FieldNamingStrategy" - } - } - ] - }, - { - "name": "spring.data.mongodb.protocol", - "values": [ - { - "value": "mongodb" - }, - { - "value": "mongodb+srv" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.data.redis.lettuce.read-from", - "values": [ - { - "value": "any", - "description": "Read from any node." - }, - { - "value": "any-replica", - "description": "Read from any replica node." - }, - { - "value": "lowest-latency", - "description": "Read from the node with the lowest latency during topology discovery." - }, - { - "value": "regex:", - "description": "Read from any node that has RedisURI matching with the given pattern." - }, - { - "value": "replica", - "description": "Read from the replica only." - }, - { - "value": "replica-preferred", - "description": "Read preferred from replica and fall back to upstream if no replica is available." - }, - { - "value": "subnet:", - "description": "Read from any node in the subnets." - }, - { - "value": "upstream", - "description": "Read from the upstream only." - }, - { - "value": "upstream-preferred", - "description": "Read preferred from the upstream and fall back to a replica if the upstream is not available." - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.datasource.data", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "java.util.List" - } - } - ] - }, - { - "name": "spring.datasource.driver-class-name", - "providers": [ - { - "name": "class-reference", - "parameters": { - "target": "java.sql.Driver" - } - } - ] - }, - { - "name": "spring.datasource.schema", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "java.util.List" - } - } - ] - }, - { - "name": "spring.datasource.xa.data-source-class-name", - "providers": [ - { - "name": "class-reference", - "parameters": { - "target": "javax.sql.XADataSource" - } - } - ] - }, - { - "name": "spring.datasource.xa.data-source-class-name", - "providers": [ - { - "name": "class-reference", - "parameters": { - "target": "javax.sql.XADataSource" - } - } - ] - }, - { - "name": "spring.graphql.cors.allowed-headers", - "values": [ - { - "value": "*" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.graphql.cors.allowed-methods", - "values": [ - { - "value": "*" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.graphql.cors.allowed-origins", - "values": [ - { - "value": "*" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.http.converters.preferred-json-mapper", - "values": [ - { - "value": "gson" - }, - { - "value": "jackson" - }, - { - "value": "jsonb" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.jms.listener.session.acknowledge-mode", - "values": [ - { - "value": "auto", - "description": "Messages sent or received from the session are automatically acknowledged. This is the simplest mode and enables once-only message delivery guarantee." - }, - { - "value": "client", - "description": "Messages are acknowledged once the message listener implementation has called \"jakarta.jms.Message#acknowledge()\". This mode gives the application (rather than the JMS provider) complete control over message acknowledgement." - }, - { - "value": "dups_ok", - "description": "Similar to auto acknowledgment except that said acknowledgment is lazy. As a consequence, the messages might be delivered more than once. This mode enables at-least-once message delivery guarantee." - } - ] - }, - { - "name": "spring.jms.template.session.acknowledge-mode", - "values": [ - { - "value": "auto", - "description": "Messages sent or received from the session are automatically acknowledged. This is the simplest mode and enables once-only message delivery guarantee." - }, - { - "value": "client", - "description": "Messages are acknowledged once the message listener implementation has called \"jakarta.jms.Message#acknowledge()\". This mode gives the application (rather than the JMS provider) complete control over message acknowledgement." - }, - { - "value": "dups_ok", - "description": "Similar to auto acknowledgment except that said acknowledgment is lazy. As a consequence, the messages might be delivered more than once. This mode enables at-least-once message delivery guarantee." - } - ] + "name": "server.servlet.jsp.class-name", + "providers": [ + { + "name": "class-reference", + "parameters": { + "target": "jakarta.servlet.http.HttpServlet" + } + } + ] }, { "name": "spring.jmx.server", @@ -3011,336 +281,6 @@ } } ] - }, - { - "name": "spring.jpa.hibernate.ddl-auto", - "values": [ - { - "value": "create", - "description": "Create the schema and destroy previous data." - }, - { - "value": "create-drop", - "description": "Create and then destroy the schema at the end of the session." - }, - { - "value": "create-only", - "description": "Create the schema." - }, - { - "value": "drop", - "description": "Drop the schema." - }, - { - "value": "none", - "description": "Disable DDL handling." - }, - { - "value": "truncate", - "description": "Truncate the tables in the schema." - }, - { - "value": "update", - "description": "Update the schema if necessary." - }, - { - "value": "validate", - "description": "Validate the schema, make no changes to the database." - } - ] - }, - { - "name": "spring.jpa.hibernate.naming.implicit-strategy", - "providers": [ - { - "name": "class-reference", - "parameters": { - "target": "org.hibernate.boot.model.naming.ImplicitNamingStrategy" - } - } - ] - }, - { - "name": "spring.jpa.hibernate.naming.physical-strategy", - "providers": [ - { - "name": "class-reference", - "parameters": { - "target": "org.hibernate.boot.model.naming.PhysicalNamingStrategy" - } - } - ] - }, - { - "name": "spring.kafka.consumer.auto-offset-reset", - "values": [ - { - "value": "earliest", - "description": "Automatically reset the offset to the earliest offset." - }, - { - "value": "latest", - "description": "Automatically reset the offset to the latest offset." - }, - { - "value": "none", - "description": "Throw exception to the consumer if no previous offset is found for the consumer's group." - }, - { - "value": "exception", - "description": "Throw exception to the consumer." - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.kafka.consumer.key-deserializer", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "org.apache.kafka.common.serialization.Deserializer" - } - } - ] - }, - { - "name": "spring.kafka.consumer.value-deserializer", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "org.apache.kafka.common.serialization.Deserializer" - } - } - ] - }, - { - "name": "spring.kafka.producer.key-serializer", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "org.apache.kafka.common.serialization.Serializer" - } - } - ] - }, - { - "name": "spring.kafka.producer.value-serializer", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "org.apache.kafka.common.serialization.Serializer" - } - } - ] - }, - { - "name": "spring.liquibase.change-log", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "org.springframework.core.io.Resource" - } - } - ] - }, - { - "name": "spring.mvc.converters.preferred-json-mapper", - "values": [ - { - "value": "gson" - }, - { - "value": "jackson" - }, - { - "value": "jsonb" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.mvc.format.date", - "values": [ - { - "value": "dd/MM/yyyy", - "description": "Example date format. Any format supported by DateTimeFormatter.parse can be used." - }, - { - "value": "iso", - "description": "ISO-8601 extended local date format." - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.mvc.format.date-time", - "values": [ - { - "value": "yyyy-MM-dd HH:mm:ss", - "description": "Example date-time format. Any format supported by DateTimeFormatter.parse can be used." - }, - { - "value": "iso", - "description": "ISO-8601 extended local date-time format." - }, - { - "value": "iso-offset", - "description": "ISO offset date-time format." - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.mvc.format.time", - "values": [ - { - "value": "HH:mm:ss", - "description": "Example time format. Any format supported by DateTimeFormatter.parse can be used." - }, - { - "value": "iso", - "description": "ISO-8601 extended local time format." - }, - { - "value": "iso-offset", - "description": "ISO offset time format." - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.sql.init.data-locations", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "java.util.List" - } - } - ] - }, - { - "name": "spring.sql.init.schema-locations", - "providers": [ - { - "name": "handle-as", - "parameters": { - "target": "java.util.List" - } - } - ] - }, - { - "name": "spring.webflux.format.date", - "values": [ - { - "value": "dd/MM/yyyy", - "description": "Example date format. Any format supported by DateTimeFormatter.parse can be used." - }, - { - "value": "iso", - "description": "ISO-8601 extended local date format." - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.webflux.format.date-time", - "values": [ - { - "value": "yyyy-MM-dd HH:mm:ss", - "description": "Example date-time format. Any format supported by DateTimeFormatter.parse can be used." - }, - { - "value": "iso", - "description": "ISO-8601 extended local date-time format." - }, - { - "value": "iso-offset", - "description": "ISO offset date-time format." - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.webflux.format.time", - "values": [ - { - "value": "HH:mm:ss", - "description": "Example time format. Any format supported by DateTimeFormatter.parse can be used." - }, - { - "value": "iso", - "description": "ISO-8601 extended local time format." - }, - { - "value": "iso-offset", - "description": "ISO offset time format." - } - ], - "providers": [ - { - "name": "any" - } - ] } - ], - "ignored": { - "properties": [ - { - "name": "spring.datasource.dbcp2.driver" - }, - { - "name": "spring.datasource.hikari.credentials" - }, - { - "name": "spring.datasource.hikari.exception-override" - }, - { - "name": "spring.datasource.hikari.metrics-tracker-factory" - }, - { - "name": "spring.datasource.hikari.scheduled-executor" - }, - { - "name": "spring.datasource.oracleucp.connection-wait-duration-in-millis" - }, - { - "name": "spring.datasource.oracleucp.hostname-resolver" - } - ] - } + ] } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 23dc687cea13..0f4ed80b64ae 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -5,11 +5,7 @@ org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingL # Application Listeners org.springframework.context.ApplicationListener=\ -org.springframework.boot.autoconfigure.BackgroundPreinitializer - -# Environment Post Processors -org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.boot.autoconfigure.integration.IntegrationPropertiesEnvironmentPostProcessor +org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializingApplicationListener # Auto Configuration Import Listeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\ @@ -21,34 +17,12 @@ org.springframework.boot.autoconfigure.condition.OnBeanCondition,\ org.springframework.boot.autoconfigure.condition.OnClassCondition,\ org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition +# Background Preinitializers +org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer=\ +org.springframework.boot.autoconfigure.preinitialize.CharsetsBackgroundPreinitializer,\ +org.springframework.boot.autoconfigure.preinitialize.ConversionServiceBackgroundPreinitializer + # Failure Analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ -org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\ org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\ -org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\ -org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\ -org.springframework.boot.autoconfigure.jooq.JaxbNotAvailableExceptionFailureAnalyzer,\ -org.springframework.boot.autoconfigure.jooq.NoDslContextBeanFailureAnalyzer,\ -org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\ -org.springframework.boot.autoconfigure.r2dbc.MissingR2dbcPoolDependencyFailureAnalyzer,\ -org.springframework.boot.autoconfigure.r2dbc.MultipleConnectionPoolConfigurationsFailureAnalyzer,\ -org.springframework.boot.autoconfigure.r2dbc.NoConnectionFactoryBeanFailureAnalyzer,\ org.springframework.boot.autoconfigure.ssl.BundleContentNotWatchableFailureAnalyzer - -# Template Availability Providers -org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ -org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\ -org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\ -org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\ -org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\ -org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider - -# DataSource Initializer Detectors -org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\ -org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializerDatabaseInitializerDetector - -# Depends on Database Initialization Detectors -org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ -org.springframework.boot.autoconfigure.batch.JobRepositoryDependsOnDatabaseInitializationDetector,\ -org.springframework.boot.autoconfigure.quartz.SchedulerDependsOnDatabaseInitializationDetector,\ -org.springframework.boot.autoconfigure.session.JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/aot.factories index 17302dfd9b9c..e8b017f47142 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/aot.factories +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/aot.factories @@ -1,14 +1,8 @@ -org.springframework.aot.hint.RuntimeHintsRegistrar=\ -org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider$FreeMarkerTemplateAvailabilityRuntimeHints,\ -org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider$GroovyTemplateAvailabilityRuntimeHints,\ -org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonAutoConfigurationRuntimeHints,\ -org.springframework.boot.autoconfigure.template.TemplateRuntimeHints - org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=\ org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingProcessor -org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\ -org.springframework.boot.autoconfigure.flyway.ResourceProviderCustomizerBeanRegistrationAotProcessor - org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter=\ -org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer \ No newline at end of file +org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer + +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.autoconfigure.template.TemplateRuntimeHints diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index a691e4bbf4b4..c0bd0c0b0853 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,158 +1,12 @@ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration -org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration org.springframework.boot.autoconfigure.aop.AopAutoConfiguration org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration -org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration -org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration -org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration -org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration -org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration -org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration -org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration -org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration -org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration -org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration -org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration -org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration -org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration -org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration -org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration -org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration -org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration -org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration -org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration -org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration -org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration -org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration -org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration -org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration -org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration -org.springframework.boot.autoconfigure.graphql.data.GraphQlQueryByExampleAutoConfiguration -org.springframework.boot.autoconfigure.graphql.data.GraphQlQuerydslAutoConfiguration -org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQueryByExampleAutoConfiguration -org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQuerydslAutoConfiguration -org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration -org.springframework.boot.autoconfigure.graphql.rsocket.GraphQlRSocketAutoConfiguration -org.springframework.boot.autoconfigure.graphql.rsocket.RSocketGraphQlClientAutoConfiguration -org.springframework.boot.autoconfigure.graphql.security.GraphQlWebFluxSecurityAutoConfiguration -org.springframework.boot.autoconfigure.graphql.security.GraphQlWebMvcSecurityAutoConfiguration -org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration -org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration -org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration -org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration -org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration -org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration -org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration -org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration -org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration -org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorAutoConfiguration -org.springframework.boot.autoconfigure.http.client.reactive.service.ReactiveHttpServiceClientAutoConfiguration -org.springframework.boot.autoconfigure.http.client.service.HttpServiceClientAutoConfiguration -org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration -org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration -org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JdbcClientAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration -org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration -org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration -org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration -org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration -org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration -org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration -org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration -org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration -org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration -org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration -org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration -org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration -org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration -org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration -org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration -org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration -org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration -org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration -org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration -org.springframework.boot.autoconfigure.pulsar.PulsarAutoConfiguration -org.springframework.boot.autoconfigure.pulsar.PulsarReactiveAutoConfiguration -org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration -org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration -org.springframework.boot.autoconfigure.r2dbc.R2dbcProxyAutoConfiguration -org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration -org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration -org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration -org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration -org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration -org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientWebSecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientWebSecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.server.servlet.OAuth2AuthorizationServerAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.server.servlet.OAuth2AuthorizationServerJwtAutoConfiguration -org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration -org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration -org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration -org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration -org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration -org.springframework.boot.autoconfigure.session.SessionAutoConfiguration -org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration -org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration -org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration -org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration -org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration -org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration -org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration -org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration -org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration -org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration -org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration -org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements deleted file mode 100644 index 909fe10913d5..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration=org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/admin/SpringApplicationAdminJmxAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/admin/SpringApplicationAdminJmxAutoConfigurationTests.java index 9d0368257a44..22c6bc551733 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/admin/SpringApplicationAdminJmxAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/admin/SpringApplicationAdminJmxAutoConfigurationTests.java @@ -31,11 +31,8 @@ import org.springframework.boot.WebApplicationType; import org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -108,21 +105,6 @@ void registerWithCustomJmxNameWhenThereAreMultipleMBeanExporters() { }); } - @Test - void registerWithSimpleWebApp() throws Exception { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder() - .sources(ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - MultipleMBeanExportersConfiguration.class, SpringApplicationAdminJmxAutoConfiguration.class) - .run("--" + ENABLE_ADMIN_PROP, "--server.port=0")) { - assertThat(context).isInstanceOf(ServletWebServerApplicationContext.class); - assertThat(this.server.getAttribute(createDefaultObjectName(), "EmbeddedWebApplication")) - .isEqualTo(Boolean.TRUE); - int expected = ((ServletWebServerApplicationContext) context).getWebServer().getPort(); - String actual = getProperty(createDefaultObjectName(), "local.server.port"); - assertThat(actual).isEqualTo(String.valueOf(expected)); - } - } - @Test void onlyRegisteredOnceWhenThereIsAChildContext() { SpringApplicationBuilder parentBuilder = new SpringApplicationBuilder().web(WebApplicationType.NONE) @@ -151,11 +133,6 @@ private ObjectName createObjectName(String jmxName) { } } - private String getProperty(ObjectName objectName, String key) throws Exception { - return (String) this.server.invoke(objectName, "getProperty", new Object[] { key }, - new String[] { String.class.getName() }); - } - @Configuration(proxyBeanMethods = false) static class MultipleMBeanExportersConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/domain/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/domain/City.java deleted file mode 100644 index b55092b4f961..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/domain/City.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.batch.domain; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; - -@Entity -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String state; - - @Column(nullable = false) - private String country; - - @Column(nullable = false) - private String map; - - protected City() { - } - - public City(String name, String state, String country, String map) { - this.name = name; - this.state = state; - this.country = country; - this.map = map; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBeanTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingFilterBeanTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBeanTests.java rename to spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingFilterBeanTests.java index 0733ecfb7ea1..f305be13d224 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnMissingFilterBeanTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingFilterBeanTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.autoconfigure.condition; import java.io.IOException; import java.util.function.Consumer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeploymentTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeploymentTests.java index b64dad327d4c..f87c34db8363 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeploymentTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeploymentTests.java @@ -21,7 +21,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWebApplicationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWebApplicationTests.java index 475272597e2c..df240aa99318 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWebApplicationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWebApplicationTests.java @@ -17,16 +17,12 @@ package org.springframework.boot.autoconfigure.condition; import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.server.reactive.HttpHandler; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; @@ -47,8 +43,7 @@ void testNotWebApplicationWithServletContext() { @Test void testNotWebApplicationWithReactiveContext() { - new ReactiveWebApplicationContextRunner() - .withUserConfiguration(ReactiveApplicationConfig.class, NotWebApplicationConfiguration.class) + new ReactiveWebApplicationContextRunner().withUserConfiguration(NotWebApplicationConfiguration.class) .run((context) -> assertThat(context).doesNotHaveBean(String.class)); } @@ -58,21 +53,6 @@ void testNotWebApplication() { .run((context) -> assertThat(context).getBeans(String.class).containsExactly(entry("none", "none"))); } - @Configuration(proxyBeanMethods = false) - static class ReactiveApplicationConfig { - - @Bean - ReactiveWebServerFactory reactiveWebServerFactory() { - return new MockReactiveWebServerFactory(); - } - - @Bean - HttpHandler httpHandler() { - return (request, response) -> Mono.empty(); - } - - } - @Configuration(proxyBeanMethods = false) @ConditionalOnNotWebApplication static class NotWebApplicationConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeploymentTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeploymentTests.java index 8ae7e7f3064a..87d931e2cfdf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeploymentTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeploymentTests.java @@ -21,7 +21,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWebApplicationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWebApplicationTests.java index 7ed65f63a17f..4f926eb41bec 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWebApplicationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWebApplicationTests.java @@ -18,18 +18,14 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.reactive.AnnotationConfigReactiveWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.server.reactive.HttpHandler; import org.springframework.mock.web.MockServletContext; import static org.assertj.core.api.Assertions.assertThat; @@ -116,16 +112,6 @@ String reactive() { return "reactive"; } - @Bean - ReactiveWebServerFactory reactiveWebServerFactory() { - return new MockReactiveWebServerFactory(); - } - - @Bean - HttpHandler httpHandler() { - return (request, response) -> Mono.empty(); - } - } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/dao/PersistenceExceptionTranslationAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/dao/PersistenceExceptionTranslationAutoConfigurationTests.java deleted file mode 100644 index ea0cb78664d8..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/dao/PersistenceExceptionTranslationAutoConfigurationTests.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.dao; - -import java.util.Map; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; -import org.springframework.stereotype.Repository; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link PersistenceExceptionTranslationAutoConfiguration} - * - * @author Andy Wilkinson - * @author Stephane Nicoll - */ -class PersistenceExceptionTranslationAutoConfigurationTests { - - private AnnotationConfigApplicationContext context; - - @AfterEach - void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - void exceptionTranslationPostProcessorUsesCglibByDefault() { - this.context = new AnnotationConfigApplicationContext(PersistenceExceptionTranslationAutoConfiguration.class); - Map beans = this.context - .getBeansOfType(PersistenceExceptionTranslationPostProcessor.class); - assertThat(beans).hasSize(1); - assertThat(beans.values().iterator().next().isProxyTargetClass()).isTrue(); - } - - @Test - void exceptionTranslationPostProcessorCanBeConfiguredToUseJdkProxy() { - this.context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.aop.proxy-target-class=false").applyTo(this.context); - this.context.register(PersistenceExceptionTranslationAutoConfiguration.class); - this.context.refresh(); - Map beans = this.context - .getBeansOfType(PersistenceExceptionTranslationPostProcessor.class); - assertThat(beans).hasSize(1); - assertThat(beans.values().iterator().next().isProxyTargetClass()).isFalse(); - } - - @Test - void exceptionTranslationPostProcessorCanBeDisabled() { - this.context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.dao.exceptiontranslation.enabled=false").applyTo(this.context); - this.context.register(PersistenceExceptionTranslationAutoConfiguration.class); - this.context.refresh(); - Map beans = this.context - .getBeansOfType(PersistenceExceptionTranslationPostProcessor.class); - assertThat(beans).isEmpty(); - } - - @Test - void persistOfNullThrowsIllegalArgumentExceptionWithoutExceptionTranslation() { - this.context = new AnnotationConfigApplicationContext(EmbeddedDataSourceConfiguration.class, - HibernateJpaAutoConfiguration.class, TestConfiguration.class); - assertThatIllegalArgumentException().isThrownBy(() -> this.context.getBean(TestRepository.class).doSomething()); - } - - @Test - void persistOfNullThrowsInvalidDataAccessApiUsageExceptionWithExceptionTranslation() { - this.context = new AnnotationConfigApplicationContext(EmbeddedDataSourceConfiguration.class, - HibernateJpaAutoConfiguration.class, TestConfiguration.class, - PersistenceExceptionTranslationAutoConfiguration.class); - assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) - .isThrownBy(() -> this.context.getBean(TestRepository.class).doSomething()); - } - - @Configuration(proxyBeanMethods = false) - static class TestConfiguration { - - @Bean - TestRepository testRepository(EntityManagerFactory entityManagerFactory) { - return new TestRepository(entityManagerFactory.createEntityManager()); - } - - } - - @Repository - static class TestRepository { - - private final EntityManager entityManager; - - TestRepository(EntityManager entityManager) { - this.entityManager = entityManager; - } - - void doSomething() { - this.entityManager.persist(null); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/cassandra/CityCassandraRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/cassandra/CityCassandraRepository.java deleted file mode 100644 index dc74619bb5ce..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/cassandra/CityCassandraRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.cassandra; - -import org.springframework.boot.autoconfigure.data.cassandra.city.City; -import org.springframework.data.repository.Repository; - -public interface CityCassandraRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/cassandra/ReactiveCityCassandraRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/cassandra/ReactiveCityCassandraRepository.java deleted file mode 100644 index a4db4bd1cc5c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/cassandra/ReactiveCityCassandraRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.cassandra; - -import org.springframework.boot.autoconfigure.data.cassandra.city.City; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; - -public interface ReactiveCityCassandraRepository extends ReactiveCrudRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/CityCouchbaseRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/CityCouchbaseRepository.java deleted file mode 100644 index 4fbdcafc7652..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/CityCouchbaseRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.couchbase; - -import org.springframework.boot.autoconfigure.data.couchbase.city.City; -import org.springframework.data.repository.Repository; - -public interface CityCouchbaseRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/ReactiveCityCouchbaseRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/ReactiveCityCouchbaseRepository.java deleted file mode 100644 index 018cca78ac17..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/couchbase/ReactiveCityCouchbaseRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.couchbase; - -import org.springframework.boot.autoconfigure.data.couchbase.city.City; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; - -public interface ReactiveCityCouchbaseRepository extends ReactiveCrudRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/elasticsearch/CityElasticsearchDbRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/elasticsearch/CityElasticsearchDbRepository.java deleted file mode 100644 index 95b6ee5356b1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/elasticsearch/CityElasticsearchDbRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.elasticsearch; - -import org.springframework.boot.autoconfigure.data.elasticsearch.city.City; -import org.springframework.data.repository.Repository; - -public interface CityElasticsearchDbRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/elasticsearch/CityReactiveElasticsearchDbRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/elasticsearch/CityReactiveElasticsearchDbRepository.java deleted file mode 100644 index 23042b2096e5..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/elasticsearch/CityReactiveElasticsearchDbRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.elasticsearch; - -import org.springframework.boot.autoconfigure.data.elasticsearch.city.City; -import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; - -public interface CityReactiveElasticsearchDbRepository extends ReactiveElasticsearchRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/jpa/CityJpaRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/jpa/CityJpaRepository.java deleted file mode 100644 index 2fe340173745..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/jpa/CityJpaRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.jpa; - -import org.springframework.boot.autoconfigure.data.jpa.city.City; -import org.springframework.data.repository.Repository; - -public interface CityJpaRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/ldap/PersonLdapRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/ldap/PersonLdapRepository.java deleted file mode 100644 index d8fa8ee21ff1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/ldap/PersonLdapRepository.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.ldap; - -import javax.naming.Name; - -import org.springframework.boot.autoconfigure.data.ldap.person.Person; -import org.springframework.data.repository.Repository; - -public interface PersonLdapRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/neo4j/CityNeo4jRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/neo4j/CityNeo4jRepository.java deleted file mode 100644 index ae4734076a7a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/neo4j/CityNeo4jRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.neo4j; - -import org.springframework.boot.autoconfigure.data.neo4j.city.City; -import org.springframework.data.neo4j.repository.Neo4jRepository; - -public interface CityNeo4jRepository extends Neo4jRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/redis/CityRedisRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/redis/CityRedisRepository.java deleted file mode 100644 index af10ca1c6f3f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/redis/CityRedisRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.alt.redis; - -import org.springframework.boot.autoconfigure.data.redis.city.City; -import org.springframework.data.repository.Repository; - -public interface CityRedisRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/City.java deleted file mode 100644 index a5566944ec99..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/City.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.cassandra.city; - -import org.springframework.data.cassandra.core.mapping.CassandraType; -import org.springframework.data.cassandra.core.mapping.CassandraType.Name; -import org.springframework.data.cassandra.core.mapping.Column; -import org.springframework.data.cassandra.core.mapping.PrimaryKey; -import org.springframework.data.cassandra.core.mapping.Table; - -@Table -public class City { - - @PrimaryKey - @CassandraType(type = Name.BIGINT) - private Long id; - - @Column - private String name; - - @Column - private String state; - - @Column - private String country; - - @Column - private String map; - - public Long getId() { - return this.id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getState() { - return this.state; - } - - public void setState(String state) { - this.state = state; - } - - public String getCountry() { - return this.country; - } - - public void setCountry(String country) { - this.country = country; - } - - public String getMap() { - return this.map; - } - - public void setMap(String map) { - this.map = map; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/CityRepository.java deleted file mode 100644 index 2533ecd3da4b..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/CityRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.cassandra.city; - -import org.springframework.data.repository.Repository; - -public interface CityRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/ReactiveCityRepository.java deleted file mode 100644 index 26d3cfbf81fb..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/city/ReactiveCityRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.cassandra.city; - -import org.springframework.data.repository.reactive.ReactiveCrudRepository; - -public interface ReactiveCityRepository extends ReactiveCrudRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/City.java deleted file mode 100644 index 83be9f0023d4..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/City.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.couchbase.city; - -import org.springframework.data.annotation.Id; -import org.springframework.data.couchbase.core.mapping.Document; -import org.springframework.data.couchbase.core.mapping.Field; - -@Document -public class City { - - @Id - private String id; - - @Field - private String name; - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/CityRepository.java deleted file mode 100644 index 98c2cbb81a48..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/CityRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.couchbase.city; - -import org.springframework.data.repository.Repository; - -public interface CityRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/ReactiveCityRepository.java deleted file mode 100644 index 720a511c7c9a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/city/ReactiveCityRepository.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.couchbase.city; - -import reactor.core.publisher.Mono; - -import org.springframework.data.repository.Repository; - -public interface ReactiveCityRepository extends Repository { - - Mono save(City city); - - Mono findById(Long id); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/City.java deleted file mode 100644 index b3f95044a94c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/City.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.elasticsearch.city; - -import java.io.Serializable; - -import org.springframework.data.annotation.Id; -import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.annotations.Setting; - -@Document(indexName = "city") -@Setting(shards = 1, replicas = 0, refreshInterval = "-1") -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - private Long id; - - private String name; - - private String state; - - private String country; - - private String map; - - protected City() { - } - - public City(String name, String country) { - this.name = name; - this.country = country; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/CityRepository.java deleted file mode 100644 index 7059b8e787a8..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/CityRepository.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.elasticsearch.city; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.Repository; - -public interface CityRepository extends Repository { - - Page findAll(Pageable pageable); - - Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); - - City findByNameAndCountryAllIgnoringCase(String name, String country); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/ReactiveCityRepository.java deleted file mode 100644 index 077a83ff76d6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/city/ReactiveCityRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.elasticsearch.city; - -import org.springframework.data.repository.reactive.ReactiveCrudRepository; - -public interface ReactiveCityRepository extends ReactiveCrudRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/empty/EmptyDataPackage.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/empty/EmptyDataPackage.java deleted file mode 100644 index 9b9fb1afd5dd..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/empty/EmptyDataPackage.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.empty; - -/** - * Empty package used with data tests. - * - * @author Phillip Webb - */ -public class EmptyDataPackage { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/city/City.java deleted file mode 100644 index 533898ecb186..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/city/City.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.jdbc.city; - -import org.springframework.data.annotation.Id; -import org.springframework.data.relational.core.mapping.Table; - -@Table("CITY") -public class City { - - @Id - private Long id; - - private String name; - - private String state; - - private String country; - - private String map; - - protected City() { - } - - public City(String name, String country) { - this.name = name; - this.country = country; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/city/CityRepository.java deleted file mode 100644 index 0447161257b6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/city/CityRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.jdbc.city; - -import org.springframework.data.repository.CrudRepository; - -public interface CityRepository extends CrudRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/city/City.java deleted file mode 100644 index 765346f4cea9..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/city/City.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.jpa.city; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; - -@Entity -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String state; - - @Column(nullable = false) - private String country; - - @Column(nullable = false) - private String map; - - protected City() { - } - - public City(String name, String country) { - this.name = name; - this.country = country; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/city/CityRepository.java deleted file mode 100644 index 38a64c6240d0..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/city/CityRepository.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.jpa.city; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface CityRepository extends JpaRepository { - - @Override - Page findAll(Pageable pageable); - - Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); - - City findByNameAndCountryAllIgnoringCase(String name, String country); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/country/Country.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/country/Country.java deleted file mode 100644 index a26ff83e6e35..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/country/Country.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.jpa.country; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import org.hibernate.envers.Audited; - -@Entity -public class Country implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Audited - @Column - private String name; - - public Long getId() { - return this.id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/country/CountryRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/country/CountryRepository.java deleted file mode 100644 index 84ceb68cd2e8..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/country/CountryRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.jpa.country; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.repository.history.RevisionRepository; - -public interface CountryRepository extends JpaRepository, RevisionRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MixedMongoRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MixedMongoRepositoriesAutoConfigurationTests.java deleted file mode 100644 index 74a32f0d49b8..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MixedMongoRepositoriesAutoConfigurationTests.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.mongo; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.data.jpa.city.City; -import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository; -import org.springframework.boot.autoconfigure.data.mongo.country.Country; -import org.springframework.boot.autoconfigure.data.mongo.country.CountryRepository; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.ImportSelector; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; -import org.springframework.util.StringUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MongoRepositoriesAutoConfiguration}. - * - * @author Dave Syer - * @author Oliver Gierke - */ -class MixedMongoRepositoriesAutoConfigurationTests { - - private AnnotationConfigApplicationContext context; - - @AfterEach - void close() { - this.context.close(); - } - - @Test - void testDefaultRepositoryConfiguration() { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(TestConfiguration.class, BaseConfiguration.class); - this.context.refresh(); - assertThat(this.context.getBean(CountryRepository.class)).isNotNull(); - } - - @Test - void testMixedRepositoryConfiguration() { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(MixedConfiguration.class, BaseConfiguration.class); - this.context.refresh(); - assertThat(this.context.getBean(CountryRepository.class)).isNotNull(); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - } - - @Test - void testJpaRepositoryConfigurationWithMongoTemplate() { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(JpaConfiguration.class, BaseConfiguration.class); - this.context.refresh(); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - } - - @Test - void testJpaRepositoryConfigurationWithMongoOverlap() { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(OverlapConfiguration.class, BaseConfiguration.class); - this.context.refresh(); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - } - - @Test - void testJpaRepositoryConfigurationWithMongoOverlapDisabled() { - this.context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.data.mongodb.repositories.type:none").applyTo(this.context); - this.context.register(OverlapConfiguration.class, BaseConfiguration.class); - this.context.refresh(); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(MongoAutoConfiguration.class) - // Not this package or its parent - @EnableMongoRepositories(basePackageClasses = Country.class) - static class TestConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(MongoAutoConfiguration.class) - @EnableMongoRepositories(basePackageClasses = Country.class) - @EntityScan(basePackageClasses = City.class) - @EnableJpaRepositories(basePackageClasses = CityRepository.class) - static class MixedConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(MongoAutoConfiguration.class) - @EntityScan(basePackageClasses = City.class) - @EnableJpaRepositories(basePackageClasses = CityRepository.class) - static class JpaConfiguration { - - } - - // In this one the Jpa repositories and the auto-configuration packages overlap, so - // Mongo will try and configure the same repositories - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(CityRepository.class) - @EnableJpaRepositories(basePackageClasses = CityRepository.class) - static class OverlapConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @Import(Registrar.class) - static class BaseConfiguration { - - } - - static class Registrar implements ImportSelector { - - @Override - public String[] selectImports(AnnotationMetadata importingClassMetadata) { - List names = new ArrayList<>(); - for (Class type : new Class[] { DataSourceAutoConfiguration.class, - HibernateJpaAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, - MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, - MongoRepositoriesAutoConfiguration.class }) { - names.add(type.getName()); - } - return StringUtils.toStringArray(names); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/City.java deleted file mode 100644 index b9c2b3c5f07d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/City.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.mongo.city; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; - -import org.springframework.data.mongodb.core.mapping.Document; - -@Document -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String state; - - @Column(nullable = false) - private String country; - - @Column(nullable = false) - private String map; - - protected City() { - } - - public City(String name, String country) { - this.name = name; - this.country = country; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/CityRepository.java deleted file mode 100644 index 4041c5e0fb86..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/CityRepository.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.mongo.city; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.Repository; - -public interface CityRepository extends Repository { - - Page findAll(Pageable pageable); - - Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); - - City findByNameAndCountryAllIgnoringCase(String name, String country); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/ReactiveCityRepository.java deleted file mode 100644 index 8921e25d2726..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/ReactiveCityRepository.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.mongo.city; - -import reactor.core.publisher.Flux; - -import org.springframework.data.repository.Repository; - -public interface ReactiveCityRepository extends Repository { - - Flux findAll(); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/country/Country.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/country/Country.java deleted file mode 100644 index 21cff51ec449..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/country/Country.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.mongo.country; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; - -import org.springframework.data.mongodb.core.mapping.Document; - -@Document -public class Country implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Column(nullable = false) - private String name; - - protected Country() { - } - - public Country(String name) { - this.name = name; - } - - public String getName() { - return this.name; - } - - @Override - public String toString() { - return getName(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/country/CountryRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/country/CountryRepository.java deleted file mode 100644 index d219ddb91c8a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/country/CountryRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.mongo.country; - -import org.springframework.data.repository.Repository; - -public interface CountryRepository extends Repository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java deleted file mode 100644 index e5bb0496591c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MixedNeo4jRepositoriesAutoConfigurationTests.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.neo4j.driver.Config; -import org.neo4j.driver.Driver; -import org.neo4j.driver.GraphDatabase; -import org.neo4j.driver.internal.logging.Slf4jLogging; - -import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.data.jpa.city.City; -import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository; -import org.springframework.boot.autoconfigure.data.neo4j.country.Country; -import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository; -import org.springframework.boot.autoconfigure.data.neo4j.empty.EmptyMarker; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.data.neo4j.config.AbstractNeo4jConfig; -import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link Neo4jRepositoriesAutoConfiguration}. - * - * @author Dave Syer - * @author Oliver Gierke - * @author Michael Hunger - * @author Vince Bickers - * @author Stephane Nicoll - * @author Michael J. Simons - */ -class MixedNeo4jRepositoriesAutoConfigurationTests { - - private AnnotationConfigApplicationContext context; - - @AfterEach - void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - void testDefaultRepositoryConfiguration() { - load(TestConfiguration.class); - assertThat(this.context.getBean(CountryRepository.class)).isNotNull(); - } - - @Test - void testMixedRepositoryConfiguration() { - load(MixedConfiguration.class); - assertThat(this.context.getBean(CountryRepository.class)).isNotNull(); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - } - - @Test - void testJpaRepositoryConfigurationWithNeo4jTemplate() { - load(JpaConfiguration.class); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - } - - @Test - @Disabled - void testJpaRepositoryConfigurationWithNeo4jOverlap() { - load(OverlapConfiguration.class); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - } - - @Test - void testJpaRepositoryConfigurationWithNeo4jOverlapDisabled() { - load(OverlapConfiguration.class, "spring.data.neo4j.repositories.enabled:false"); - assertThat(this.context.getBean(CityRepository.class)).isNotNull(); - } - - private void load(Class config, String... environment) { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of(environment).applyTo(context); - context.register(config); - context.register(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, - JpaRepositoriesAutoConfiguration.class, Neo4jDataAutoConfiguration.class, - Neo4jReactiveDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, - Neo4jReactiveRepositoriesAutoConfiguration.class); - context.refresh(); - this.context = context; - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(EmptyMarker.class) - // Not this package or its parent - @EnableNeo4jRepositories(basePackageClasses = Country.class) - static class TestConfiguration extends AbstractNeo4jConfig { - - @Override - @Bean - public Driver driver() { - return GraphDatabase.driver("bolt://neo4j.test:7687", - Config.builder().withLogging(new Slf4jLogging()).build()); - } - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(EmptyMarker.class) - @EnableNeo4jRepositories(basePackageClasses = Country.class) - @EntityScan(basePackageClasses = City.class) - @EnableJpaRepositories(basePackageClasses = CityRepository.class) - static class MixedConfiguration extends AbstractNeo4jConfig { - - @Override - @Bean - public Driver driver() { - return GraphDatabase.driver("bolt://neo4j.test:7687", - Config.builder().withLogging(new Slf4jLogging()).build()); - } - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(EmptyMarker.class) - @EntityScan(basePackageClasses = City.class) - @EnableJpaRepositories(basePackageClasses = CityRepository.class) - static class JpaConfiguration { - - } - - // In this one the Jpa repositories and the auto-configuration packages overlap, so - // Neo4j will try and configure the same repositories - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(CityRepository.class) - @EnableJpaRepositories(basePackageClasses = CityRepository.class) - static class OverlapConfiguration { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java deleted file mode 100644 index afeccc140173..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/City.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j.city; - -import java.io.Serializable; - -import org.springframework.boot.autoconfigure.data.neo4j.country.Country; -import org.springframework.data.neo4j.core.schema.GeneratedValue; -import org.springframework.data.neo4j.core.schema.Id; -import org.springframework.data.neo4j.core.schema.Node; - -@Node -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - private final String name; - - private String state; - - private final Country country; - - private String map; - - public City(String name, Country country) { - this.name = name; - this.country = country; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public Country getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/CityRepository.java deleted file mode 100644 index dcf4af9dd905..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/CityRepository.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j.city; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.neo4j.repository.Neo4jRepository; - -public interface CityRepository extends Neo4jRepository { - - @Override - Page findAll(Pageable pageable); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/ReactiveCityRepository.java deleted file mode 100644 index 54228f055dc6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/city/ReactiveCityRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j.city; - -import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; - -public interface ReactiveCityRepository extends ReactiveNeo4jRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java deleted file mode 100644 index e95b98de7725..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/Country.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j.country; - -import java.io.Serializable; - -import org.springframework.data.neo4j.core.schema.GeneratedValue; -import org.springframework.data.neo4j.core.schema.Id; -import org.springframework.data.neo4j.core.schema.Node; - -@Node -public class Country implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - private final String name; - - public Country(String name) { - this.name = name; - } - - public String getName() { - return this.name; - } - - @Override - public String toString() { - return getName(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/CountryRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/CountryRepository.java deleted file mode 100644 index 72745fa5e4ce..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/CountryRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j.country; - -import org.springframework.data.neo4j.repository.Neo4jRepository; - -public interface CountryRepository extends Neo4jRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/empty/EmptyMarker.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/empty/EmptyMarker.java deleted file mode 100644 index b616345c6e64..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/empty/EmptyMarker.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.neo4j.empty; - -public class EmptyMarker { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/city/City.java deleted file mode 100644 index 2bc0c3b770c3..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/city/City.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.r2dbc.city; - -import org.springframework.data.annotation.Id; -import org.springframework.data.relational.core.mapping.Table; - -@Table("CITY") -public class City { - - @Id - private Long id; - - private String name; - - private String state; - - private String country; - - private String map; - - protected City() { - } - - public City(String name, String country) { - this.name = name; - this.country = country; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/city/CityRepository.java deleted file mode 100644 index 7f7709326f4f..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/city/CityRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.r2dbc.city; - -import org.springframework.data.repository.reactive.ReactiveCrudRepository; - -public interface CityRepository extends ReactiveCrudRepository { - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/city/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/city/City.java deleted file mode 100644 index dcd6b4f2cb97..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/city/City.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.redis.city; - -import java.io.Serializable; - -import org.springframework.data.annotation.Id; -import org.springframework.data.redis.core.RedisHash; - -@RedisHash("cities") -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - private Long id; - - private String name; - - private String state; - - private String country; - - private String map; - - protected City() { - } - - public City(String name, String country) { - this.name = name; - this.country = country; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/city/CityRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/city/CityRepository.java deleted file mode 100644 index 08550f83e22a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/city/CityRepository.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.redis.city; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.Repository; - -public interface CityRepository extends Repository { - - Page findAll(Pageable pageable); - - Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); - - City findByNameAndCountryAllIgnoringCase(String name, String country); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfigurationJpaTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfigurationJpaTests.java deleted file mode 100644 index 179f2bc96827..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfigurationJpaTests.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.data.web; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.data.jpa.city.City; -import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.geo.Distance; -import org.springframework.data.web.PageableHandlerMethodArgumentResolver; -import org.springframework.data.web.SortHandlerMethodArgumentResolver; -import org.springframework.format.support.FormattingConversionService; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SpringDataWebAutoConfiguration} and - * {@link JpaRepositoriesAutoConfiguration}. - * - * @author Dave Syer - * @author Stephane Nicoll - */ -class SpringDataWebAutoConfigurationJpaTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, - JpaRepositoriesAutoConfiguration.class, SpringDataWebAutoConfiguration.class)) - .withPropertyValues("spring.datasource.generate-unique-name=true"); - - @Test - void springDataWebIsConfiguredWithJpaRepositories() { - this.contextRunner.withUserConfiguration(TestConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(CityRepository.class); - assertThat(context).hasSingleBean(PageableHandlerMethodArgumentResolver.class); - assertThat(context).hasSingleBean(SortHandlerMethodArgumentResolver.class); - assertThat(context.getBean(FormattingConversionService.class).canConvert(String.class, Distance.class)) - .isTrue(); - }); - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(City.class) - @EnableWebMvc - static class TestConfiguration { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfigurationTests.java deleted file mode 100644 index 6bbf65e57de2..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ReactiveElasticsearchClientAutoConfigurationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.elasticsearch; - -import org.elasticsearch.client.RestClient; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ReactiveElasticsearchClientAutoConfiguration}. - * - * @author Brian Clozel - * @author Andy Wilkinson - */ -class ReactiveElasticsearchClientAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ReactiveElasticsearchClientAutoConfiguration.class)); - - @Test - void configureWithoutRestClientShouldBackOff() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ReactiveElasticsearchClient.class)); - } - - @Test - void configureWithRestClientShouldCreateTransportAndClient() { - this.contextRunner.withUserConfiguration(RestClientConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchClient.class)); - } - - @Test - void configureWhenCustomClientShouldBackOff() { - this.contextRunner.withUserConfiguration(RestClientConfiguration.class, CustomClientConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchClient.class) - .hasBean("customClient")); - } - - @Configuration(proxyBeanMethods = false) - static class RestClientConfiguration { - - @Bean - RestClient restClient() { - return mock(RestClient.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomClientConfiguration { - - @Bean - ReactiveElasticsearchClient customClient() { - return mock(ReactiveElasticsearchClient.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/Gson210AutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/Gson210AutoConfigurationTests.java deleted file mode 100644 index 5f614e046ad0..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/Gson210AutoConfigurationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.gson; - -import com.google.gson.Gson; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.boot.testsupport.classpath.ClassPathOverrides; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link GsonAutoConfiguration} with Gson 2.10. - * - * @author Andy Wilkinson - */ -@ClassPathExclusions("gson-*.jar") -@ClassPathOverrides("com.google.code.gson:gson:2.10") -class Gson210AutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(GsonAutoConfiguration.class)); - - @Test - void gsonRegistration() { - this.contextRunner.run((context) -> { - Gson gson = context.getBean(Gson.class); - assertThat(gson.toJson(new DataObject())).isEqualTo("{\"data\":1}"); - }); - } - - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void withoutLenient() { - this.contextRunner.run((context) -> { - Gson gson = context.getBean(Gson.class); - assertThat(gson).hasFieldOrPropertyWithValue("lenient", false); - }); - } - - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void withLenientTrue() { - this.contextRunner.withPropertyValues("spring.gson.lenient:true").run((context) -> { - Gson gson = context.getBean(Gson.class); - assertThat(gson).hasFieldOrPropertyWithValue("lenient", true); - }); - } - - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void withLenientFalse() { - this.contextRunner.withPropertyValues("spring.gson.lenient:false").run((context) -> { - Gson gson = context.getBean(Gson.class); - assertThat(gson).hasFieldOrPropertyWithValue("lenient", false); - }); - } - - public class DataObject { - - @SuppressWarnings("unused") - private Long data = 1L; - - @SuppressWarnings("unused") - private final String owner = null; - - public void setData(Long data) { - this.data = data; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactoriesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactoriesTests.java deleted file mode 100644 index 7d226a2ad5da..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactoriesTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.boot.autoconfigure.http.client.AbstractHttpRequestFactoryProperties.Factory; -import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; -import org.springframework.boot.http.client.HttpComponentsClientHttpRequestFactoryBuilder; -import org.springframework.boot.http.client.HttpRedirects; -import org.springframework.boot.http.client.JettyClientHttpRequestFactoryBuilder; -import org.springframework.boot.ssl.DefaultSslBundleRegistry; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslBundles; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ClientHttpRequestFactories} - * - * @author Phillip Webb - */ -class ClientHttpRequestFactoriesTests { - - private final DefaultSslBundleRegistry bundleRegistry = new DefaultSslBundleRegistry(); - - private ObjectFactory sslBundles = () -> this.bundleRegistry; - - @Test - void builderWhenHasFactoryPropertyReturnsFirst() { - TestProperties p1 = new TestProperties(); - TestProperties p2 = new TestProperties(); - p2.setFactory(Factory.JETTY); - TestProperties p3 = new TestProperties(); - p3.setFactory(Factory.REACTOR); - ClientHttpRequestFactories factories = new ClientHttpRequestFactories(this.sslBundles, p1, p2, p3); - assertThat(factories.builder(null)).isInstanceOf(JettyClientHttpRequestFactoryBuilder.class); - } - - @Test - void buildWhenHasNoFactoryPropertyReturnsDetected() { - TestProperties properties = new TestProperties(); - ClientHttpRequestFactories factories = new ClientHttpRequestFactories(this.sslBundles, properties); - assertThat(factories.builder(null)).isInstanceOf(HttpComponentsClientHttpRequestFactoryBuilder.class); - } - - @Test - void settingsWhenHasNoSettingProperties() { - TestProperties properties = new TestProperties(); - ClientHttpRequestFactories factories = new ClientHttpRequestFactories(this.sslBundles, properties); - ClientHttpRequestFactorySettings settings = factories.settings(); - assertThat(settings).isEqualTo(new ClientHttpRequestFactorySettings(null, null, null, null)); - } - - @Test - void settingsWhenHasMultipleSettingProperties() { - this.bundleRegistry.registerBundle("p2", mock(SslBundle.class)); - this.bundleRegistry.registerBundle("p3", mock(SslBundle.class)); - TestProperties p1 = new TestProperties(); - TestProperties p2 = new TestProperties(); - p2.setRedirects(HttpRedirects.DONT_FOLLOW); - p2.setConnectTimeout(Duration.ofSeconds(1)); - p2.setReadTimeout(Duration.ofSeconds(2)); - p2.getSsl().setBundle("p2"); - TestProperties p3 = new TestProperties(); - p3.setRedirects(HttpRedirects.FOLLOW); - p3.setConnectTimeout(Duration.ofSeconds(10)); - p3.setReadTimeout(Duration.ofSeconds(20)); - p3.getSsl().setBundle("p3"); - ClientHttpRequestFactories factories = new ClientHttpRequestFactories(this.sslBundles, p1, p2, p3); - ClientHttpRequestFactorySettings settings = factories.settings(); - assertThat(settings).isEqualTo(new ClientHttpRequestFactorySettings(HttpRedirects.DONT_FOLLOW, - Duration.ofSeconds(1), Duration.ofSeconds(2), this.bundleRegistry.getBundle("p2"))); - } - - static class TestProperties extends AbstractHttpRequestFactoryProperties { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfigurationTests.java deleted file mode 100644 index a3af3b6cfe69..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorAutoConfigurationTests.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.client.reactive; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import org.apache.hc.client5.http.impl.async.HttpAsyncClients; -import org.junit.jupiter.api.Test; -import reactor.netty.http.client.HttpClient; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; -import org.springframework.boot.http.client.HttpRedirects; -import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; -import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; -import org.springframework.boot.http.client.reactive.JdkClientHttpConnectorBuilder; -import org.springframework.boot.http.client.reactive.JettyClientHttpConnectorBuilder; -import org.springframework.boot.http.client.reactive.ReactorClientHttpConnectorBuilder; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.ReactorResourceFactory; -import org.springframework.http.client.reactive.ClientHttpConnector; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ClientHttpConnectorAutoConfiguration} - * - * @author Brian Clozel - * @author Phillip Webb - */ -class ClientHttpConnectorAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(ClientHttpConnectorAutoConfiguration.class, SslAutoConfiguration.class)); - - @Test - void whenReactorIsAvailableThenReactorBeansAreDefined() { - this.contextRunner.run((context) -> { - BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("clientHttpConnector"); - assertThat(connectorDefinition.isLazyInit()).isTrue(); - assertThat(context).hasSingleBean(ReactorResourceFactory.class); - assertThat(context.getBean(ClientHttpConnectorBuilder.class)) - .isExactlyInstanceOf(ReactorClientHttpConnectorBuilder.class); - }); - } - - @Test - void whenReactorIsUnavailableThenJettyClientBeansAreDefined() { - this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class)).run((context) -> { - BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("clientHttpConnector"); - assertThat(connectorDefinition.isLazyInit()).isTrue(); - assertThat(context.getBean(ClientHttpConnectorBuilder.class)) - .isExactlyInstanceOf(JettyClientHttpConnectorBuilder.class); - }); - } - - @Test - void whenReactorAndHttpClientAreUnavailableThenJettyClientBeansAreDefined() { - this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class, HttpAsyncClients.class)) - .run((context) -> { - BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("clientHttpConnector"); - assertThat(connectorDefinition.isLazyInit()).isTrue(); - assertThat(context.getBean(ClientHttpConnectorBuilder.class)) - .isExactlyInstanceOf(JettyClientHttpConnectorBuilder.class); - }); - } - - @Test - void whenReactorAndHttpClientAndJettyAreUnavailableThenJdkClientBeansAreDefined() { - this.contextRunner - .withClassLoader(new FilteredClassLoader(HttpClient.class, HttpAsyncClients.class, - org.eclipse.jetty.client.HttpClient.class)) - .run((context) -> { - BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("clientHttpConnector"); - assertThat(connectorDefinition.isLazyInit()).isTrue(); - assertThat(context.getBean(ClientHttpConnectorBuilder.class)) - .isExactlyInstanceOf(JdkClientHttpConnectorBuilder.class); - }); - } - - @Test - void shouldNotOverrideCustomClientConnector() { - this.contextRunner.withUserConfiguration(CustomClientHttpConnectorConfig.class).run((context) -> { - assertThat(context).hasSingleBean(ClientHttpConnector.class); - assertThat(context).hasBean("customConnector"); - }); - } - - @Test - void shouldUseCustomReactorResourceFactory() { - this.contextRunner.withUserConfiguration(CustomReactorResourceConfig.class).run((context) -> { - assertThat(context).hasSingleBean(ClientHttpConnector.class); - assertThat(context).hasSingleBean(ReactorResourceFactory.class); - assertThat(context).hasBean("customReactorResourceFactory"); - }); - } - - @Test - void configuresDetectedClientHttpConnectorBuilderBuilder() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ClientHttpConnectorBuilder.class)); - } - - @Test - void configuresDefinedClientHttpConnectorBuilder() { - this.contextRunner.withPropertyValues("spring.http.reactiveclient.connector=jetty") - .run((context) -> assertThat(context.getBean(ClientHttpConnectorBuilder.class)) - .isInstanceOf(JettyClientHttpConnectorBuilder.class)); - } - - @Test - void configuresClientHttpConnectorSettings() { - this.contextRunner.withPropertyValues(sslPropertyValues().toArray(String[]::new)) - .withPropertyValues("spring.http.reactiveclient.redirects=dont-follow", - "spring.http.reactiveclient.connect-timeout=10s", "spring.http.reactiveclient.read-timeout=20s", - "spring.http.reactiveclient.ssl.bundle=test") - .run((context) -> { - ClientHttpConnectorSettings settings = context.getBean(ClientHttpConnectorSettings.class); - assertThat(settings.redirects()).isEqualTo(HttpRedirects.DONT_FOLLOW); - assertThat(settings.connectTimeout()).isEqualTo(Duration.ofSeconds(10)); - assertThat(settings.readTimeout()).isEqualTo(Duration.ofSeconds(20)); - assertThat(settings.sslBundle().getKey().getAlias()).isEqualTo("alias1"); - }); - } - - @Test - void shouldBeConditionalOnAtLeastOneHttpConnectorClass() { - FilteredClassLoader classLoader = new FilteredClassLoader(reactor.netty.http.client.HttpClient.class, - org.eclipse.jetty.client.HttpClient.class, org.apache.hc.client5.http.impl.async.HttpAsyncClients.class, - java.net.http.HttpClient.class); - assertThatIllegalStateException().as("enough filtering") - .isThrownBy(() -> ClientHttpConnectorBuilder.detect(classLoader)); - this.contextRunner.withClassLoader(classLoader) - .run((context) -> assertThat(context).doesNotHaveBean(ClientHttpConnectorSettings.class)); - } - - private List sslPropertyValues() { - List propertyValues = new ArrayList<>(); - String location = "classpath:org/springframework/boot/autoconfigure/ssl/"; - propertyValues.add("spring.ssl.bundle.pem.test.key.alias=alias1"); - propertyValues.add("spring.ssl.bundle.pem.test.truststore.type=PKCS12"); - propertyValues.add("spring.ssl.bundle.pem.test.truststore.certificate=" + location + "rsa-cert.pem"); - propertyValues.add("spring.ssl.bundle.pem.test.truststore.private-key=" + location + "rsa-key.pem"); - return propertyValues; - } - - @Test - void clientHttpConnectorBuilderCustomizersAreApplied() { - this.contextRunner.withPropertyValues("spring.http.reactiveclient.connector=jdk") - .withUserConfiguration(ClientHttpConnectorBuilderCustomizersConfiguration.class) - .run((context) -> { - ClientHttpConnector connector = context.getBean(ClientHttpConnectorBuilder.class).build(); - assertThat(connector).extracting("readTimeout").isEqualTo(Duration.ofSeconds(5)); - }); - } - - @Configuration(proxyBeanMethods = false) - static class CustomClientHttpConnectorConfig { - - @Bean - ClientHttpConnector customConnector() { - return mock(ClientHttpConnector.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomReactorResourceConfig { - - @Bean - ReactorResourceFactory customReactorResourceFactory() { - return new ReactorResourceFactory(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ClientHttpConnectorBuilderCustomizersConfiguration { - - @Bean - ClientHttpConnectorBuilderCustomizer jdkCustomizer() { - return (builder) -> builder.withCustomizer((connector) -> connector.setReadTimeout(Duration.ofSeconds(5))); - } - - @Bean - ClientHttpConnectorBuilderCustomizer jettyCustomizer() { - return (builder) -> { - throw new IllegalStateException(); - }; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfigurationTests.java deleted file mode 100644 index ef66b2c4a91a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfigurationTests.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.http.codec; - -import java.util.List; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.codec.CodecCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.http.codec.CodecConfigurer; -import org.springframework.http.codec.CodecConfigurer.DefaultCodecs; -import org.springframework.http.codec.support.DefaultClientCodecConfigurer; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link CodecsAutoConfiguration}. - * - * @author Madhura Bhave - * @author Andy Wilkinson - */ -class CodecsAutoConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(CodecsAutoConfiguration.class)); - - @Test - void autoConfigShouldProvideALoggingRequestDetailsCustomizer() { - this.contextRunner.run((context) -> assertThat(defaultCodecs(context)) - .hasFieldOrPropertyWithValue("enableLoggingRequestDetails", false)); - } - - @Test - void loggingRequestDetailsCustomizerShouldUseCodecProperties() { - this.contextRunner.withPropertyValues("spring.codec.log-request-details=true") - .run((context) -> assertThat(defaultCodecs(context)) - .hasFieldOrPropertyWithValue("enableLoggingRequestDetails", true)); - } - - @Test - void loggingRequestDetailsCustomizerShouldUseHttpCodecsProperties() { - this.contextRunner.withPropertyValues("spring.http.codecs.log-request-details=true") - .run((context) -> assertThat(defaultCodecs(context)) - .hasFieldOrPropertyWithValue("enableLoggingRequestDetails", true)); - } - - @Test - void logRequestDetailsShouldGivePriorityToHttpCodecProperty() { - this.contextRunner - .withPropertyValues("spring.http.codecs.log-request-details=true", "spring.codec.log-request-details=false") - .run((context) -> assertThat(defaultCodecs(context)) - .hasFieldOrPropertyWithValue("enableLoggingRequestDetails", true)); - } - - @Test - void maxInMemorySizeShouldUseCodecProperties() { - this.contextRunner.withPropertyValues("spring.codec.max-in-memory-size=64KB") - .run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize", - 64 * 1024)); - } - - @Test - void maxInMemorySizeShouldUseHttpCodecProperties() { - this.contextRunner.withPropertyValues("spring.http.codecs.max-in-memory-size=64KB") - .run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize", - 64 * 1024)); - } - - @Test - void maxInMemorySizeShouldGivePriorityToHttpCodecProperty() { - this.contextRunner - .withPropertyValues("spring.http.codecs.max-in-memory-size=64KB", "spring.codec.max-in-memory-size=32KB") - .run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize", - 64 * 1024)); - } - - @Test - void defaultCodecCustomizerBeanShouldHaveOrderZero() { - this.contextRunner - .run((context) -> assertThat(context.getBean("defaultCodecCustomizer", Ordered.class).getOrder()).isZero()); - } - - @Test - void jacksonCodecCustomizerBacksOffWhenThereIsNoObjectMapper() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean("jacksonCodecCustomizer")); - } - - @Test - void jacksonCodecCustomizerIsAutoConfiguredWhenObjectMapperIsPresent() { - this.contextRunner.withUserConfiguration(ObjectMapperConfiguration.class) - .run((context) -> assertThat(context).hasBean("jacksonCodecCustomizer")); - } - - @Test - void userProvidedCustomizerCanOverrideJacksonCodecCustomizer() { - this.contextRunner.withUserConfiguration(ObjectMapperConfiguration.class, CodecCustomizerConfiguration.class) - .run((context) -> { - List codecCustomizers = context.getBean(CodecCustomizers.class).codecCustomizers; - assertThat(codecCustomizers).hasSize(3); - assertThat(codecCustomizers.get(2)).isInstanceOf(TestCodecCustomizer.class); - }); - } - - @Test - void maxInMemorySizeEnforcedInDefaultCodecs() { - this.contextRunner.withPropertyValues("spring.codec.max-in-memory-size=1MB") - .run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize", - 1048576)); - } - - private DefaultCodecs defaultCodecs(AssertableWebApplicationContext context) { - CodecCustomizer customizer = context.getBean(CodecCustomizer.class); - CodecConfigurer configurer = new DefaultClientCodecConfigurer(); - customizer.customize(configurer); - return configurer.defaultCodecs(); - } - - @Configuration(proxyBeanMethods = false) - static class ObjectMapperConfiguration { - - @Bean - ObjectMapper objectMapper() { - return new ObjectMapper(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CodecCustomizerConfiguration { - - @Bean - CodecCustomizer codecCustomizer() { - return new TestCodecCustomizer(); - } - - @Bean - CodecCustomizers codecCustomizers(List customizers) { - return new CodecCustomizers(customizers); - } - - } - - private static final class TestCodecCustomizer implements CodecCustomizer { - - @Override - public void customize(CodecConfigurer configurer) { - } - - } - - private static final class CodecCustomizers { - - private final List codecCustomizers; - - private CodecCustomizers(List codecCustomizers) { - this.codecCustomizers = codecCustomizers; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcClientAutoConfigurationTests.java deleted file mode 100644 index 87fdacda271d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcClientAutoConfigurationTests.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.jdbc; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.core.simple.JdbcClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link JdbcClientAutoConfiguration}. - * - * @author Stephane Nicoll - */ -class JdbcClientAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.datasource.generate-unique-name=true") - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, - JdbcClientAutoConfiguration.class)); - - @Test - void jdbcClientWhenNoAvailableJdbcTemplateIsNotCreated() { - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class, JdbcClientAutoConfiguration.class)) - .run((context) -> assertThat(context).doesNotHaveBean(JdbcClient.class)); - } - - @Test - void jdbcClientWhenExistingJdbcTemplateIsCreated() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(JdbcClient.class); - NamedParameterJdbcTemplate namedParameterJdbcTemplate = context.getBean(NamedParameterJdbcTemplate.class); - assertThat(namedParameterJdbcTemplate.getJdbcOperations()).isEqualTo(context.getBean(JdbcOperations.class)); - }); - } - - @Test - void jdbcClientWithCustomJdbcClientIsNotCreated() { - this.contextRunner.withBean("customJdbcClient", JdbcClient.class, () -> mock(JdbcClient.class)) - .run((context) -> { - assertThat(context).hasSingleBean(JdbcClient.class); - assertThat(context.getBean(JdbcClient.class)).isEqualTo(context.getBean("customJdbcClient")); - }); - } - - @Test - @WithResource(name = "db/city/V1__init.sql", content = """ - CREATE SEQUENCE city_seq INCREMENT BY 50; - CREATE TABLE CITY ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY, - name VARCHAR(30), - state VARCHAR(30), - country VARCHAR(30), - map VARCHAR(30) - ); - """) - void jdbcClientIsOrderedAfterFlywayMigration() { - this.contextRunner.withUserConfiguration(JdbcClientDataSourceMigrationValidator.class) - .withPropertyValues("spring.flyway.locations:classpath:db/city") - .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasNotFailed().hasSingleBean(JdbcClient.class); - assertThat(context.getBean(JdbcClientDataSourceMigrationValidator.class).count).isZero(); - }); - } - - @Test - @WithResource(name = "db/changelog/db.changelog-city.yaml", content = """ - databaseChangeLog: - - changeSet: - id: 1 - author: dsyer - changes: - - createSequence: - sequenceName: city_seq - incrementBy: 50 - - createTable: - tableName: city - columns: - - column: - name: id - type: bigint - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: name - type: varchar(50) - constraints: - nullable: false - """) - void jdbcClientIsOrderedAfterLiquibaseMigration() { - this.contextRunner.withUserConfiguration(JdbcClientDataSourceMigrationValidator.class) - .withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml") - .withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasNotFailed().hasSingleBean(JdbcClient.class); - assertThat(context.getBean(JdbcClientDataSourceMigrationValidator.class).count).isZero(); - }); - } - - static class JdbcClientDataSourceMigrationValidator { - - private final Long count; - - JdbcClientDataSourceMigrationValidator(JdbcClient jdbcClient) { - this.count = jdbcClient.sql("SELECT COUNT(*) from CITY").query(Long.class).single(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfigurationTests.java deleted file mode 100644 index 13f4e766af7d..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfigurationTests.java +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.jdbc; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Collections; - -import javax.sql.DataSource; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.support.SQLExceptionTranslator; -import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link JdbcTemplateAutoConfiguration}. - * - * @author Dave Syer - * @author Stephane Nicoll - * @author Kazuki Shimizu - * @author Dan Zheng - */ -class JdbcTemplateAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.datasource.generate-unique-name=true") - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class)); - - @Test - void testJdbcTemplateExists() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(JdbcOperations.class); - JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); - assertThat(jdbcTemplate.getDataSource()).isEqualTo(context.getBean(DataSource.class)); - assertThat(jdbcTemplate.isIgnoreWarnings()).isEqualTo(true); - assertThat(jdbcTemplate.getFetchSize()).isEqualTo(-1); - assertThat(jdbcTemplate.getQueryTimeout()).isEqualTo(-1); - assertThat(jdbcTemplate.getMaxRows()).isEqualTo(-1); - assertThat(jdbcTemplate.isSkipResultsProcessing()).isEqualTo(false); - assertThat(jdbcTemplate.isSkipUndeclaredResults()).isEqualTo(false); - assertThat(jdbcTemplate.isResultsMapCaseInsensitive()).isEqualTo(false); - }); - } - - @Test - void testJdbcTemplateWithCustomProperties() { - this.contextRunner - .withPropertyValues("spring.jdbc.template.ignore-warnings:false", "spring.jdbc.template.fetch-size:100", - "spring.jdbc.template.query-timeout:60", "spring.jdbc.template.max-rows:1000", - "spring.jdbc.template.skip-results-processing:true", - "spring.jdbc.template.skip-undeclared-results:true", - "spring.jdbc.template.results-map-case-insensitive:true") - .run((context) -> { - assertThat(context).hasSingleBean(JdbcOperations.class); - JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); - assertThat(jdbcTemplate.getDataSource()).isNotNull(); - assertThat(jdbcTemplate.isIgnoreWarnings()).isEqualTo(false); - assertThat(jdbcTemplate.getFetchSize()).isEqualTo(100); - assertThat(jdbcTemplate.getQueryTimeout()).isEqualTo(60); - assertThat(jdbcTemplate.getMaxRows()).isEqualTo(1000); - assertThat(jdbcTemplate.isSkipResultsProcessing()).isEqualTo(true); - assertThat(jdbcTemplate.isSkipUndeclaredResults()).isEqualTo(true); - assertThat(jdbcTemplate.isResultsMapCaseInsensitive()).isEqualTo(true); - }); - } - - @Test - void testJdbcTemplateExistsWithCustomDataSource() { - this.contextRunner.withUserConfiguration(TestDataSourceConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(JdbcOperations.class); - JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); - assertThat(jdbcTemplate.getDataSource()).isEqualTo(context.getBean("customDataSource")); - }); - } - - @Test - void testNamedParameterJdbcTemplateExists() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class); - NamedParameterJdbcTemplate namedParameterJdbcTemplate = context.getBean(NamedParameterJdbcTemplate.class); - assertThat(namedParameterJdbcTemplate.getJdbcOperations()).isEqualTo(context.getBean(JdbcOperations.class)); - }); - } - - @Test - void testMultiDataSource() { - this.contextRunner.withUserConfiguration(MultiDataSourceConfiguration.class).run((context) -> { - assertThat(context).doesNotHaveBean(JdbcOperations.class); - assertThat(context).doesNotHaveBean(NamedParameterJdbcOperations.class); - }); - } - - @Test - void testMultiJdbcTemplate() { - this.contextRunner.withUserConfiguration(MultiJdbcTemplateConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(NamedParameterJdbcOperations.class)); - } - - @Test - void testMultiDataSourceUsingPrimary() { - this.contextRunner.withUserConfiguration(MultiDataSourceUsingPrimaryConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(JdbcOperations.class); - assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class); - assertThat(context.getBean(JdbcTemplate.class).getDataSource()) - .isEqualTo(context.getBean("test1DataSource")); - }); - } - - @Test - void testMultiJdbcTemplateUsingPrimary() { - this.contextRunner.withUserConfiguration(MultiJdbcTemplateUsingPrimaryConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class); - assertThat(context.getBean(NamedParameterJdbcTemplate.class).getJdbcOperations()) - .isEqualTo(context.getBean("test1Template")); - }); - } - - @Test - void testExistingCustomJdbcTemplate() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(JdbcOperations.class); - assertThat(context.getBean(JdbcOperations.class)).isEqualTo(context.getBean("customJdbcOperations")); - }); - } - - @Test - void testExistingCustomNamedParameterJdbcTemplate() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class); - assertThat(context.getBean(NamedParameterJdbcOperations.class)) - .isEqualTo(context.getBean("customNamedParameterJdbcOperations")); - }); - } - - @Test - @WithResource(name = "schema.sql", content = """ - CREATE TABLE BAR ( - id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - name VARCHAR(30) - ); - """) - @WithResource(name = "data.sql", content = "INSERT INTO BAR VALUES (1, 'Andy');") - void testDependencyToScriptBasedDataSourceInitialization() { - this.contextRunner.withConfiguration(AutoConfigurations.of(SqlInitializationAutoConfiguration.class)) - .withUserConfiguration(DataSourceInitializationValidator.class) - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context.getBean(DataSourceInitializationValidator.class).count).isOne(); - }); - } - - @Test - @WithResource(name = "db/city/V1__init.sql", content = """ - CREATE SEQUENCE city_seq INCREMENT BY 50; - CREATE TABLE CITY ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY, - name VARCHAR(30), - state VARCHAR(30), - country VARCHAR(30), - map VARCHAR(30) - ); - """) - void testDependencyToFlyway() { - this.contextRunner.withUserConfiguration(DataSourceMigrationValidator.class) - .withPropertyValues("spring.flyway.locations:classpath:db/city") - .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context.getBean(DataSourceMigrationValidator.class).count).isZero(); - }); - } - - @Test - @WithResource(name = "db/city/V1__init.sql", content = """ - CREATE SEQUENCE city_seq INCREMENT BY 50; - CREATE TABLE CITY ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY, - name VARCHAR(30), - state VARCHAR(30), - country VARCHAR(30), - map VARCHAR(30) - ); - """) - void testDependencyToFlywayWithJdbcTemplateMixed() { - this.contextRunner.withUserConfiguration(NamedParameterDataSourceMigrationValidator.class) - .withPropertyValues("spring.flyway.locations:classpath:db/city") - .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context.getBean(JdbcTemplate.class)).isNotNull(); - assertThat(context.getBean(NamedParameterDataSourceMigrationValidator.class).count).isZero(); - }); - } - - @Test - @WithDbChangelogCityYamlResource - void testDependencyToLiquibase() { - this.contextRunner.withUserConfiguration(DataSourceMigrationValidator.class) - .withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml") - .withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context.getBean(DataSourceMigrationValidator.class).count).isZero(); - }); - } - - @Test - @WithDbChangelogCityYamlResource - void testDependencyToLiquibaseWithJdbcTemplateMixed() { - this.contextRunner.withUserConfiguration(NamedParameterDataSourceMigrationValidator.class) - .withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml") - .withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context.getBean(JdbcTemplate.class)).isNotNull(); - assertThat(context.getBean(NamedParameterDataSourceMigrationValidator.class).count).isZero(); - }); - } - - @Test - void shouldConfigureJdbcTemplateWithSQLExceptionTranslatorIfPresent() { - SQLStateSQLExceptionTranslator sqlExceptionTranslator = new SQLStateSQLExceptionTranslator(); - this.contextRunner.withBean(SQLExceptionTranslator.class, () -> sqlExceptionTranslator).run((context) -> { - assertThat(context).hasSingleBean(JdbcTemplate.class); - JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); - assertThat(jdbcTemplate.getExceptionTranslator()).isSameAs(sqlExceptionTranslator); - }); - } - - @Test - void shouldNotConfigureJdbcTemplateWithSQLExceptionTranslatorIfNotUnique() { - SQLStateSQLExceptionTranslator sqlExceptionTranslator1 = new SQLStateSQLExceptionTranslator(); - SQLStateSQLExceptionTranslator sqlExceptionTranslator2 = new SQLStateSQLExceptionTranslator(); - this.contextRunner - .withBean("sqlExceptionTranslator1", SQLExceptionTranslator.class, () -> sqlExceptionTranslator1) - .withBean("sqlExceptionTranslator2", SQLExceptionTranslator.class, () -> sqlExceptionTranslator2) - .run((context) -> { - assertThat(context).hasSingleBean(JdbcTemplate.class); - JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); - assertThat(jdbcTemplate.getExceptionTranslator()).isNotSameAs(sqlExceptionTranslator1) - .isNotSameAs(sqlExceptionTranslator2); - }); - } - - @Configuration(proxyBeanMethods = false) - static class CustomConfiguration { - - @Bean - JdbcOperations customJdbcOperations(DataSource dataSource) { - return new JdbcTemplate(dataSource); - } - - @Bean - NamedParameterJdbcOperations customNamedParameterJdbcOperations(DataSource dataSource) { - return new NamedParameterJdbcTemplate(dataSource); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestDataSourceConfiguration { - - @Bean - DataSource customDataSource() { - return new TestDataSource(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MultiJdbcTemplateConfiguration { - - @Bean - JdbcTemplate test1Template() { - return mock(JdbcTemplate.class); - } - - @Bean - JdbcTemplate test2Template() { - return mock(JdbcTemplate.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MultiJdbcTemplateUsingPrimaryConfiguration { - - @Bean - @Primary - JdbcTemplate test1Template() { - return mock(JdbcTemplate.class); - } - - @Bean - JdbcTemplate test2Template() { - return mock(JdbcTemplate.class); - } - - } - - static class DataSourceInitializationValidator { - - private final Integer count; - - DataSourceInitializationValidator(JdbcTemplate jdbcTemplate) { - this.count = jdbcTemplate.queryForObject("SELECT COUNT(*) from BAR", Integer.class); - } - - } - - static class DataSourceMigrationValidator { - - private final Integer count; - - DataSourceMigrationValidator(JdbcTemplate jdbcTemplate) { - this.count = jdbcTemplate.queryForObject("SELECT COUNT(*) from CITY", Integer.class); - } - - } - - static class NamedParameterDataSourceMigrationValidator { - - private final Integer count; - - NamedParameterDataSourceMigrationValidator(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { - this.count = namedParameterJdbcTemplate.queryForObject("SELECT COUNT(*) from CITY", Collections.emptyMap(), - Integer.class); - } - - } - - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - @WithResource(name = "db/changelog/db.changelog-city.yaml", content = """ - databaseChangeLog: - - changeSet: - id: 1 - author: dsyer - changes: - - createSequence: - sequenceName: city_seq - incrementBy: 50 - - createTable: - tableName: city - columns: - - column: - name: id - type: bigint - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: name - type: varchar(50) - constraints: - nullable: false - """) - @interface WithDbChangelogCityYamlResource { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfigurationTests.java index dc9edd3ccb33..c5ced7697021 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfigurationTests.java @@ -19,14 +19,11 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; import org.springframework.boot.context.annotation.UserConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport; -import org.springframework.integration.monitor.IntegrationMBeanExporter; import org.springframework.jmx.export.MBeanExporter; import org.springframework.jmx.export.annotation.ManagedAttribute; import org.springframework.jmx.export.annotation.ManagedOperation; @@ -120,23 +117,6 @@ void testParentContext() { } } - @Test - void customJmxDomain() { - this.contextRunner.withConfiguration(UserConfigurations.of(CustomJmxDomainConfiguration.class)) - .withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, IntegrationAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasSingleBean(IntegrationMBeanExporter.class); - IntegrationMBeanExporter exporter = context.getBean(IntegrationMBeanExporter.class); - assertThat(exporter).hasFieldOrPropertyWithValue("domain", "foo.my"); - }); - } - - @Configuration(proxyBeanMethods = false) - @EnableIntegrationMBeanExport(defaultDomain = "foo.my") - static class CustomJmxDomainConfiguration { - - } - @Configuration(proxyBeanMethods = false) static class TestConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java index cb35b03ff78d..6bad90812f08 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java @@ -34,7 +34,7 @@ import org.springframework.boot.context.event.ApplicationFailedEvent; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationReactiveIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationReactiveIntegrationTests.java deleted file mode 100644 index 1088d7b6cc30..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationReactiveIntegrationTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.mustache; - -import java.util.Date; - -import com.samskivert.mustache.Mustache; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.reactive.result.view.MustacheView; -import org.springframework.boot.web.reactive.result.view.MustacheViewResolver; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Controller; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration Tests for {@link MustacheAutoConfiguration}, {@link MustacheViewResolver} - * and {@link MustacheView}. - * - * @author Brian Clozel - */ -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=reactive") -class MustacheAutoConfigurationReactiveIntegrationTests { - - @Autowired - private WebTestClient client; - - @Test - void testHomePage() { - String result = this.client.get() - .uri("/") - .exchange() - .expectStatus() - .isOk() - .expectBody(String.class) - .returnResult() - .getResponseBody(); - assertThat(result).contains("Hello App").contains("Hello World"); - } - - @Test - void testPartialPage() { - String result = this.client.get() - .uri("/partial") - .exchange() - .expectStatus() - .isOk() - .expectBody(String.class) - .returnResult() - .getResponseBody(); - assertThat(result).contains("Hello App").contains("Hello World"); - } - - @Configuration(proxyBeanMethods = false) - @Import({ ReactiveWebServerFactoryAutoConfiguration.class, WebFluxAutoConfiguration.class, - HttpHandlerAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - @Controller - static class Application { - - @RequestMapping("/") - String home(Model model) { - model.addAttribute("time", new Date()); - model.addAttribute("message", "Hello World"); - model.addAttribute("title", "Hello App"); - return "home"; - } - - @RequestMapping("/partial") - String layout(Model model) { - model.addAttribute("time", new Date()); - model.addAttribute("message", "Hello World"); - model.addAttribute("title", "Hello App"); - return "partial"; - } - - @Bean - MustacheViewResolver viewResolver() { - Mustache.Compiler compiler = Mustache.compiler() - .withLoader(new MustacheResourceTemplateLoader( - "classpath:/org/springframework/boot/autoconfigure/mustache/", ".html")); - MustacheViewResolver resolver = new MustacheViewResolver(compiler); - resolver.setPrefix("classpath:/org/springframework/boot/autoconfigure/mustache/"); - resolver.setSuffix(".html"); - return resolver; - } - - static void main(String[] args) { - SpringApplication application = new SpringApplication(Application.class); - application.setWebApplicationType(WebApplicationType.REACTIVE); - application.run(args); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationServletIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationServletIntegrationTests.java deleted file mode 100644 index a23fe4bfa538..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationServletIntegrationTests.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.mustache; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import com.samskivert.mustache.Mustache; -import com.samskivert.mustache.Template; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.view.MustacheView; -import org.springframework.boot.web.servlet.view.MustacheViewResolver; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Controller; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.web.bind.annotation.RequestMapping; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration Tests for {@link MustacheAutoConfiguration}, {@link MustacheViewResolver} - * and {@link MustacheView}. - * - * @author Dave Syer - */ -@DirtiesContext -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -class MustacheAutoConfigurationServletIntegrationTests { - - @Autowired - private ServletWebServerApplicationContext context; - - private int port; - - @BeforeEach - void init() { - this.port = this.context.getWebServer().getPort(); - } - - @Test - void contextLoads() { - String source = "Hello {{arg}}!"; - Template tmpl = Mustache.compiler().compile(source); - Map context = new HashMap<>(); - context.put("arg", "world"); - assertThat(tmpl.execute(context)).isEqualTo("Hello world!"); - } - - @Test - void testHomePage() { - String body = new TestRestTemplate().getForObject("http://localhost:" + this.port, String.class); - assertThat(body).contains("Hello World"); - } - - @Test - void testPartialPage() { - String body = new TestRestTemplate().getForObject("http://localhost:" + this.port + "/partial", String.class); - assertThat(body).contains("Hello World"); - } - - @Configuration(proxyBeanMethods = false) - @MinimalWebConfiguration - @Controller - static class Application { - - @RequestMapping("/") - String home(Map model) { - model.put("time", new Date()); - model.put("message", "Hello World"); - model.put("title", "Hello App"); - return "home"; - } - - @RequestMapping("/partial") - String layout(Map model) { - model.put("time", new Date()); - model.put("message", "Hello World"); - model.put("title", "Hello App"); - return "partial"; - } - - @Bean - MustacheViewResolver viewResolver() { - Mustache.Compiler compiler = Mustache.compiler() - .withLoader(new MustacheResourceTemplateLoader( - "classpath:/org/springframework/boot/autoconfigure/mustache/", ".html")); - MustacheViewResolver resolver = new MustacheViewResolver(compiler); - resolver.setPrefix("classpath:/org/springframework/boot/autoconfigure/mustache/"); - resolver.setSuffix(".html"); - return resolver; - } - - static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - - } - - @Target(ElementType.TYPE) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Import({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class }) - protected @interface MinimalWebConfiguration { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java deleted file mode 100644 index dc0eb346a52a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.orm.jpa; - -import java.io.File; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import javax.sql.DataSource; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.metamodel.ManagedType; -import jakarta.persistence.spi.PersistenceUnitInfo; -import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.jpa.country.Country; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.test.City; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.testsupport.BuildOutput; -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.JpaVendorAdapter; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager; -import org.springframework.orm.jpa.persistenceunit.ManagedClassNameFilter; -import org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypes; -import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager; -import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter; -import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionManager; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Base for JPA tests and tests for {@link JpaBaseConfiguration}. - * - * @author Phillip Webb - * @author Dave Syer - * @author Stephane Nicoll - * @author Yanming Zhou - */ -abstract class AbstractJpaAutoConfigurationTests { - - private final Class autoConfiguredClass; - - private final ApplicationContextRunner contextRunner; - - protected AbstractJpaAutoConfigurationTests(Class autoConfiguredClass) { - this.autoConfiguredClass = autoConfiguredClass; - this.contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.datasource.generate-unique-name=true", - "spring.jta.log-dir=" + new File(new BuildOutput(getClass()).getRootLocation(), "transaction-logs")) - .withUserConfiguration(TestConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - TransactionAutoConfiguration.class, TransactionManagerCustomizationAutoConfiguration.class, - SqlInitializationAutoConfiguration.class, autoConfiguredClass)); - } - - protected ApplicationContextRunner contextRunner() { - return this.contextRunner; - } - - @Test - void notConfiguredIfDataSourceIsNotAvailable() { - new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(this.autoConfiguredClass)) - .run(assertJpaIsNotAutoConfigured()); - } - - @Test - void notConfiguredIfNoSingleDataSourceCandidateIsAvailable() { - new ApplicationContextRunner().withUserConfiguration(TestTwoDataSourcesConfiguration.class) - .withConfiguration(AutoConfigurations.of(this.autoConfiguredClass)) - .run(assertJpaIsNotAutoConfigured()); - } - - protected ContextConsumer assertJpaIsNotAutoConfigured() { - return (context) -> { - assertThat(context).hasNotFailed(); - assertThat(context).hasSingleBean(JpaProperties.class); - assertThat(context).doesNotHaveBean(TransactionManager.class); - assertThat(context).doesNotHaveBean(EntityManagerFactory.class); - }; - } - - @Test - void configuredWithAutoConfiguredDataSource() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(DataSource.class); - assertThat(context).hasSingleBean(JpaTransactionManager.class); - assertThat(context).hasSingleBean(EntityManagerFactory.class); - assertThat(context).hasSingleBean(PersistenceManagedTypes.class); - }); - } - - @Test - void configuredWithSingleCandidateDataSource() { - this.contextRunner.withUserConfiguration(TestTwoDataSourcesAndPrimaryConfiguration.class).run((context) -> { - assertThat(context).getBeans(DataSource.class).hasSize(2); - assertThat(context).hasSingleBean(JpaTransactionManager.class); - assertThat(context).hasSingleBean(EntityManagerFactory.class); - assertThat(context).hasSingleBean(PersistenceManagedTypes.class); - }); - } - - @Test - void jpaTransactionManagerTakesPrecedenceOverSimpleDataSourceOne() { - this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasSingleBean(DataSource.class); - assertThat(context).hasSingleBean(JpaTransactionManager.class); - assertThat(context).getBean("transactionManager").isInstanceOf(JpaTransactionManager.class); - }); - } - - @Test - void openEntityManagerInViewInterceptorIsCreated() { - new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true") - .withUserConfiguration(TestConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - TransactionAutoConfiguration.class, this.autoConfiguredClass)) - .run((context) -> assertThat(context).hasSingleBean(OpenEntityManagerInViewInterceptor.class)); - } - - @Test - void openEntityManagerInViewInterceptorIsNotRegisteredWhenFilterPresent() { - new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true") - .withUserConfiguration(TestFilterConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - TransactionAutoConfiguration.class, this.autoConfiguredClass)) - .run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class)); - } - - @Test - void openEntityManagerInViewInterceptorIsNotRegisteredWhenFilterRegistrationPresent() { - new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true") - .withUserConfiguration(TestFilterRegistrationConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - TransactionAutoConfiguration.class, this.autoConfiguredClass)) - .run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class)); - } - - @Test - void openEntityManagerInViewInterceptorAutoConfigurationBacksOffWhenManuallyRegistered() { - new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true") - .withUserConfiguration(TestInterceptorManualConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - TransactionAutoConfiguration.class, this.autoConfiguredClass)) - .run((context) -> assertThat(context).getBean(OpenEntityManagerInViewInterceptor.class) - .isExactlyInstanceOf( - TestInterceptorManualConfiguration.ManualOpenEntityManagerInViewInterceptor.class)); - } - - @Test - void openEntityManagerInViewInterceptorIsNotRegisteredWhenExplicitlyOff() { - new WebApplicationContextRunner() - .withPropertyValues("spring.datasource.generate-unique-name=true", "spring.jpa.open-in-view=false") - .withUserConfiguration(TestConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - TransactionAutoConfiguration.class, this.autoConfiguredClass)) - .run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class)); - } - - @Test - void customJpaProperties() { - this.contextRunner - .withPropertyValues("spring.jpa.properties.a:b", "spring.jpa.properties.a.b:c", "spring.jpa.properties.c:d") - .run((context) -> { - LocalContainerEntityManagerFactoryBean bean = context - .getBean(LocalContainerEntityManagerFactoryBean.class); - Map map = bean.getJpaPropertyMap(); - assertThat(map).containsEntry("a", "b"); - assertThat(map).containsEntry("c", "d"); - assertThat(map).containsEntry("a.b", "c"); - }); - } - - @Test - @WithMetaInfPersistenceXmlResource - void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanUsingBuilder() { - this.contextRunner.withPropertyValues("spring.jpa.properties.a=b") - .withUserConfiguration(TestConfigurationWithEntityManagerFactoryBuilder.class) - .run((context) -> { - LocalContainerEntityManagerFactoryBean factoryBean = context - .getBean(LocalContainerEntityManagerFactoryBean.class); - Map map = factoryBean.getJpaPropertyMap(); - assertThat(map).containsEntry("configured", "manually").containsEntry("a", "b"); - }); - } - - @Test - @WithMetaInfPersistenceXmlResource - void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanIfAvailable() { - this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class) - .run((context) -> { - LocalContainerEntityManagerFactoryBean factoryBean = context - .getBean(LocalContainerEntityManagerFactoryBean.class); - Map map = factoryBean.getJpaPropertyMap(); - assertThat(map).containsEntry("configured", "manually"); - }); - } - - @Test - @WithMetaInfPersistenceXmlResource - void usesManuallyDefinedEntityManagerFactoryIfAvailable() { - this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class) - .run((context) -> { - EntityManagerFactory factoryBean = context.getBean(EntityManagerFactory.class); - Map map = factoryBean.getProperties(); - assertThat(map).containsEntry("configured", "manually"); - }); - } - - @Test - void usesManuallyDefinedTransactionManagerBeanIfAvailable() { - this.contextRunner.withUserConfiguration(TestConfigurationWithTransactionManager.class).run((context) -> { - assertThat(context).hasSingleBean(TransactionManager.class); - TransactionManager txManager = context.getBean(TransactionManager.class); - assertThat(txManager).isInstanceOf(CustomJpaTransactionManager.class); - }); - } - - @Test - void defaultPersistenceManagedTypes() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(PersistenceManagedTypes.class); - EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager(); - assertThat(getManagedJavaTypes(entityManager)).contains(City.class).doesNotContain(Country.class); - }); - } - - @Test - void customPersistenceManagedTypes() { - this.contextRunner - .withBean(PersistenceManagedTypes.class, () -> PersistenceManagedTypes.of(Country.class.getName())) - .run((context) -> { - assertThat(context).hasSingleBean(PersistenceManagedTypes.class); - EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager(); - assertThat(getManagedJavaTypes(entityManager)).contains(Country.class).doesNotContain(City.class); - }); - } - - @Test - void customPersistenceUnitManager() { - this.contextRunner.withUserConfiguration(TestConfigurationWithCustomPersistenceUnitManager.class) - .run((context) -> { - LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context - .getBean(LocalContainerEntityManagerFactoryBean.class); - assertThat(entityManagerFactoryBean).hasFieldOrPropertyWithValue("persistenceUnitManager", - context.getBean(PersistenceUnitManager.class)); - }); - } - - @Test - void customPersistenceUnitPostProcessors() { - this.contextRunner.withUserConfiguration(TestConfigurationWithCustomPersistenceUnitPostProcessors.class) - .run((context) -> { - LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context - .getBean(LocalContainerEntityManagerFactoryBean.class); - PersistenceUnitInfo persistenceUnitInfo = entityManagerFactoryBean.getPersistenceUnitInfo(); - assertThat(persistenceUnitInfo).isNotNull(); - assertThat(persistenceUnitInfo.getManagedClassNames()) - .contains("customized.attribute.converter.class.name"); - }); - } - - @Test - void customManagedClassNameFilter() { - this.contextRunner.withBean(ManagedClassNameFilter.class, () -> (s) -> !s.endsWith("City")) - .withUserConfiguration(AutoConfigurePackageForCountry.class) - .run((context) -> { - EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager(); - assertThat(getManagedJavaTypes(entityManager)).contains(Country.class).doesNotContain(City.class); - }); - } - - private Class[] getManagedJavaTypes(EntityManager entityManager) { - Set> managedTypes = entityManager.getMetamodel().getManagedTypes(); - return managedTypes.stream().map(ManagedType::getJavaType).toArray(Class[]::new); - } - - @Configuration(proxyBeanMethods = false) - static class TestTwoDataSourcesConfiguration { - - @Bean - DataSource firstDataSource() { - return createRandomDataSource(); - } - - @Bean - DataSource secondDataSource() { - return createRandomDataSource(); - } - - private DataSource createRandomDataSource() { - String url = "jdbc:h2:mem:init-" + UUID.randomUUID(); - return DataSourceBuilder.create().url(url).build(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestTwoDataSourcesAndPrimaryConfiguration { - - @Bean - @Primary - DataSource firstDataSource() { - return createRandomDataSource(); - } - - @Bean - DataSource secondDataSource() { - return createRandomDataSource(); - } - - private DataSource createRandomDataSource() { - String url = "jdbc:h2:mem:init-" + UUID.randomUUID(); - return DataSourceBuilder.create().url(url).build(); - } - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(City.class) - static class TestConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(City.class) - static class TestFilterConfiguration { - - @Bean - OpenEntityManagerInViewFilter openEntityManagerInViewFilter() { - return new OpenEntityManagerInViewFilter(); - } - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(City.class) - static class TestFilterRegistrationConfiguration { - - @Bean - FilterRegistrationBean openEntityManagerInViewFilterFilterRegistrationBean() { - return new FilterRegistrationBean<>(); - } - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(City.class) - static class TestInterceptorManualConfiguration { - - @Bean - OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor() { - return new ManualOpenEntityManagerInViewInterceptor(); - } - - static class ManualOpenEntityManagerInViewInterceptor extends OpenEntityManagerInViewInterceptor { - - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestConfigurationWithEntityManagerFactoryBuilder extends TestConfiguration { - - @Bean - LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder, - DataSource dataSource) { - return builder.dataSource(dataSource).properties(Map.of("configured", "manually")).build(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestConfigurationWithLocalContainerEntityManagerFactoryBean extends TestConfiguration { - - @Bean - LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter) { - LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); - factoryBean.setJpaVendorAdapter(adapter); - factoryBean.setDataSource(dataSource); - factoryBean.setPersistenceUnitName("manually-configured"); - Map properties = new HashMap<>(); - properties.put("configured", "manually"); - properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); - factoryBean.setJpaPropertyMap(properties); - return factoryBean; - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestConfigurationWithEntityManagerFactory extends TestConfiguration { - - @Bean - EntityManagerFactory entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter) { - LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); - factoryBean.setJpaVendorAdapter(adapter); - factoryBean.setDataSource(dataSource); - factoryBean.setPersistenceUnitName("manually-configured"); - Map properties = new HashMap<>(); - properties.put("configured", "manually"); - properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); - factoryBean.setJpaPropertyMap(properties); - factoryBean.afterPropertiesSet(); - return factoryBean.getObject(); - } - - @Bean - PlatformTransactionManager transactionManager(EntityManagerFactory emf) { - JpaTransactionManager transactionManager = new JpaTransactionManager(); - transactionManager.setEntityManagerFactory(emf); - return transactionManager; - } - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(City.class) - static class TestConfigurationWithTransactionManager { - - @Bean - TransactionManager testTransactionManager() { - return new CustomJpaTransactionManager(); - } - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(Country.class) - static class AutoConfigurePackageForCountry { - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(AbstractJpaAutoConfigurationTests.class) - static class TestConfigurationWithCustomPersistenceUnitManager { - - private final DataSource dataSource; - - TestConfigurationWithCustomPersistenceUnitManager(DataSource dataSource) { - this.dataSource = dataSource; - } - - @Bean - PersistenceUnitManager persistenceUnitManager() { - DefaultPersistenceUnitManager persistenceUnitManager = new DefaultPersistenceUnitManager(); - persistenceUnitManager.setDefaultDataSource(this.dataSource); - persistenceUnitManager.setPackagesToScan(City.class.getPackage().getName()); - return persistenceUnitManager; - } - - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(AbstractJpaAutoConfigurationTests.class) - static class TestConfigurationWithCustomPersistenceUnitPostProcessors { - - @Bean - EntityManagerFactoryBuilderCustomizer entityManagerFactoryBuilderCustomizer() { - return (builder) -> builder.setPersistenceUnitPostProcessors( - (pui) -> pui.addManagedClassName("customized.attribute.converter.class.name")); - } - - } - - static class CustomJpaTransactionManager extends JpaTransactionManager { - - } - - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - @WithResource(name = "META-INF/persistence.xml", - content = """ - - - - org.springframework.boot.autoconfigure.orm.jpa.test.City - true - - - """) - @interface WithMetaInfPersistenceXmlResource { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/Hibernate2ndLevelCacheIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/Hibernate2ndLevelCacheIntegrationTests.java deleted file mode 100644 index c5cc96aa4398..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/Hibernate2ndLevelCacheIntegrationTests.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.orm.jpa; - -import org.ehcache.jsr107.EhcacheCachingProvider; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cache.annotation.EnableCaching; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for Hibernate 2nd level cache with jcache. - * - * @author Stephane Nicoll - */ -class Hibernate2ndLevelCacheIntegrationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(CacheAutoConfiguration.class, DataSourceAutoConfiguration.class, - HibernateJpaAutoConfiguration.class)) - .withUserConfiguration(TestConfiguration.class); - - @Test - void hibernate2ndLevelCacheWithJCacheAndEhCache() { - String cachingProviderFqn = EhcacheCachingProvider.class.getName(); - this.contextRunner - .withPropertyValues("spring.cache.type=jcache", "spring.cache.jcache.provider=" + cachingProviderFqn, - "spring.jpa.properties.hibernate.cache.region.factory_class=jcache", - "spring.jpa.properties.hibernate.cache.provider=" + cachingProviderFqn) - .run((context) -> assertThat(context).hasNotFailed()); - } - - @Configuration(proxyBeanMethods = false) - @EnableCaching - static class TestConfiguration { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java deleted file mode 100644 index f772d9332661..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java +++ /dev/null @@ -1,896 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.orm.jpa; - -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -import javax.sql.DataSource; - -import com.zaxxer.hikari.HikariDataSource; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.transaction.Synchronization; -import jakarta.transaction.Transaction; -import jakarta.transaction.TransactionManager; -import jakarta.transaction.UserTransaction; -import org.hibernate.boot.model.naming.ImplicitNamingStrategy; -import org.hibernate.boot.model.naming.PhysicalNamingStrategy; -import org.hibernate.boot.model.naming.PhysicalNamingStrategySnakeCaseImpl; -import org.hibernate.cfg.ManagedBeanSettings; -import org.hibernate.cfg.SchemaToolingSettings; -import org.hibernate.dialect.H2Dialect; -import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; -import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; -import org.hibernate.internal.SessionFactoryImpl; -import org.hibernate.jpa.HibernatePersistenceProvider; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.TypeReference; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurationTests.JpaUsingApplicationListenerConfiguration.EventCapturingApplicationListener; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration.HibernateRuntimeHints; -import org.springframework.boot.autoconfigure.orm.jpa.mapping.NonAnnotatedEntity; -import org.springframework.boot.autoconfigure.orm.jpa.test.City; -import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration; -import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; -import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform; -import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization; -import org.springframework.boot.test.context.assertj.AssertableApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.support.SQLExceptionTranslator; -import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.JpaVendorAdapter; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.transaction.jta.JtaTransactionManager; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatNoException; -import static org.assertj.core.api.Assertions.entry; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link HibernateJpaAutoConfiguration}. - * - * @author Dave Syer - * @author Phillip Webb - * @author Andy Wilkinson - * @author Kazuki Shimizu - * @author Stephane Nicoll - * @author Chris Bono - * @author Moritz Halbritter - */ -class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTests { - - HibernateJpaAutoConfigurationTests() { - super(HibernateJpaAutoConfiguration.class); - } - - @Test - void testDmlScriptWithMissingDdl() { - contextRunner().withPropertyValues("spring.sql.init.data-locations:classpath:/city.sql", - // Missing: - "spring.sql.init.schema-locations:classpath:/ddl.sql") - .run((context) -> { - assertThat(context).hasFailed(); - assertThat(context.getStartupFailure()).hasMessageContaining("ddl.sql"); - }); - } - - @Test - void testDmlScript() { - // This can't succeed because the data SQL is executed immediately after the - // schema and Hibernate hasn't initialized yet at that point - contextRunner().withPropertyValues("spring.sql.init.data-locations:/city.sql").run((context) -> { - assertThat(context).hasFailed(); - assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class); - }); - } - - @Test - @WithResource(name = "city.sql", - content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google')") - void testDmlScriptRunsEarly() { - contextRunner().withUserConfiguration(TestInitializedJpaConfiguration.class) - .withClassLoader(new HideDataScriptClassLoader()) - .withPropertyValues("spring.jpa.show-sql=true", "spring.jpa.properties.hibernate.format_sql=true", - "spring.jpa.properties.hibernate.highlight_sql=true", "spring.jpa.hibernate.ddl-auto:create-drop", - "spring.sql.init.data-locations:/city.sql", "spring.jpa.defer-datasource-initialization=true") - .run((context) -> assertThat(context.getBean(TestInitializedJpaConfiguration.class).called).isTrue()); - } - - @Test - @WithResource(name = "db/city/V1__init.sql", content = """ - CREATE SEQUENCE city_seq INCREMENT BY 50; - CREATE TABLE CITY ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY, - name VARCHAR(30), - state VARCHAR(30), - country VARCHAR(30), - map VARCHAR(30) - ); - """) - void testFlywaySwitchOffDdlAuto() { - contextRunner().withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city") - .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) - .run((context) -> assertThat(context).hasNotFailed()); - } - - @Test - @WithResource(name = "db/city/V1__init.sql", content = """ - CREATE SEQUENCE city_seq INCREMENT BY 50; - - CREATE TABLE CITY ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY, - name VARCHAR(30), - state VARCHAR(30), - country VARCHAR(30), - map VARCHAR(30) - ); - """) - void testFlywayPlusValidation() { - contextRunner() - .withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city", - "spring.jpa.hibernate.ddl-auto:validate") - .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) - .run((context) -> assertThat(context).hasNotFailed()); - } - - @Test - @WithResource(name = "db/changelog/db.changelog-city.yaml", content = """ - databaseChangeLog: - - changeSet: - id: 1 - author: dsyer - changes: - - createSequence: - sequenceName: city_seq - incrementBy: 50 - - createTable: - tableName: city - columns: - - column: - name: id - type: bigint - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: name - type: varchar(50) - constraints: - nullable: false - - column: - name: state - type: varchar(50) - constraints: - nullable: false - - column: - name: country - type: varchar(50) - constraints: - nullable: false - - column: - name: map - type: varchar(50) - constraints: - nullable: true - """) - void testLiquibasePlusValidation() { - contextRunner() - .withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml", - "spring.jpa.hibernate.ddl-auto:validate") - .withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class)) - .run((context) -> assertThat(context).hasNotFailed()); - } - - @Test - void hibernateDialectIsNotSetByDefault() { - contextRunner().run(assertJpaVendorAdapter( - (adapter) -> assertThat(adapter.getJpaPropertyMap()).doesNotContainKeys("hibernate.dialect"))); - } - - @Test - void shouldConfigureHibernateJpaDialectWithSqlExceptionTranslatorIfPresent() { - SQLStateSQLExceptionTranslator sqlExceptionTranslator = new SQLStateSQLExceptionTranslator(); - contextRunner().withBean(SQLStateSQLExceptionTranslator.class, () -> sqlExceptionTranslator) - .run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaDialect()) - .hasFieldOrPropertyWithValue("jdbcExceptionTranslator", sqlExceptionTranslator))); - } - - @Test - void shouldNotConfigureHibernateJpaDialectWithSqlExceptionTranslatorIfNotUnique() { - SQLStateSQLExceptionTranslator sqlExceptionTranslator1 = new SQLStateSQLExceptionTranslator(); - SQLStateSQLExceptionTranslator sqlExceptionTranslator2 = new SQLStateSQLExceptionTranslator(); - contextRunner().withBean("sqlExceptionTranslator1", SQLExceptionTranslator.class, () -> sqlExceptionTranslator1) - .withBean("sqlExceptionTranslator2", SQLExceptionTranslator.class, () -> sqlExceptionTranslator2) - .run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaDialect()) - .hasFieldOrPropertyWithValue("jdbcExceptionTranslator", null))); - } - - @Test - void hibernateDialectIsSetWhenDatabaseIsSet() { - contextRunner().withPropertyValues("spring.jpa.database=H2") - .run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaPropertyMap()) - .contains(entry("hibernate.dialect", H2Dialect.class.getName())))); - } - - @Test - void hibernateDialectIsSetWhenDatabasePlatformIsSet() { - String databasePlatform = TestH2Dialect.class.getName(); - contextRunner().withPropertyValues("spring.jpa.database-platform=" + databasePlatform) - .run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaPropertyMap()) - .contains(entry("hibernate.dialect", databasePlatform)))); - } - - private ContextConsumer assertJpaVendorAdapter( - Consumer adapter) { - return (context) -> { - assertThat(context).hasSingleBean(JpaVendorAdapter.class); - assertThat(context).hasSingleBean(HibernateJpaVendorAdapter.class); - adapter.accept(context.getBean(HibernateJpaVendorAdapter.class)); - }; - } - - @Test - void jtaDefaultPlatform() { - contextRunner().withUserConfiguration(JtaTransactionManagerConfiguration.class) - .run(assertJtaPlatform(SpringJtaPlatform.class)); - } - - @Test - void jtaCustomPlatform() { - contextRunner() - .withPropertyValues( - "spring.jpa.properties.hibernate.transaction.jta.platform:" + TestJtaPlatform.class.getName()) - .withConfiguration(AutoConfigurations.of(JtaAutoConfiguration.class)) - .run(assertJtaPlatform(TestJtaPlatform.class)); - } - - @Test - void jtaNotUsedByTheApplication() { - contextRunner().run(assertJtaPlatform(NoJtaPlatform.class)); - } - - private ContextConsumer assertJtaPlatform(Class expectedType) { - return (context) -> { - SessionFactoryImpl sessionFactory = context.getBean(LocalContainerEntityManagerFactoryBean.class) - .getNativeEntityManagerFactory() - .unwrap(SessionFactoryImpl.class); - assertThat(sessionFactory.getServiceRegistry().getService(JtaPlatform.class)).isInstanceOf(expectedType); - }; - } - - @Test - void jtaCustomTransactionManagerUsingProperties() { - contextRunner() - .withPropertyValues("spring.transaction.default-timeout:30", - "spring.transaction.rollback-on-commit-failure:true") - .run((context) -> { - JpaTransactionManager transactionManager = context.getBean(JpaTransactionManager.class); - assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); - assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); - }); - } - - @Test - void autoConfigurationBacksOffWithSeveralDataSources() { - contextRunner() - .withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class, - XADataSourceAutoConfiguration.class, JtaAutoConfiguration.class)) - .withUserConfiguration(TestTwoDataSourcesConfiguration.class) - .run((context) -> { - assertThat(context).hasNotFailed(); - assertThat(context).doesNotHaveBean(EntityManagerFactory.class); - }); - } - - @Test - void providerDisablesAutoCommitIsConfigured() { - contextRunner() - .withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(), - "spring.datasource.hikari.auto-commit:false") - .run((context) -> { - Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) - .getJpaPropertyMap(); - assertThat(jpaProperties).contains(entry("hibernate.connection.provider_disables_autocommit", "true")); - }); - } - - @Test - void providerDisablesAutoCommitIsNotConfiguredIfAutoCommitIsEnabled() { - contextRunner() - .withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(), - "spring.datasource.hikari.auto-commit:true") - .run((context) -> { - Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) - .getJpaPropertyMap(); - assertThat(jpaProperties).doesNotContainKeys("hibernate.connection.provider_disables_autocommit"); - }); - } - - @Test - void providerDisablesAutoCommitIsNotConfiguredIfPropertyIsSet() { - contextRunner() - .withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(), - "spring.datasource.hikari.auto-commit:false", - "spring.jpa.properties.hibernate.connection.provider_disables_autocommit=false") - .run((context) -> { - Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) - .getJpaPropertyMap(); - assertThat(jpaProperties).contains(entry("hibernate.connection.provider_disables_autocommit", "false")); - }); - } - - @Test - void providerDisablesAutoCommitIsNotConfiguredWithJta() { - contextRunner().withUserConfiguration(JtaTransactionManagerConfiguration.class) - .withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(), - "spring.datasource.hikari.auto-commit:false") - .run((context) -> { - Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) - .getJpaPropertyMap(); - assertThat(jpaProperties).doesNotContainKeys("hibernate.connection.provider_disables_autocommit"); - }); - } - - @Test - @WithResource(name = "META-INF/mappings/non-annotated.xml", - content = """ - - - - - - - - - - - - - - - - """) - @WithResource(name = "non-annotated-data.sql", - content = "INSERT INTO NON_ANNOTATED (id, item) values (2000, 'Test');") - void customResourceMapping() { - contextRunner().withClassLoader(new HideDataScriptClassLoader()) - .withPropertyValues("spring.sql.init.data-locations:classpath:non-annotated-data.sql", - "spring.jpa.mapping-resources=META-INF/mappings/non-annotated.xml", - "spring.jpa.defer-datasource-initialization=true") - .run((context) -> { - EntityManager em = context.getBean(EntityManagerFactory.class).createEntityManager(); - NonAnnotatedEntity found = em.find(NonAnnotatedEntity.class, 2000L); - assertThat(found).isNotNull(); - assertThat(found.getItem()).isEqualTo("Test"); - }); - } - - @Test - void physicalNamingStrategyCanBeUsed() { - contextRunner().withUserConfiguration(TestPhysicalNamingStrategyConfiguration.class).run((context) -> { - Map hibernateProperties = getVendorProperties(context); - assertThat(hibernateProperties) - .contains(entry("hibernate.physical_naming_strategy", context.getBean("testPhysicalNamingStrategy"))); - assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy"); - }); - } - - @Test - void implicitNamingStrategyCanBeUsed() { - contextRunner().withUserConfiguration(TestImplicitNamingStrategyConfiguration.class).run((context) -> { - Map hibernateProperties = getVendorProperties(context); - assertThat(hibernateProperties) - .contains(entry("hibernate.implicit_naming_strategy", context.getBean("testImplicitNamingStrategy"))); - assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy"); - }); - } - - @Test - void namingStrategyInstancesTakePrecedenceOverNamingStrategyProperties() { - contextRunner() - .withUserConfiguration(TestPhysicalNamingStrategyConfiguration.class, - TestImplicitNamingStrategyConfiguration.class) - .withPropertyValues("spring.jpa.hibernate.naming.physical-strategy:com.example.Physical", - "spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit") - .run((context) -> { - Map hibernateProperties = getVendorProperties(context); - assertThat(hibernateProperties).contains( - entry("hibernate.physical_naming_strategy", context.getBean("testPhysicalNamingStrategy")), - entry("hibernate.implicit_naming_strategy", context.getBean("testImplicitNamingStrategy"))); - assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy"); - }); - } - - @Test - void hibernatePropertiesCustomizerTakesPrecedenceOverStrategyInstancesAndNamingStrategyProperties() { - contextRunner() - .withUserConfiguration(TestHibernatePropertiesCustomizerConfiguration.class, - TestPhysicalNamingStrategyConfiguration.class, TestImplicitNamingStrategyConfiguration.class) - .withPropertyValues("spring.jpa.hibernate.naming.physical-strategy:com.example.Physical", - "spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit") - .run((context) -> { - Map hibernateProperties = getVendorProperties(context); - TestHibernatePropertiesCustomizerConfiguration configuration = context - .getBean(TestHibernatePropertiesCustomizerConfiguration.class); - assertThat(hibernateProperties).contains( - entry("hibernate.physical_naming_strategy", configuration.physicalNamingStrategy), - entry("hibernate.implicit_naming_strategy", configuration.implicitNamingStrategy)); - assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy"); - }); - } - - @Test - @WithResource(name = "city.sql", - content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google')") - void eventListenerCanBeRegisteredAsBeans() { - contextRunner().withUserConfiguration(TestInitializedJpaConfiguration.class) - .withClassLoader(new HideDataScriptClassLoader()) - .withPropertyValues("spring.jpa.show-sql=true", "spring.jpa.hibernate.ddl-auto:create-drop", - "spring.sql.init.data-locations:classpath:/city.sql", - "spring.jpa.defer-datasource-initialization=true") - .run((context) -> { - // See CityListener - assertThat(context).hasSingleBean(City.class); - assertThat(context.getBean(City.class).getName()).isEqualTo("Washington"); - }); - } - - @Test - void hibernatePropertiesCustomizerCanDisableBeanContainer() { - contextRunner().withUserConfiguration(DisableBeanContainerConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(City.class)); - } - - @Test - void vendorPropertiesWithEmbeddedDatabaseAndNoDdlProperty() { - contextRunner().run(vendorProperties((vendorProperties) -> { - assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION); - assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "create-drop"); - })); - } - - @Test - void vendorPropertiesWhenDdlAutoPropertyIsSet() { - contextRunner().withPropertyValues("spring.jpa.hibernate.ddl-auto=update") - .run(vendorProperties((vendorProperties) -> { - assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION); - assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "update"); - })); - } - - @Test - void vendorPropertiesWhenDdlAutoPropertyAndHibernatePropertiesAreSet() { - contextRunner() - .withPropertyValues("spring.jpa.hibernate.ddl-auto=update", - "spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop") - .run(vendorProperties((vendorProperties) -> { - assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION); - assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "create-drop"); - })); - } - - @Test - void vendorPropertiesWhenDdlAutoPropertyIsSetToNone() { - contextRunner().withPropertyValues("spring.jpa.hibernate.ddl-auto=none") - .run(vendorProperties((vendorProperties) -> assertThat(vendorProperties).doesNotContainKeys( - SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, SchemaToolingSettings.HBM2DDL_AUTO))); - } - - @Test - void vendorPropertiesWhenJpaDdlActionIsSet() { - contextRunner() - .withPropertyValues("spring.jpa.properties.jakarta.persistence.schema-generation.database.action=create") - .run(vendorProperties((vendorProperties) -> { - assertThat(vendorProperties).containsEntry(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, - "create"); - assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.HBM2DDL_AUTO); - })); - } - - @Test - void vendorPropertiesWhenBothDdlAutoPropertiesAreSet() { - contextRunner() - .withPropertyValues("spring.jpa.properties.jakarta.persistence.schema-generation.database.action=create", - "spring.jpa.hibernate.ddl-auto=create-only") - .run(vendorProperties((vendorProperties) -> { - assertThat(vendorProperties).containsEntry(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, - "create"); - assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "create-only"); - })); - } - - private ContextConsumer vendorProperties( - Consumer> vendorProperties) { - return (context) -> vendorProperties.accept(getVendorProperties(context)); - } - - private static Map getVendorProperties(ConfigurableApplicationContext context) { - return context.getBean(HibernateJpaConfiguration.class).getVendorProperties(context.getBean(DataSource.class)); - } - - @Test - void withSyncBootstrappingAnApplicationListenerThatUsesJpaDoesNotTriggerABeanCurrentlyInCreationException() { - contextRunner().withUserConfiguration(JpaUsingApplicationListenerConfiguration.class).run((context) -> { - assertThat(context).hasNotFailed(); - EventCapturingApplicationListener listener = context.getBean(EventCapturingApplicationListener.class); - assertThat(listener.events).hasSize(1); - assertThat(listener.events).hasOnlyElementsOfType(ContextRefreshedEvent.class); - }); - } - - @Test - void withAsyncBootstrappingAnApplicationListenerThatUsesJpaDoesNotTriggerABeanCurrentlyInCreationException() { - contextRunner() - .withUserConfiguration(AsyncBootstrappingConfiguration.class, - JpaUsingApplicationListenerConfiguration.class) - .run((context) -> { - assertThat(context).hasNotFailed(); - EventCapturingApplicationListener listener = context.getBean(EventCapturingApplicationListener.class); - assertThat(listener.events).hasSize(1); - assertThat(listener.events).hasOnlyElementsOfType(ContextRefreshedEvent.class); - // createEntityManager requires Hibernate bootstrapping to be complete - assertThatNoException() - .isThrownBy(() -> context.getBean(EntityManagerFactory.class).createEntityManager()); - }); - } - - @Test - @WithMetaInfPersistenceXmlResource - void whenLocalContainerEntityManagerFactoryBeanHasNoJpaVendorAdapterAutoConfigurationSucceeds() { - contextRunner() - .withUserConfiguration( - TestConfigurationWithLocalContainerEntityManagerFactoryBeanWithNoJpaVendorAdapter.class) - .run((context) -> { - EntityManagerFactory factoryBean = context.getBean(EntityManagerFactory.class); - Map map = factoryBean.getProperties(); - assertThat(map).containsEntry("configured", "manually"); - }); - } - - @Test - void registersHintsForJtaClasses() { - RuntimeHints hints = new RuntimeHints(); - new HibernateRuntimeHints().registerHints(hints, getClass().getClassLoader()); - for (String noJtaPlatformClass : Arrays.asList( - "org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform", - "org.hibernate.service.jta.platform.internal.NoJtaPlatform")) { - assertThat(RuntimeHintsPredicates.reflection() - .onType(TypeReference.of(noJtaPlatformClass)) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints); - } - } - - @Test - void registersHintsForNamingClasses() { - RuntimeHints hints = new RuntimeHints(); - new HibernateRuntimeHints().registerHints(hints, getClass().getClassLoader()); - for (Class noJtaPlatformClass : Arrays.asList(SpringImplicitNamingStrategy.class, - PhysicalNamingStrategySnakeCaseImpl.class)) { - assertThat(RuntimeHintsPredicates.reflection() - .onType(noJtaPlatformClass) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints); - } - } - - @Test - @Disabled("gh-40177") - void whenSpringJpaGenerateDdlIsNotSetThenTableIsNotCreated() { - // spring.jpa.generated-ddl defaults to false but this test still fails because - // we're using an embedded database which means that HibernateProperties defaults - // hibernate.hbm2ddl.auto to create-drop, replacing the - // hibernate.hbm2ddl.auto=none that comes from generate-ddl being false. - contextRunner().run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); - } - - @Test - void whenSpringJpaGenerateDdlIsTrueThenTableIsCreated() { - contextRunner().withPropertyValues("spring.jpa.generate-ddl=true") - .run((context) -> assertThat(tablesFrom(context)).contains("CITY")); - } - - @Test - @Disabled("gh-40177") - void whenSpringJpaGenerateDdlIsFalseThenTableIsNotCreated() { - // This test fails because we're using an embedded database which means that - // HibernateProperties defaults hibernate.hbm2ddl.auto to create-drop, replacing - // the hibernate.hbm2ddl.auto=none that comes from setting generate-ddl to false. - contextRunner().withPropertyValues("spring.jpa.generate-ddl=false") - .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); - } - - @Test - void whenHbm2DdlAutoIsNoneThenTableIsNotCreated() { - contextRunner().withPropertyValues("spring.jpa.properties.hibernate.hbm2ddl.auto=none") - .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); - } - - @Test - void whenSpringJpaHibernateDdlAutoIsNoneThenTableIsNotCreated() { - contextRunner().withPropertyValues("spring.jpa.hibernate.ddl-auto=none") - .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); - } - - @Test - @Disabled("gh-40177") - void whenSpringJpaGenerateDdlIsTrueAndSpringJpaHibernateDdlAutoIsNoneThenTableIsNotCreated() { - // This test fails because when ddl-auto is set to none, we remove - // hibernate.hbm2ddl.auto from Hibernate properties. This then allows - // spring.jpa.generate-ddl to set it to create-drop - contextRunner().withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=none") - .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); - } - - @Test - void whenSpringJpaGenerateDdlIsTrueAndSpringJpaHibernateDdlAutoIsDropThenTableIsNotCreated() { - contextRunner().withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=drop") - .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); - } - - @Test - void whenSpringJpaGenerateDdlIsTrueAndJakartaSchemaGenerationIsNoneThenTableIsNotCreated() { - contextRunner() - .withPropertyValues("spring.jpa.generate-ddl=true", - "spring.jpa.properties.jakarta.persistence.schema-generation.database.action=none") - .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); - } - - @Test - void whenSpringJpaGenerateDdlIsTrueSpringJpaHibernateDdlAutoIsCreateAndJakartaSchemaGenerationIsNoneThenTableIsNotCreated() { - contextRunner() - .withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=create", - "spring.jpa.properties.jakarta.persistence.schema-generation.database.action=none") - .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); - } - - private List tablesFrom(AssertableApplicationContext context) { - DataSource dataSource = context.getBean(DataSource.class); - JdbcTemplate jdbc = new JdbcTemplate(dataSource); - List tables = jdbc.query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES", - (results, row) -> results.getString(1)); - return tables; - } - - @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(City.class) - @DependsOnDatabaseInitialization - static class TestInitializedJpaConfiguration { - - private boolean called; - - @Autowired - void validateDataSourceIsInitialized(EntityManagerFactory entityManagerFactory) { - // Inject the entity manager to validate it is initialized at the injection - // point - EntityManager entityManager = entityManagerFactory.createEntityManager(); - City city = entityManager.find(City.class, 2000L); - assertThat(city).isNotNull(); - assertThat(city.getName()).isEqualTo("Washington"); - this.called = true; - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestImplicitNamingStrategyConfiguration { - - @Bean - ImplicitNamingStrategy testImplicitNamingStrategy() { - return new SpringImplicitNamingStrategy(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestPhysicalNamingStrategyConfiguration { - - @Bean - PhysicalNamingStrategy testPhysicalNamingStrategy() { - return new PhysicalNamingStrategySnakeCaseImpl(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestHibernatePropertiesCustomizerConfiguration { - - private final PhysicalNamingStrategy physicalNamingStrategy = new PhysicalNamingStrategySnakeCaseImpl(); - - private final ImplicitNamingStrategy implicitNamingStrategy = new SpringImplicitNamingStrategy(); - - @Bean - HibernatePropertiesCustomizer testHibernatePropertiesCustomizer() { - return (hibernateProperties) -> { - hibernateProperties.put("hibernate.physical_naming_strategy", this.physicalNamingStrategy); - hibernateProperties.put("hibernate.implicit_naming_strategy", this.implicitNamingStrategy); - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DisableBeanContainerConfiguration { - - @Bean - HibernatePropertiesCustomizer disableBeanContainerHibernatePropertiesCustomizer() { - return (hibernateProperties) -> hibernateProperties.remove(ManagedBeanSettings.BEAN_CONTAINER); - } - - } - - public static class TestJtaPlatform implements JtaPlatform { - - @Override - public TransactionManager retrieveTransactionManager() { - return mock(TransactionManager.class); - } - - @Override - public UserTransaction retrieveUserTransaction() { - throw new UnsupportedOperationException(); - } - - @Override - public Object getTransactionIdentifier(Transaction transaction) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean canRegisterSynchronization() { - throw new UnsupportedOperationException(); - } - - @Override - public void registerSynchronization(Synchronization synchronization) { - throw new UnsupportedOperationException(); - } - - @Override - public int getCurrentStatus() { - throw new UnsupportedOperationException(); - } - - } - - static class HideDataScriptClassLoader extends URLClassLoader { - - private static final List HIDDEN_RESOURCES = Arrays.asList("schema-all.sql", "schema.sql"); - - HideDataScriptClassLoader() { - super(new URL[0], Thread.currentThread().getContextClassLoader()); - } - - @Override - public Enumeration getResources(String name) throws IOException { - if (HIDDEN_RESOURCES.contains(name)) { - return Collections.emptyEnumeration(); - } - return super.getResources(name); - } - - } - - @org.springframework.context.annotation.Configuration(proxyBeanMethods = false) - static class JpaUsingApplicationListenerConfiguration { - - @Bean - EventCapturingApplicationListener jpaUsingApplicationListener(EntityManagerFactory emf) { - return new EventCapturingApplicationListener(); - } - - static class EventCapturingApplicationListener implements ApplicationListener { - - private final List events = new ArrayList<>(); - - @Override - public void onApplicationEvent(ApplicationEvent event) { - this.events.add(event); - } - - } - - } - - @Configuration(proxyBeanMethods = false) - static class AsyncBootstrappingConfiguration { - - @Bean - ThreadPoolTaskExecutor ThreadPoolTaskExecutor() { - return new ThreadPoolTaskExecutor(); - } - - @Bean - EntityManagerFactoryBuilderCustomizer asyncBootstrappingCustomizer(ThreadPoolTaskExecutor executor) { - return (builder) -> builder.setBootstrapExecutor(executor); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestConfigurationWithLocalContainerEntityManagerFactoryBeanWithNoJpaVendorAdapter - extends TestConfiguration { - - @Bean - LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { - LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); - factoryBean.setDataSource(dataSource); - factoryBean.setPersistenceUnitName("manually-configured"); - factoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); - Map properties = new HashMap<>(); - properties.put("configured", "manually"); - properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); - factoryBean.setJpaPropertyMap(properties); - return factoryBean; - } - - } - - public static class TestH2Dialect extends H2Dialect { - - } - - @Configuration(proxyBeanMethods = false) - static class JtaTransactionManagerConfiguration { - - @Bean - JtaTransactionManager jtaTransactionManager() { - JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(); - jtaTransactionManager.setUserTransaction(mock(UserTransaction.class)); - jtaTransactionManager.setTransactionManager(mock(TransactionManager.class)); - return jtaTransactionManager; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/domain/country/Country.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/domain/country/Country.java deleted file mode 100644 index 0535fadc6436..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/domain/country/Country.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.orm.jpa.domain.country; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import org.hibernate.envers.Audited; - -@Entity -public class Country implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Audited - @Column - private String name; - - public Long getId() { - return this.id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/test/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/test/City.java deleted file mode 100644 index f129a6b506bc..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/test/City.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.orm.jpa.test; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; - -@Entity -@EntityListeners(CityListener.class) -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String state; - - @Column(nullable = false) - private String country; - - @Column(nullable = false) - private String map; - - protected City() { - } - - public City(String name, String state, String country, String map) { - this.name = name; - this.state = state; - this.country = country; - this.map = map; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/jpa/City.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/jpa/City.java deleted file mode 100644 index 3171339f56a2..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/jpa/City.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.jpa; - -import java.io.Serializable; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; - -@Entity -public class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String state; - - @Column(nullable = false) - private String country; - - @Column(nullable = false) - private String map; - - protected City() { - } - - public City(String name, String state, String country, String map) { - this.name = name; - this.state = state; - this.country = country; - this.map = map; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/PathRequestTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/PathRequestTests.java deleted file mode 100644 index a5b14ed075c0..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/PathRequestTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.reactive; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link PathRequest}. - * - * @author Madhura Bhave - */ -class PathRequestTests { - - @Test - void toStaticResourcesShouldReturnStaticResourceRequest() { - assertThat(PathRequest.toStaticResources()).isInstanceOf(StaticResourceRequest.class); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/StaticResourceRequestTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/StaticResourceRequestTests.java deleted file mode 100644 index f658a00c4748..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/StaticResourceRequestTests.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.reactive; - -import java.time.Duration; - -import org.assertj.core.api.AssertDelegateTarget; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.security.StaticResourceLocation; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.context.support.StaticApplicationContext; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.http.server.reactive.MockServerHttpResponse; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; -import org.springframework.web.context.support.StaticWebApplicationContext; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebHandler; -import org.springframework.web.server.adapter.HttpWebHandlerAdapter; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link StaticResourceRequest}. - * - * @author Madhura Bhave - */ -class StaticResourceRequestTests { - - private final StaticResourceRequest resourceRequest = StaticResourceRequest.INSTANCE; - - @Test - void atCommonLocationsShouldMatchCommonLocations() { - ServerWebExchangeMatcher matcher = this.resourceRequest.atCommonLocations(); - assertMatcher(matcher).matches("/css/file.css"); - assertMatcher(matcher).matches("/js/file.js"); - assertMatcher(matcher).matches("/images/file.css"); - assertMatcher(matcher).matches("/webjars/file.css"); - assertMatcher(matcher).matches("/favicon.ico"); - assertMatcher(matcher).matches("/favicon.png"); - assertMatcher(matcher).matches("/icons/icon-48x48.png"); - assertMatcher(matcher).doesNotMatch("/bar"); - } - - @Test - void atCommonLocationsWithExcludeShouldNotMatchExcluded() { - ServerWebExchangeMatcher matcher = this.resourceRequest.atCommonLocations() - .excluding(StaticResourceLocation.CSS); - assertMatcher(matcher).doesNotMatch("/css/file.css"); - assertMatcher(matcher).matches("/js/file.js"); - } - - @Test - void atLocationShouldMatchLocation() { - ServerWebExchangeMatcher matcher = this.resourceRequest.at(StaticResourceLocation.CSS); - assertMatcher(matcher).matches("/css/file.css"); - assertMatcher(matcher).doesNotMatch("/js/file.js"); - } - - @Test - void atLocationsFromSetWhenSetIsNullShouldThrowException() { - assertThatIllegalArgumentException().isThrownBy(() -> this.resourceRequest.at(null)) - .withMessageContaining("'locations' must not be null"); - } - - @Test - void excludeFromSetWhenSetIsNullShouldThrowException() { - assertThatIllegalArgumentException().isThrownBy(() -> this.resourceRequest.atCommonLocations().excluding(null)) - .withMessageContaining("'locations' must not be null"); - } - - private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher) { - StaticWebApplicationContext context = new StaticWebApplicationContext(); - context.registerBean(ServerProperties.class); - return assertThat(new RequestMatcherAssert(context, matcher)); - } - - static class RequestMatcherAssert implements AssertDelegateTarget { - - private final StaticApplicationContext context; - - private final ServerWebExchangeMatcher matcher; - - RequestMatcherAssert(StaticApplicationContext context, ServerWebExchangeMatcher matcher) { - this.context = context; - this.matcher = matcher; - } - - void matches(String path) { - ServerWebExchange exchange = webHandler().createExchange(MockServerHttpRequest.get(path).build(), - new MockServerHttpResponse()); - matches(exchange); - } - - private void matches(ServerWebExchange exchange) { - assertThat(this.matcher.matches(exchange).block(Duration.ofSeconds(30)).isMatch()) - .as("Matches " + getRequestPath(exchange)) - .isTrue(); - } - - void doesNotMatch(String path) { - ServerWebExchange exchange = webHandler().createExchange(MockServerHttpRequest.get(path).build(), - new MockServerHttpResponse()); - doesNotMatch(exchange); - } - - private void doesNotMatch(ServerWebExchange exchange) { - assertThat(this.matcher.matches(exchange).block(Duration.ofSeconds(30)).isMatch()) - .as("Does not match " + getRequestPath(exchange)) - .isFalse(); - } - - private TestHttpWebHandlerAdapter webHandler() { - TestHttpWebHandlerAdapter adapter = new TestHttpWebHandlerAdapter(mock(WebHandler.class)); - adapter.setApplicationContext(this.context); - return adapter; - } - - private String getRequestPath(ServerWebExchange exchange) { - return exchange.getRequest().getPath().toString(); - } - - } - - static class TestHttpWebHandlerAdapter extends HttpWebHandlerAdapter { - - TestHttpWebHandlerAdapter(WebHandler delegate) { - super(delegate); - } - - @Override - protected ServerWebExchange createExchange(ServerHttpRequest request, ServerHttpResponse response) { - return super.createExchange(request, response); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/PathRequestTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/PathRequestTests.java deleted file mode 100644 index 982e7f60ceba..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/PathRequestTests.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.servlet; - -import jakarta.servlet.http.HttpServletRequest; -import org.assertj.core.api.AssertDelegateTarget; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.h2.H2ConsoleProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockServletContext; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.StringUtils; -import org.springframework.web.context.WebApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link PathRequest}. - * - * @author Madhura Bhave - */ -class PathRequestTests { - - @Test - void toStaticResourcesShouldReturnStaticResourceRequest() { - assertThat(PathRequest.toStaticResources()).isInstanceOf(StaticResourceRequest.class); - } - - @Test - void toH2ConsoleShouldMatchH2ConsolePath() { - RequestMatcher matcher = PathRequest.toH2Console(); - assertMatcher(matcher).matches("/h2-console"); - assertMatcher(matcher).matches("/h2-console/subpath"); - assertMatcher(matcher).doesNotMatch("/js/file.js"); - } - - @Test - void toH2ConsoleWhenManagementContextShouldNeverMatch() { - RequestMatcher matcher = PathRequest.toH2Console(); - assertMatcher(matcher, "management").doesNotMatch("/h2-console"); - assertMatcher(matcher, "management").doesNotMatch("/h2-console/subpath"); - assertMatcher(matcher, "management").doesNotMatch("/js/file.js"); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher) { - return assertMatcher(matcher, null); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String serverNamespace) { - TestWebApplicationContext context = new TestWebApplicationContext(serverNamespace); - context.registerBean(ServerProperties.class); - context.registerBean(H2ConsoleProperties.class); - return assertThat(new RequestMatcherAssert(context, matcher)); - } - - static class RequestMatcherAssert implements AssertDelegateTarget { - - private final WebApplicationContext context; - - private final RequestMatcher matcher; - - RequestMatcherAssert(WebApplicationContext context, RequestMatcher matcher) { - this.context = context; - this.matcher = matcher; - } - - void matches(String path) { - matches(mockRequest(path)); - } - - private void matches(HttpServletRequest request) { - assertThat(this.matcher.matches(request)).as("Matches " + getRequestPath(request)).isTrue(); - } - - void doesNotMatch(String path) { - doesNotMatch(mockRequest(path)); - } - - private void doesNotMatch(HttpServletRequest request) { - assertThat(this.matcher.matches(request)).as("Does not match " + getRequestPath(request)).isFalse(); - } - - private MockHttpServletRequest mockRequest(String path) { - MockServletContext servletContext = new MockServletContext(); - servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); - MockHttpServletRequest request = new MockHttpServletRequest(servletContext); - request.setRequestURI(path); - return request; - } - - private String getRequestPath(HttpServletRequest request) { - String url = request.getServletPath(); - if (StringUtils.hasText(request.getRequestURI())) { - url += request.getRequestURI(); - } - return url; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationTests.java deleted file mode 100644 index 05b7005fd282..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.servlet; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.ConverterBean; -import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.DeserializerBean; -import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.ExampleController; -import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.JacksonModuleBean; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.mock.web.MockServletContext; - -/** - * Tests for {@link SecurityFilterAutoConfiguration}. - * - * @author Andy Wilkinson - */ -class SecurityFilterAutoConfigurationTests { - - @Test - void filterAutoConfigurationWorksWithoutSecurityAutoConfiguration() { - try (AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext()) { - context.setServletContext(new MockServletContext()); - context.register(Config.class); - context.refresh(); - } - } - - @Configuration(proxyBeanMethods = false) - @Import({ DeserializerBean.class, JacksonModuleBean.class, ExampleController.class, ConverterBean.class }) - @ImportAutoConfiguration({ WebMvcAutoConfiguration.class, JacksonAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - SecurityFilterAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/StaticResourceRequestTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/StaticResourceRequestTests.java deleted file mode 100644 index 5f181732e772..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/StaticResourceRequestTests.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.servlet; - -import jakarta.servlet.http.HttpServletRequest; -import org.assertj.core.api.AssertDelegateTarget; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.security.StaticResourceLocation; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockServletContext; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.StringUtils; -import org.springframework.web.context.WebApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link StaticResourceRequest}. - * - * @author Madhura Bhave - * @author Phillip Webb - */ -class StaticResourceRequestTests { - - private final StaticResourceRequest resourceRequest = StaticResourceRequest.INSTANCE; - - @Test - void atCommonLocationsShouldMatchCommonLocations() { - RequestMatcher matcher = this.resourceRequest.atCommonLocations(); - assertMatcher(matcher).matches("/css/file.css"); - assertMatcher(matcher).matches("/js/file.js"); - assertMatcher(matcher).matches("/images/file.css"); - assertMatcher(matcher).matches("/webjars/file.css"); - assertMatcher(matcher).matches("/favicon.ico"); - assertMatcher(matcher).matches("/favicon.png"); - assertMatcher(matcher).matches("/icons/icon-48x48.png"); - assertMatcher(matcher).doesNotMatch("/bar"); - } - - @Test - void atCommonLocationsWhenManagementContextShouldNeverMatch() { - RequestMatcher matcher = this.resourceRequest.atCommonLocations(); - assertMatcher(matcher, "management").doesNotMatch("/css/file.css"); - assertMatcher(matcher, "management").doesNotMatch("/js/file.js"); - assertMatcher(matcher, "management").doesNotMatch("/images/file.css"); - assertMatcher(matcher, "management").doesNotMatch("/webjars/file.css"); - assertMatcher(matcher, "management").doesNotMatch("/foo/favicon.ico"); - } - - @Test - void atCommonLocationsWithExcludeShouldNotMatchExcluded() { - RequestMatcher matcher = this.resourceRequest.atCommonLocations().excluding(StaticResourceLocation.CSS); - assertMatcher(matcher).doesNotMatch("/css/file.css"); - assertMatcher(matcher).matches("/js/file.js"); - } - - @Test - void atLocationShouldMatchLocation() { - RequestMatcher matcher = this.resourceRequest.at(StaticResourceLocation.CSS); - assertMatcher(matcher).matches("/css/file.css"); - assertMatcher(matcher).doesNotMatch("/js/file.js"); - } - - @Test - void atLocationWhenHasServletPathShouldMatchLocation() { - RequestMatcher matcher = this.resourceRequest.at(StaticResourceLocation.CSS); - assertMatcher(matcher, null, "/foo").matches("/foo", "/css/file.css"); - assertMatcher(matcher, null, "/foo").doesNotMatch("/foo", "/js/file.js"); - } - - @Test - void atLocationsFromSetWhenSetIsNullShouldThrowException() { - assertThatIllegalArgumentException().isThrownBy(() -> this.resourceRequest.at(null)) - .withMessageContaining("'locations' must not be null"); - } - - @Test - void excludeFromSetWhenSetIsNullShouldThrowException() { - assertThatIllegalArgumentException().isThrownBy(() -> this.resourceRequest.atCommonLocations().excluding(null)) - .withMessageContaining("'locations' must not be null"); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher) { - return assertMatcher(matcher, null, ""); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String serverNamespace) { - return assertMatcher(matcher, serverNamespace, ""); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String serverNamespace, String path) { - DispatcherServletPath dispatcherServletPath = () -> path; - TestWebApplicationContext context = new TestWebApplicationContext(serverNamespace); - context.registerBean(DispatcherServletPath.class, () -> dispatcherServletPath); - return assertThat(new RequestMatcherAssert(context, matcher)); - } - - static class RequestMatcherAssert implements AssertDelegateTarget { - - private final WebApplicationContext context; - - private final RequestMatcher matcher; - - RequestMatcherAssert(WebApplicationContext context, RequestMatcher matcher) { - this.context = context; - this.matcher = matcher; - } - - void matches(String path) { - matches(mockRequest(path)); - } - - void matches(String servletPath, String path) { - matches(mockRequest(servletPath, path)); - } - - private void matches(HttpServletRequest request) { - assertThat(this.matcher.matches(request)).as("Matches " + getRequestPath(request)).isTrue(); - } - - void doesNotMatch(String path) { - doesNotMatch(mockRequest(path)); - } - - void doesNotMatch(String servletPath, String path) { - doesNotMatch(mockRequest(servletPath, path)); - } - - private void doesNotMatch(HttpServletRequest request) { - assertThat(this.matcher.matches(request)).as("Does not match " + getRequestPath(request)).isFalse(); - } - - private MockHttpServletRequest mockRequest(String path) { - return mockRequest(null, path); - } - - private MockHttpServletRequest mockRequest(String servletPath, String path) { - MockServletContext servletContext = new MockServletContext(); - servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); - MockHttpServletRequest request = new MockHttpServletRequest(servletContext); - if (servletPath != null) { - request.setServletPath(servletPath); - request.setRequestURI(servletPath + path); - } - else { - request.setRequestURI(path); - } - return request; - } - - private String getRequestPath(HttpServletRequest request) { - String url = request.getServletPath(); - if (StringUtils.hasText(request.getRequestURI())) { - url += request.getRequestURI(); - } - return url; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/user/User.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/user/User.java deleted file mode 100644 index a5dac0b8391a..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/user/User.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.user; - -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; - -@Entity -public class User { - - @Id - @GeneratedValue - private Long id; - - private String email; - - public User() { - } - - public User(String email) { - this.email = email; - } - - public Long getId() { - return this.id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getEmail() { - return this.email; - } - - public void setEmail(String email) { - this.email = email; - } - - @Override - public String toString() { - return getClass().getSimpleName() + ":" + this.id; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/user/UserRepository.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/user/UserRepository.java deleted file mode 100644 index 9be0e42b1bd1..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/user/UserRepository.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.security.user; - -import org.springframework.data.jpa.repository.JpaRepository; - -interface UserRepository extends JpaRepository { - - User findByEmail(String email); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/AbstractSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/AbstractSessionAutoConfigurationTests.java deleted file mode 100644 index 8b51ef20ab26..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/AbstractSessionAutoConfigurationTests.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.util.Collections; -import java.util.function.Consumer; - -import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.web.server.MockServerWebExchange; -import org.springframework.session.MapSessionRepository; -import org.springframework.session.ReactiveSessionRepository; -import org.springframework.session.SessionRepository; -import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; -import org.springframework.session.web.http.SessionRepositoryFilter; -import org.springframework.web.server.WebSession; -import org.springframework.web.server.session.WebSessionManager; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Shared test utilities for {@link SessionAutoConfiguration} tests. - * - * @author Stephane Nicoll - * @author Weix Sun - */ -public abstract class AbstractSessionAutoConfigurationTests { - - private static final MockReactiveWebServerFactory mockReactiveWebServerFactory = new MockReactiveWebServerFactory(); - - protected ContextConsumer assertExchangeWithSession( - Consumer exchange) { - return (context) -> { - MockServerHttpRequest request = MockServerHttpRequest.get("/").build(); - MockServerWebExchange webExchange = MockServerWebExchange.from(request); - WebSessionManager webSessionManager = context.getBean(WebSessionManager.class); - WebSession webSession = webSessionManager.getSession(webExchange).block(); - webSession.start(); - webExchange.getResponse().setComplete().block(); - exchange.accept(webExchange); - }; - } - - protected > T validateSessionRepository(AssertableWebApplicationContext context, - Class type) { - assertThat(context).hasSingleBean(SessionRepositoryFilter.class); - assertThat(context).hasSingleBean(SessionRepository.class); - SessionRepository repository = context.getBean(SessionRepository.class); - assertThat(repository).as("Wrong session repository type").isInstanceOf(type); - return type.cast(repository); - } - - protected > T validateSessionRepository( - AssertableReactiveWebApplicationContext context, Class type) { - assertThat(context).hasSingleBean(WebSessionManager.class); - assertThat(context).hasSingleBean(ReactiveSessionRepository.class); - ReactiveSessionRepository repository = context.getBean(ReactiveSessionRepository.class); - assertThat(repository).as("Wrong session repository type").isInstanceOf(type); - return type.cast(repository); - } - - @Configuration - @EnableSpringHttpSession - static class SessionRepositoryConfiguration { - - @Bean - MapSessionRepository mySessionRepository() { - return new MapSessionRepository(Collections.emptyMap()); - } - - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - MockReactiveWebServerFactory mockReactiveWebServerFactory() { - return mockReactiveWebServerFactory; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationHazelcastTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationHazelcastTests.java deleted file mode 100644 index 0bb01c90f326..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationHazelcastTests.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.time.Duration; - -import com.hazelcast.core.HazelcastInstance; -import com.hazelcast.map.IMap; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.session.FlushMode; -import org.springframework.session.SaveMode; -import org.springframework.session.config.SessionRepositoryCustomizer; -import org.springframework.session.data.mongo.MongoIndexedSessionRepository; -import org.springframework.session.data.redis.RedisIndexedSessionRepository; -import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository; -import org.springframework.session.jdbc.JdbcIndexedSessionRepository; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Hazelcast specific tests for {@link SessionAutoConfiguration}. - * - * @author Vedran Pavic - */ -class SessionAutoConfigurationHazelcastTests extends AbstractSessionAutoConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withClassLoader(new FilteredClassLoader(JdbcIndexedSessionRepository.class, - RedisIndexedSessionRepository.class, MongoIndexedSessionRepository.class)) - .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class)) - .withUserConfiguration(HazelcastConfiguration.class); - - @Test - void defaultConfig() { - this.contextRunner.run(this::validateDefaultConfig); - } - - @Test - void hazelcastTakesPrecedenceOverMongo() { - this.contextRunner - .withClassLoader( - new FilteredClassLoader(RedisIndexedSessionRepository.class, JdbcIndexedSessionRepository.class)) - .run(this::validateDefaultConfig); - } - - @Test - void defaultConfigWithCustomTimeout() { - this.contextRunner.withPropertyValues("spring.session.timeout=1m").run((context) -> { - HazelcastIndexedSessionRepository repository = validateSessionRepository(context, - HazelcastIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); - }); - } - - private void validateDefaultConfig(AssertableWebApplicationContext context) { - HazelcastIndexedSessionRepository repository = validateSessionRepository(context, - HazelcastIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", - new ServerProperties().getServlet().getSession().getTimeout()); - HazelcastInstance hazelcastInstance = context.getBean(HazelcastInstance.class); - then(hazelcastInstance).should().getMap("spring:session:sessions"); - } - - @Test - void customMapName() { - this.contextRunner.withPropertyValues("spring.session.hazelcast.map-name=foo:bar:biz").run((context) -> { - validateSessionRepository(context, HazelcastIndexedSessionRepository.class); - HazelcastInstance hazelcastInstance = context.getBean(HazelcastInstance.class); - then(hazelcastInstance).should().getMap("foo:bar:biz"); - }); - } - - @Test - void customFlushMode() { - this.contextRunner.withPropertyValues("spring.session.hazelcast.flush-mode=immediate").run((context) -> { - HazelcastIndexedSessionRepository repository = validateSessionRepository(context, - HazelcastIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.IMMEDIATE); - }); - } - - @Test - void customSaveMode() { - this.contextRunner.withPropertyValues("spring.session.hazelcast.save-mode=on-get-attribute").run((context) -> { - HazelcastIndexedSessionRepository repository = validateSessionRepository(context, - HazelcastIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("saveMode", SaveMode.ON_GET_ATTRIBUTE); - }); - } - - @Test - void whenTheUserDefinesTheirOwnSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { - this.contextRunner.withUserConfiguration(CustomizerConfiguration.class) - .withPropertyValues("spring.session.hazelcast.save-mode=on-get-attribute") - .run((context) -> { - HazelcastIndexedSessionRepository repository = validateSessionRepository(context, - HazelcastIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("saveMode", SaveMode.ALWAYS); - }); - } - - @Configuration(proxyBeanMethods = false) - static class HazelcastConfiguration { - - @Bean - @SuppressWarnings("unchecked") - HazelcastInstance hazelcastInstance() { - IMap map = mock(IMap.class); - HazelcastInstance mock = mock(HazelcastInstance.class); - given(mock.getMap("spring:session:sessions")).willReturn(map); - given(mock.getMap("foo:bar:biz")).willReturn(map); - return mock; - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomizerConfiguration { - - @Bean - SessionRepositoryCustomizer sessionRepositoryCustomizer() { - return (repository) -> repository.setSaveMode(SaveMode.ALWAYS); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java deleted file mode 100644 index 0c647e4205b4..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.time.Duration; - -import javax.sql.DataSource; - -import org.apache.commons.dbcp2.BasicDataSource; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; -import org.springframework.boot.sql.init.DatabaseInitializationMode; -import org.springframework.boot.sql.init.DatabaseInitializationSettings; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.jdbc.BadSqlGrammarException; -import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.session.FlushMode; -import org.springframework.session.SaveMode; -import org.springframework.session.data.mongo.MongoIndexedSessionRepository; -import org.springframework.session.data.redis.RedisIndexedSessionRepository; -import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository; -import org.springframework.session.jdbc.JdbcIndexedSessionRepository; -import org.springframework.session.jdbc.PostgreSqlJdbcIndexedSessionRepositoryCustomizer; -import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * JDBC specific tests for {@link SessionAutoConfiguration}. - * - * @author Vedran Pavic - * @author Stephane Nicoll - */ -class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfigurationTests { - - private WebApplicationContextRunner contextRunner; - - @BeforeEach - void prepareRunner() { - this.contextRunner = new WebApplicationContextRunner() - .withClassLoader(new FilteredClassLoader(Thread.currentThread().getContextClassLoader(), - HazelcastIndexedSessionRepository.class, MongoIndexedSessionRepository.class, - RedisIndexedSessionRepository.class)) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, - SessionAutoConfiguration.class)) - .withPropertyValues("spring.datasource.generate-unique-name=true"); - } - - @Test - void defaultConfig() { - this.contextRunner.run(this::validateDefaultConfig); - } - - @Test - void jdbcTakesPrecedenceOverMongoAndHazelcast() { - this.contextRunner.withClassLoader(new FilteredClassLoader(RedisIndexedSessionRepository.class)) - .run(this::validateDefaultConfig); - } - - private void validateDefaultConfig(AssertableWebApplicationContext context) { - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", - new ServerProperties().getServlet().getSession().getTimeout()); - assertThat(repository).hasFieldOrPropertyWithValue("tableName", "SPRING_SESSION"); - assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", "0 * * * * *"); - assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema()) - .isEqualTo(DatabaseInitializationMode.EMBEDDED); - assertThat(context.getBean(JdbcOperations.class).queryForList("select * from SPRING_SESSION")).isEmpty(); - } - - @Test - void filterOrderCanBeCustomized() { - this.contextRunner.withPropertyValues("spring.session.servlet.filter-order=123").run((context) -> { - AbstractFilterRegistrationBean registration = context.getBean(AbstractFilterRegistrationBean.class); - assertThat(registration.getOrder()).isEqualTo(123); - }); - } - - @Test - void disableDataSourceInitializer() { - this.contextRunner.withPropertyValues("spring.session.jdbc.initialize-schema=never").run((context) -> { - assertThat(context).doesNotHaveBean(JdbcSessionDataSourceScriptDatabaseInitializer.class); - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("tableName", "SPRING_SESSION"); - assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema()) - .isEqualTo(DatabaseInitializationMode.NEVER); - assertThatExceptionOfType(BadSqlGrammarException.class) - .isThrownBy(() -> context.getBean(JdbcOperations.class).queryForList("select * from SPRING_SESSION")); - }); - } - - @Test - void customTimeout() { - this.contextRunner.withPropertyValues("spring.session.timeout=1m").run((context) -> { - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); - }); - } - - @Test - void customTableName() { - this.contextRunner.withPropertyValues("spring.session.jdbc.table-name=FOO_BAR", - "spring.session.jdbc.schema=classpath:org/springframework/boot/autoconfigure/session/custom-schema-h2.sql") - .run((context) -> { - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("tableName", "FOO_BAR"); - assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema()) - .isEqualTo(DatabaseInitializationMode.EMBEDDED); - assertThat(context.getBean(JdbcOperations.class).queryForList("select * from FOO_BAR")).isEmpty(); - }); - } - - @Test - void customCleanupCron() { - this.contextRunner.withPropertyValues("spring.session.jdbc.cleanup-cron=0 0 12 * * *").run((context) -> { - assertThat(context.getBean(JdbcSessionProperties.class).getCleanupCron()).isEqualTo("0 0 12 * * *"); - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", "0 0 12 * * *"); - }); - } - - @Test - void customFlushMode() { - this.contextRunner.withPropertyValues("spring.session.jdbc.flush-mode=immediate").run((context) -> { - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.IMMEDIATE); - }); - } - - @Test - void customSaveMode() { - this.contextRunner.withPropertyValues("spring.session.jdbc.save-mode=on-get-attribute").run((context) -> { - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("saveMode", SaveMode.ON_GET_ATTRIBUTE); - }); - } - - @Test - void sessionDataSourceIsUsedWhenAvailable() { - this.contextRunner.withUserConfiguration(SessionDataSourceConfiguration.class).run((context) -> { - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - DataSource sessionDataSource = context.getBean("sessionDataSource", DataSource.class); - assertThat(repository).extracting("jdbcOperations.dataSource").isEqualTo(sessionDataSource); - assertThat(context.getBean(JdbcSessionDataSourceScriptDatabaseInitializer.class)) - .hasFieldOrPropertyWithValue("dataSource", sessionDataSource); - assertThatExceptionOfType(BadSqlGrammarException.class) - .isThrownBy(() -> context.getBean(JdbcOperations.class).queryForList("select * from SPRING_SESSION")); - }); - } - - @Test - void sessionRepositoryBeansDependOnJdbcSessionDataSourceInitializer() { - this.contextRunner.run((context) -> { - ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); - String[] sessionRepositoryNames = beanFactory.getBeanNamesForType(JdbcIndexedSessionRepository.class); - assertThat(sessionRepositoryNames).isNotEmpty(); - for (String sessionRepositoryName : sessionRepositoryNames) { - assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn()) - .contains("jdbcSessionDataSourceScriptDatabaseInitializer"); - } - }); - } - - @Test - void sessionRepositoryBeansDependOnFlyway() { - this.contextRunner.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) - .withPropertyValues("spring.session.jdbc.initialize-schema=never") - .run((context) -> { - ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); - String[] sessionRepositoryNames = beanFactory.getBeanNamesForType(JdbcIndexedSessionRepository.class); - assertThat(sessionRepositoryNames).isNotEmpty(); - for (String sessionRepositoryName : sessionRepositoryNames) { - assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn()).contains("flyway", - "flywayInitializer"); - } - }); - } - - @Test - @WithResource(name = "db/changelog/db.changelog-master.yaml", content = "databaseChangeLog:") - void sessionRepositoryBeansDependOnLiquibase() { - this.contextRunner.withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class)) - .withPropertyValues("spring.session.jdbc.initialize-schema=never") - .run((context) -> { - ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); - String[] sessionRepositoryNames = beanFactory.getBeanNamesForType(JdbcIndexedSessionRepository.class); - assertThat(sessionRepositoryNames).isNotEmpty(); - for (String sessionRepositoryName : sessionRepositoryNames) { - assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn()) - .contains("liquibase"); - } - }); - } - - @Test - void whenTheUserDefinesTheirOwnJdbcSessionDatabaseInitializerThenTheAutoConfiguredInitializerBacksOff() { - this.contextRunner.withUserConfiguration(CustomJdbcSessionDatabaseInitializerConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - DataSourceTransactionManagerAutoConfiguration.class)) - .run((context) -> assertThat(context).hasSingleBean(JdbcSessionDataSourceScriptDatabaseInitializer.class) - .doesNotHaveBean("jdbcSessionDataSourceScriptDatabaseInitializer") - .hasBean("customInitializer")); - } - - @Test - void whenTheUserDefinesTheirOwnDatabaseInitializerThenTheAutoConfiguredJdbcSessionInitializerRemains() { - this.contextRunner.withUserConfiguration(CustomDatabaseInitializerConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - DataSourceTransactionManagerAutoConfiguration.class)) - .run((context) -> assertThat(context).hasSingleBean(JdbcSessionDataSourceScriptDatabaseInitializer.class) - .hasBean("customInitializer")); - } - - @Test - void whenTheUserDefinesTheirOwnJdbcIndexedSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { - String expectedCreateSessionAttributeQuery = """ - INSERT INTO SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) - VALUES (?, ?, ?) - ON CONFLICT (SESSION_PRIMARY_ID, ATTRIBUTE_NAME) - DO UPDATE SET ATTRIBUTE_BYTES = EXCLUDED.ATTRIBUTE_BYTES - """; - this.contextRunner.withUserConfiguration(CustomJdbcIndexedSessionRepositoryCustomizerConfiguration.class) - .withConfiguration(AutoConfigurations.of(JdbcSessionConfiguration.class)) - .run((context) -> { - JdbcIndexedSessionRepository repository = validateSessionRepository(context, - JdbcIndexedSessionRepository.class); - assertThat(repository).hasFieldOrPropertyWithValue("createSessionAttributeQuery", - expectedCreateSessionAttributeQuery); - }); - } - - @Configuration - static class SessionDataSourceConfiguration { - - @Bean - @SpringSessionDataSource - DataSource sessionDataSource() { - BasicDataSource dataSource = new BasicDataSource(); - dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); - dataSource.setUrl("jdbc:hsqldb:mem:sessiondb"); - dataSource.setUsername("sa"); - return dataSource; - } - - @Bean - @Primary - DataSource mainDataSource() { - BasicDataSource dataSource = new BasicDataSource(); - dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); - dataSource.setUrl("jdbc:hsqldb:mem:maindb"); - dataSource.setUsername("sa"); - return dataSource; - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomJdbcSessionDatabaseInitializerConfiguration { - - @Bean - JdbcSessionDataSourceScriptDatabaseInitializer customInitializer(DataSource dataSource, - JdbcSessionProperties properties) { - return new JdbcSessionDataSourceScriptDatabaseInitializer(dataSource, properties); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomDatabaseInitializerConfiguration { - - @Bean - DataSourceScriptDatabaseInitializer customInitializer(DataSource dataSource) { - return new DataSourceScriptDatabaseInitializer(dataSource, new DatabaseInitializationSettings()); - } - - } - - @Configuration - static class CustomJdbcIndexedSessionRepositoryCustomizerConfiguration { - - @Bean - PostgreSqlJdbcIndexedSessionRepositoryCustomizer postgreSqlJdbcIndexedSessionRepositoryCustomizer() { - return new PostgreSqlJdbcIndexedSessionRepositoryCustomizer(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationWithoutSecurityTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationWithoutSecurityTests.java deleted file mode 100644 index 09219dbfa4b8..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationWithoutSecurityTests.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.session.web.http.DefaultCookieSerializer; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SessionAutoConfiguration} when Spring Security is not on the - * classpath. - * - * @author Vedran Pavic - */ -@ClassPathExclusions("spring-security-*") -class SessionAutoConfigurationWithoutSecurityTests extends AbstractSessionAutoConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class)); - - @Test - void sessionCookieConfigurationIsAppliedToAutoConfiguredCookieSerializer() { - this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> { - DefaultCookieSerializer cookieSerializer = context.getBean(DefaultCookieSerializer.class); - assertThat(cookieSerializer).hasFieldOrPropertyWithValue("rememberMeRequestAttribute", null); - }); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionPropertiesTests.java deleted file mode 100644 index 552079cbfdd6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionPropertiesTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.session; - -import java.time.Duration; -import java.util.function.Supplier; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link SessionProperties}. - * - * @author Stephane Nicoll - */ -class SessionPropertiesTests { - - @Test - @SuppressWarnings("unchecked") - void determineTimeoutWithTimeoutIgnoreFallback() { - SessionProperties properties = new SessionProperties(); - properties.setTimeout(Duration.ofMinutes(1)); - Supplier fallback = mock(Supplier.class); - assertThat(properties.determineTimeout(fallback)).isEqualTo(Duration.ofMinutes(1)); - then(fallback).shouldHaveNoInteractions(); - } - - @Test - void determineTimeoutWithNoTimeoutUseFallback() { - SessionProperties properties = new SessionProperties(); - properties.setTimeout(null); - Duration fallback = Duration.ofMinutes(2); - assertThat(properties.determineTimeout(() -> fallback)).isSameAs(fallback); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfigurationTests.java deleted file mode 100644 index aef396a2a085..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfigurationTests.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.sql.init; - -import javax.sql.DataSource; - -import io.r2dbc.spi.ConnectionFactory; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; -import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; -import org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializer; -import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer; -import org.springframework.boot.sql.init.DatabaseInitializationSettings; -import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.datasource.init.DatabasePopulator; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SqlInitializationAutoConfiguration}. - * - * @author Andy Wilkinson - */ -class SqlInitializationAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SqlInitializationAutoConfiguration.class)) - .withPropertyValues("spring.datasource.generate-unique-name:true", "spring.r2dbc.generate-unique-name:true"); - - @Test - void whenNoDataSourceOrConnectionFactoryIsAvailableThenAutoConfigurationBacksOff() { - this.contextRunner - .run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class)); - } - - @Test - void whenConnectionFactoryIsAvailableThenR2dbcInitializerIsAutoConfigured() { - this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) - .run((context) -> assertThat(context).hasSingleBean(R2dbcScriptDatabaseInitializer.class)); - } - - @Test - void whenConnectionFactoryIsAvailableAndModeIsNeverThenInitializerIsNotAutoConfigured() { - this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) - .withPropertyValues("spring.sql.init.mode:never") - .run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class)); - } - - @Test - void whenDataSourceIsAvailableThenDataSourceInitializerIsAutoConfigured() { - this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .run((context) -> assertThat(context).hasSingleBean(DataSourceScriptDatabaseInitializer.class)); - } - - @Test - void whenDataSourceIsAvailableAndModeIsNeverThenThenInitializerIsNotAutoConfigured() { - this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withPropertyValues("spring.sql.init.mode:never") - .run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class)); - } - - @Test - void whenDataSourceAndConnectionFactoryAreAvailableThenOnlyR2dbcInitializerIsAutoConfigured() { - this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) - .withUserConfiguration(DataSourceAutoConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ConnectionFactory.class) - .hasSingleBean(DataSource.class) - .hasSingleBean(R2dbcScriptDatabaseInitializer.class) - .doesNotHaveBean(DataSourceScriptDatabaseInitializer.class)); - } - - @Test - void whenAnSqlInitializerIsDefinedThenInitializerIsNotAutoConfigured() { - this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) - .withUserConfiguration(DataSourceAutoConfiguration.class, SqlDatabaseInitializerConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(AbstractScriptDatabaseInitializer.class) - .hasBean("customInitializer")); - } - - @Test - void whenAnInitializerIsDefinedThenSqlInitializerIsStillAutoConfigured() { - this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withUserConfiguration(DatabaseInitializerConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(SqlDataSourceScriptDatabaseInitializer.class) - .hasBean("customInitializer")); - } - - @Test - void whenBeanIsAnnotatedAsDependingOnDatabaseInitializationThenItDependsOnR2dbcScriptDatabaseInitializer() { - this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) - .withUserConfiguration(DependsOnInitializedDatabaseConfiguration.class) - .run((context) -> { - ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); - BeanDefinition beanDefinition = beanFactory.getBeanDefinition( - "sqlInitializationAutoConfigurationTests.DependsOnInitializedDatabaseConfiguration"); - assertThat(beanDefinition.getDependsOn()).containsExactlyInAnyOrder("r2dbcScriptDatabaseInitializer"); - }); - } - - @Test - void whenBeanIsAnnotatedAsDependingOnDatabaseInitializationThenItDependsOnDataSourceScriptDatabaseInitializer() { - this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withUserConfiguration(DependsOnInitializedDatabaseConfiguration.class) - .run((context) -> { - ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); - BeanDefinition beanDefinition = beanFactory.getBeanDefinition( - "sqlInitializationAutoConfigurationTests.DependsOnInitializedDatabaseConfiguration"); - assertThat(beanDefinition.getDependsOn()) - .containsExactlyInAnyOrder("dataSourceScriptDatabaseInitializer"); - }); - } - - @Test - void whenADataSourceIsAvailableAndSpringJdbcIsNotThenAutoConfigurationBacksOff() { - this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(DatabasePopulator.class)) - .run((context) -> { - assertThat(context).hasSingleBean(DataSource.class); - assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class); - }); - } - - @Test - void whenAConnectionFactoryIsAvailableAndSpringR2dbcIsNotThenAutoConfigurationBacksOff() { - this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(org.springframework.r2dbc.connection.init.DatabasePopulator.class)) - .run((context) -> { - assertThat(context).hasSingleBean(ConnectionFactory.class); - assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class); - }); - } - - @Configuration(proxyBeanMethods = false) - static class SqlDatabaseInitializerConfiguration { - - @Bean - SqlDataSourceScriptDatabaseInitializer customInitializer() { - return new SqlDataSourceScriptDatabaseInitializer(null, new DatabaseInitializationSettings()) { - - @Override - protected void runScripts(Scripts scripts) { - // No-op - } - - @Override - protected boolean isEmbeddedDatabase() { - return true; - } - - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DatabaseInitializerConfiguration { - - @Bean - DataSourceScriptDatabaseInitializer customInitializer() { - return new DataSourceScriptDatabaseInitializer(null, new DatabaseInitializationSettings()) { - - @Override - protected void runScripts(Scripts scripts) { - // No-op - } - - @Override - protected boolean isEmbeddedDatabase() { - return true; - } - - }; - } - - } - - @Configuration(proxyBeanMethods = false) - @DependsOnDatabaseInitialization - static class DependsOnInitializedDatabaseConfiguration { - - DependsOnInitializedDatabaseConfiguration() { - - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/TemplateAvailabilityProvidersTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/TemplateAvailabilityProvidersTests.java index b3c9951bad52..d23c162d9edf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/TemplateAvailabilityProvidersTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/TemplateAvailabilityProvidersTests.java @@ -16,6 +16,10 @@ package org.springframework.boot.autoconfigure.template; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.Collection; import java.util.Collections; @@ -25,7 +29,9 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.context.ApplicationContext; +import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; import org.springframework.mock.env.MockEnvironment; @@ -71,11 +77,14 @@ void createWhenApplicationContextIsNullShouldThrowException() { } @Test + @SuppressWarnings("rawtypes") + @WithTestTemplateAvailabilityProvider void createWhenUsingApplicationContextShouldLoadProviders() { ApplicationContext applicationContext = mock(ApplicationContext.class); - given(applicationContext.getClassLoader()).willReturn(this.classLoader); + given(applicationContext.getClassLoader()).willReturn(Thread.currentThread().getContextClassLoader()); TemplateAvailabilityProviders providers = new TemplateAvailabilityProviders(applicationContext); - assertThat(providers.getProviders()).isNotEmpty(); + assertThat(providers.getProviders()).extracting((provider) -> (Class) provider.getClass()) + .containsExactly(TestTemplateAvailabilityProvider.class); then(applicationContext).should().getClassLoader(); } @@ -86,8 +95,10 @@ void createWhenClassLoaderIsNullShouldThrowException() { } @Test + @WithTestTemplateAvailabilityProvider void createWhenUsingClassLoaderShouldLoadProviders() { - TemplateAvailabilityProviders providers = new TemplateAvailabilityProviders(this.classLoader); + TemplateAvailabilityProviders providers = new TemplateAvailabilityProviders( + Thread.currentThread().getContextClassLoader()); assertThat(providers.getProviders()).isNotEmpty(); } @@ -187,4 +198,23 @@ void getProviderWhenCacheDisabledShouldNotUseCache() { .isTemplateAvailable(this.view, this.environment, this.classLoader, this.resourceLoader); } + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @WithResource(name = "META-INF/spring.factories", + content = "org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=" + + "org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvidersTests$TestTemplateAvailabilityProvider") + @interface WithTestTemplateAvailabilityProvider { + + } + + static class TestTemplateAvailabilityProvider implements TemplateAvailabilityProvider { + + @Override + public boolean isTemplateAvailable(String view, Environment environment, ClassLoader classLoader, + ResourceLoader resourceLoader) { + return false; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/TemplateRuntimeHintsTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/TemplateRuntimeHintsTests.java index b7d8b93e84bf..d876214ee41b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/TemplateRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/TemplateRuntimeHintsTests.java @@ -25,6 +25,7 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.beans.factory.aot.AotServices; import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.core.io.ClassPathResource; import static org.assertj.core.api.Assertions.assertThat; @@ -46,8 +47,9 @@ void templateRuntimeHintsIsRegistered() { } @Test + @WithResource(name = "templates/test.html") void contributeWhenTemplateLocationExists() { - RuntimeHints runtimeHints = contribute(getClass().getClassLoader()); + RuntimeHints runtimeHints = contribute(Thread.currentThread().getContextClassLoader()); assertThat(TEST_PREDICATE.test(runtimeHints)).isTrue(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/ViewResolverPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/ViewResolverPropertiesTests.java deleted file mode 100644 index a239cc048acc..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/template/ViewResolverPropertiesTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.template; - -import java.nio.charset.StandardCharsets; - -import org.junit.jupiter.api.Test; - -import org.springframework.util.MimeTypeUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link AbstractViewResolverProperties}. - * - * @author Stephane Nicoll - */ -class ViewResolverPropertiesTests { - - @Test - void defaultContentType() { - assertThat(new ViewResolverProperties().getContentType()).hasToString("text/html;charset=UTF-8"); - } - - @Test - void customContentTypeDefaultCharset() { - ViewResolverProperties properties = new ViewResolverProperties(); - properties.setContentType(MimeTypeUtils.parseMimeType("text/plain")); - assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-8"); - } - - @Test - void defaultContentTypeCustomCharset() { - ViewResolverProperties properties = new ViewResolverProperties(); - properties.setCharset(StandardCharsets.UTF_16); - assertThat(properties.getContentType()).hasToString("text/html;charset=UTF-16"); - } - - @Test - void customContentTypeCustomCharset() { - ViewResolverProperties properties = new ViewResolverProperties(); - properties.setContentType(MimeTypeUtils.parseMimeType("text/plain")); - properties.setCharset(StandardCharsets.UTF_16); - assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16"); - } - - @Test - void customContentTypeWithPropertyAndCustomCharset() { - ViewResolverProperties properties = new ViewResolverProperties(); - properties.setContentType(MimeTypeUtils.parseMimeType("text/plain;foo=bar")); - properties.setCharset(StandardCharsets.UTF_16); - assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16;foo=bar"); - } - - static class ViewResolverProperties extends AbstractViewResolverProperties { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java deleted file mode 100644 index 04dc5d445d96..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web; - -import java.net.InetAddress; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import io.undertow.UndertowOptions; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardContext; -import org.apache.catalina.core.StandardEngine; -import org.apache.catalina.valves.AccessLogValve; -import org.apache.catalina.valves.RemoteIpValve; -import org.apache.coyote.AbstractProtocol; -import org.apache.tomcat.util.net.AbstractEndpoint; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.junit.jupiter.api.Test; -import reactor.netty.http.HttpDecoderSpec; - -import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Accesslog; -import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.UseApr; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.source.ConfigurationPropertySource; -import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.jetty.JettyWebServer; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.MimeMappings; -import org.springframework.boot.web.server.MimeMappings.Mapping; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.unit.DataSize; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ServerProperties}. - * - * @author Dave Syer - * @author Stephane Nicoll - * @author Andy Wilkinson - * @author Phillip Webb - * @author Eddú Meléndez - * @author Quinten De Swaef - * @author Venil Noronha - * @author Andrew McGhie - * @author HaiTao Zhang - * @author Rafiullah Hamedy - * @author Chris Bono - * @author Parviz Rozikov - * @author Lasse Wulff - * @author Moritz Halbritter - */ -@DirtiesUrlFactories -class ServerPropertiesTests { - - private final ServerProperties properties = new ServerProperties(); - - @Test - void testAddressBinding() throws Exception { - bind("server.address", "127.0.0.1"); - assertThat(this.properties.getAddress()).isEqualTo(InetAddress.getByName("127.0.0.1")); - } - - @Test - void testPortBinding() { - bind("server.port", "9000"); - assertThat(this.properties.getPort().intValue()).isEqualTo(9000); - } - - @Test - void testServerHeaderDefault() { - assertThat(this.properties.getServerHeader()).isNull(); - } - - @Test - void testServerHeader() { - bind("server.server-header", "Custom Server"); - assertThat(this.properties.getServerHeader()).isEqualTo("Custom Server"); - } - - @Test - @SuppressWarnings("removal") - void testTomcatBinding() { - Map map = new HashMap<>(); - map.put("server.tomcat.accesslog.conditionIf", "foo"); - map.put("server.tomcat.accesslog.conditionUnless", "bar"); - map.put("server.tomcat.accesslog.pattern", "%h %t '%r' %s %b"); - map.put("server.tomcat.accesslog.prefix", "foo"); - map.put("server.tomcat.accesslog.suffix", "-bar.log"); - map.put("server.tomcat.accesslog.encoding", "UTF-8"); - map.put("server.tomcat.accesslog.locale", "en-AU"); - map.put("server.tomcat.accesslog.checkExists", "true"); - map.put("server.tomcat.accesslog.rotate", "false"); - map.put("server.tomcat.accesslog.rename-on-rotate", "true"); - map.put("server.tomcat.accesslog.ipv6Canonical", "true"); - map.put("server.tomcat.accesslog.request-attributes-enabled", "true"); - map.put("server.tomcat.remoteip.protocol-header", "X-Forwarded-Protocol"); - map.put("server.tomcat.remoteip.remote-ip-header", "Remote-Ip"); - map.put("server.tomcat.remoteip.internal-proxies", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); - map.put("server.tomcat.remoteip.trusted-proxies", "proxy1|proxy2|proxy3"); - map.put("server.tomcat.reject-illegal-header", "false"); - map.put("server.tomcat.background-processor-delay", "10"); - map.put("server.tomcat.relaxed-path-chars", "|,<"); - map.put("server.tomcat.relaxed-query-chars", "^ , | "); - map.put("server.tomcat.use-relative-redirects", "true"); - bind(map); - ServerProperties.Tomcat tomcat = this.properties.getTomcat(); - Accesslog accesslog = tomcat.getAccesslog(); - assertThat(accesslog.getConditionIf()).isEqualTo("foo"); - assertThat(accesslog.getConditionUnless()).isEqualTo("bar"); - assertThat(accesslog.getPattern()).isEqualTo("%h %t '%r' %s %b"); - assertThat(accesslog.getPrefix()).isEqualTo("foo"); - assertThat(accesslog.getSuffix()).isEqualTo("-bar.log"); - assertThat(accesslog.getEncoding()).isEqualTo("UTF-8"); - assertThat(accesslog.getLocale()).isEqualTo("en-AU"); - assertThat(accesslog.isCheckExists()).isTrue(); - assertThat(accesslog.isRotate()).isFalse(); - assertThat(accesslog.isRenameOnRotate()).isTrue(); - assertThat(accesslog.isIpv6Canonical()).isTrue(); - assertThat(accesslog.isRequestAttributesEnabled()).isTrue(); - assertThat(tomcat.getRemoteip().getRemoteIpHeader()).isEqualTo("Remote-Ip"); - assertThat(tomcat.getRemoteip().getProtocolHeader()).isEqualTo("X-Forwarded-Protocol"); - assertThat(tomcat.getRemoteip().getInternalProxies()).isEqualTo("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); - assertThat(tomcat.getRemoteip().getTrustedProxies()).isEqualTo("proxy1|proxy2|proxy3"); - assertThat(tomcat.getBackgroundProcessorDelay()).hasSeconds(10); - assertThat(tomcat.getRelaxedPathChars()).containsExactly('|', '<'); - assertThat(tomcat.getRelaxedQueryChars()).containsExactly('^', '|'); - assertThat(tomcat.isUseRelativeRedirects()).isTrue(); - } - - @Test - void testTrailingSlashOfContextPathIsRemoved() { - bind("server.servlet.context-path", "/foo/"); - assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/foo"); - } - - @Test - void testSlashOfContextPathIsDefaultValue() { - bind("server.servlet.context-path", "/"); - assertThat(this.properties.getServlet().getContextPath()).isEmpty(); - } - - @Test - void testContextPathWithLeadingWhitespace() { - bind("server.servlet.context-path", " /assets"); - assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/assets"); - } - - @Test - void testContextPathWithTrailingWhitespace() { - bind("server.servlet.context-path", "/assets/copy/ "); - assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/assets/copy"); - } - - @Test - void testContextPathWithLeadingAndTrailingWhitespace() { - bind("server.servlet.context-path", " /assets "); - assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/assets"); - } - - @Test - void testContextPathWithLeadingAndTrailingWhitespaceAndContextWithSpace() { - bind("server.servlet.context-path", " /assets /copy/ "); - assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/assets /copy"); - } - - @Test - void testDefaultMimeMapping() { - assertThat(this.properties.getMimeMappings()).isEmpty(); - } - - @Test - void testCustomizedMimeMapping() { - MimeMappings expectedMappings = new MimeMappings(); - expectedMappings.add("mjs", "text/javascript"); - bind("server.mime-mappings.mjs", "text/javascript"); - assertThat(this.properties.getMimeMappings()) - .containsExactly(expectedMappings.getAll().toArray(new Mapping[0])); - } - - @Test - void testCustomizeTomcatUriEncoding() { - bind("server.tomcat.uri-encoding", "US-ASCII"); - assertThat(this.properties.getTomcat().getUriEncoding()).isEqualTo(StandardCharsets.US_ASCII); - } - - @Test - void testCustomizeMaxHttpRequestHeaderSize() { - bind("server.max-http-request-header-size", "1MB"); - assertThat(this.properties.getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofMegabytes(1)); - } - - @Test - void testCustomizeMaxHttpRequestHeaderSizeUseBytesByDefault() { - bind("server.max-http-request-header-size", "1024"); - assertThat(this.properties.getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofKilobytes(1)); - } - - @Test - void testCustomizeTomcatMaxThreads() { - bind("server.tomcat.threads.max", "10"); - assertThat(this.properties.getTomcat().getThreads().getMax()).isEqualTo(10); - } - - @Test - void testCustomizeTomcatKeepAliveTimeout() { - bind("server.tomcat.keep-alive-timeout", "30s"); - assertThat(this.properties.getTomcat().getKeepAliveTimeout()).hasSeconds(30); - } - - @Test - void testCustomizeTomcatKeepAliveTimeoutWithInfinite() { - bind("server.tomcat.keep-alive-timeout", "-1"); - assertThat(this.properties.getTomcat().getKeepAliveTimeout()).hasMillis(-1); - } - - @Test - void testCustomizeTomcatMaxKeepAliveRequests() { - bind("server.tomcat.max-keep-alive-requests", "200"); - assertThat(this.properties.getTomcat().getMaxKeepAliveRequests()).isEqualTo(200); - } - - @Test - void testCustomizeTomcatMaxKeepAliveRequestsWithInfinite() { - bind("server.tomcat.max-keep-alive-requests", "-1"); - assertThat(this.properties.getTomcat().getMaxKeepAliveRequests()).isEqualTo(-1); - } - - @Test - void testCustomizeTomcatMaxParameterCount() { - bind("server.tomcat.max-parameter-count", "100"); - assertThat(this.properties.getTomcat().getMaxParameterCount()).isEqualTo(100); - } - - @Test - void testCustomizeTomcatMinSpareThreads() { - bind("server.tomcat.threads.min-spare", "10"); - assertThat(this.properties.getTomcat().getThreads().getMinSpare()).isEqualTo(10); - } - - @Test - void customizeTomcatMaxPartCount() { - bind("server.tomcat.max-part-count", "5"); - assertThat(this.properties.getTomcat().getMaxPartCount()).isEqualTo(5); - } - - @Test - void customizeTomcatMaxPartHeaderSize() { - bind("server.tomcat.max-part-header-size", "128"); - assertThat(this.properties.getTomcat().getMaxPartHeaderSize()).isEqualTo(DataSize.ofBytes(128)); - } - - @Test - void testCustomizeJettyAcceptors() { - bind("server.jetty.threads.acceptors", "10"); - assertThat(this.properties.getJetty().getThreads().getAcceptors()).isEqualTo(10); - } - - @Test - void testCustomizeJettySelectors() { - bind("server.jetty.threads.selectors", "10"); - assertThat(this.properties.getJetty().getThreads().getSelectors()).isEqualTo(10); - } - - @Test - void testCustomizeJettyMaxThreads() { - bind("server.jetty.threads.max", "10"); - assertThat(this.properties.getJetty().getThreads().getMax()).isEqualTo(10); - } - - @Test - void testCustomizeJettyMinThreads() { - bind("server.jetty.threads.min", "10"); - assertThat(this.properties.getJetty().getThreads().getMin()).isEqualTo(10); - } - - @Test - void testCustomizeJettyIdleTimeout() { - bind("server.jetty.threads.idle-timeout", "10s"); - assertThat(this.properties.getJetty().getThreads().getIdleTimeout()).isEqualTo(Duration.ofSeconds(10)); - } - - @Test - void testCustomizeJettyMaxQueueCapacity() { - bind("server.jetty.threads.max-queue-capacity", "5150"); - assertThat(this.properties.getJetty().getThreads().getMaxQueueCapacity()).isEqualTo(5150); - } - - @Test - void testCustomizeUndertowServerOption() { - bind("server.undertow.options.server.ALWAYS_SET_KEEP_ALIVE", "true"); - assertThat(this.properties.getUndertow().getOptions().getServer()).containsEntry("ALWAYS_SET_KEEP_ALIVE", - "true"); - } - - @Test - void testCustomizeUndertowSocketOption() { - bind("server.undertow.options.socket.ALWAYS_SET_KEEP_ALIVE", "true"); - assertThat(this.properties.getUndertow().getOptions().getSocket()).containsEntry("ALWAYS_SET_KEEP_ALIVE", - "true"); - } - - @Test - void testCustomizeUndertowIoThreads() { - bind("server.undertow.threads.io", "4"); - assertThat(this.properties.getUndertow().getThreads().getIo()).isEqualTo(4); - } - - @Test - void testCustomizeUndertowWorkerThreads() { - bind("server.undertow.threads.worker", "10"); - assertThat(this.properties.getUndertow().getThreads().getWorker()).isEqualTo(10); - } - - @Test - void testCustomizeJettyAccessLog() { - Map map = new HashMap<>(); - map.put("server.jetty.accesslog.enabled", "true"); - map.put("server.jetty.accesslog.filename", "foo.txt"); - map.put("server.jetty.accesslog.file-date-format", "yyyymmdd"); - map.put("server.jetty.accesslog.retention-period", "4"); - map.put("server.jetty.accesslog.append", "true"); - map.put("server.jetty.accesslog.custom-format", "{client}a - %u %t \"%r\" %s %O"); - map.put("server.jetty.accesslog.ignore-paths", "/a/path,/b/path"); - bind(map); - ServerProperties.Jetty jetty = this.properties.getJetty(); - assertThat(jetty.getAccesslog().isEnabled()).isTrue(); - assertThat(jetty.getAccesslog().getFilename()).isEqualTo("foo.txt"); - assertThat(jetty.getAccesslog().getFileDateFormat()).isEqualTo("yyyymmdd"); - assertThat(jetty.getAccesslog().getRetentionPeriod()).isEqualTo(4); - assertThat(jetty.getAccesslog().isAppend()).isTrue(); - assertThat(jetty.getAccesslog().getCustomFormat()).isEqualTo("{client}a - %u %t \"%r\" %s %O"); - assertThat(jetty.getAccesslog().getIgnorePaths()).containsExactly("/a/path", "/b/path"); - } - - @Test - void testCustomizeNettyIdleTimeout() { - bind("server.netty.idle-timeout", "10s"); - assertThat(this.properties.getNetty().getIdleTimeout()).isEqualTo(Duration.ofSeconds(10)); - } - - @Test - void testCustomizeNettyMaxKeepAliveRequests() { - bind("server.netty.max-keep-alive-requests", "100"); - assertThat(this.properties.getNetty().getMaxKeepAliveRequests()).isEqualTo(100); - } - - @Test - void tomcatAcceptCountMatchesProtocolDefault() throws Exception { - assertThat(this.properties.getTomcat().getAcceptCount()).isEqualTo(getDefaultProtocol().getAcceptCount()); - } - - @Test - void tomcatProcessorCacheMatchesProtocolDefault() throws Exception { - assertThat(this.properties.getTomcat().getProcessorCache()).isEqualTo(getDefaultProtocol().getProcessorCache()); - } - - @Test - void tomcatMaxConnectionsMatchesProtocolDefault() throws Exception { - assertThat(this.properties.getTomcat().getMaxConnections()).isEqualTo(getDefaultProtocol().getMaxConnections()); - } - - @Test - void tomcatMaxThreadsMatchesProtocolDefault() throws Exception { - assertThat(this.properties.getTomcat().getThreads().getMax()).isEqualTo(getDefaultProtocol().getMaxThreads()); - } - - @Test - void tomcatMinSpareThreadsMatchesProtocolDefault() throws Exception { - assertThat(this.properties.getTomcat().getThreads().getMinSpare()) - .isEqualTo(getDefaultProtocol().getMinSpareThreads()); - } - - @Test - void tomcatMaxHttpPostSizeMatchesConnectorDefault() { - assertThat(this.properties.getTomcat().getMaxHttpFormPostSize().toBytes()) - .isEqualTo(getDefaultConnector().getMaxPostSize()); - } - - @Test - void tomcatMaxParameterCountMatchesConnectorDefault() { - assertThat(this.properties.getTomcat().getMaxParameterCount()) - .isEqualTo(getDefaultConnector().getMaxParameterCount()); - } - - @Test - void tomcatBackgroundProcessorDelayMatchesEngineDefault() { - assertThat(this.properties.getTomcat().getBackgroundProcessorDelay()) - .hasSeconds((new StandardEngine().getBackgroundProcessorDelay())); - } - - @Test - void tomcatMaxHttpFormPostSizeMatchesConnectorDefault() { - assertThat(this.properties.getTomcat().getMaxHttpFormPostSize().toBytes()) - .isEqualTo(getDefaultConnector().getMaxPostSize()); - } - - @Test - void tomcatMaxPartCountMatchesConnectorDefault() { - assertThat(this.properties.getTomcat().getMaxPartCount()).isEqualTo(getDefaultConnector().getMaxPartCount()); - } - - @Test - void tomcatMaxPartHeaderSizeMatchesConnectorDefault() { - assertThat(this.properties.getTomcat().getMaxPartHeaderSize().toBytes()) - .isEqualTo(getDefaultConnector().getMaxPartHeaderSize()); - } - - @Test - void tomcatUriEncodingMatchesConnectorDefault() { - assertThat(this.properties.getTomcat().getUriEncoding().name()) - .isEqualTo(getDefaultConnector().getURIEncoding()); - } - - @Test - void tomcatRedirectContextRootMatchesDefault() { - assertThat(this.properties.getTomcat().getRedirectContextRoot()) - .isEqualTo(new StandardContext().getMapperContextRootRedirectEnabled()); - } - - @Test - void tomcatAccessLogRenameOnRotateMatchesDefault() { - assertThat(this.properties.getTomcat().getAccesslog().isRenameOnRotate()) - .isEqualTo(new AccessLogValve().isRenameOnRotate()); - } - - @Test - void tomcatAccessLogRequestAttributesEnabledMatchesDefault() { - assertThat(this.properties.getTomcat().getAccesslog().isRequestAttributesEnabled()) - .isEqualTo(new AccessLogValve().getRequestAttributesEnabled()); - } - - @Test - void tomcatInternalProxiesMatchesDefault() { - assertThat(this.properties.getTomcat().getRemoteip().getInternalProxies()) - .isEqualTo(new RemoteIpValve().getInternalProxies()); - } - - @Test - void tomcatUseRelativeRedirectsDefaultsToFalse() { - assertThat(this.properties.getTomcat().isUseRelativeRedirects()).isFalse(); - } - - @Test - void tomcatMaxKeepAliveRequestsDefault() throws Exception { - AbstractEndpoint endpoint = (AbstractEndpoint) ReflectionTestUtils.getField(getDefaultProtocol(), - "endpoint"); - int defaultMaxKeepAliveRequests = (int) ReflectionTestUtils.getField(endpoint, "maxKeepAliveRequests"); - assertThat(this.properties.getTomcat().getMaxKeepAliveRequests()).isEqualTo(defaultMaxKeepAliveRequests); - } - - @Test - void jettyThreadPoolPropertyDefaultsShouldMatchServerDefault() { - JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0); - JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer(); - Server server = jetty.getServer(); - QueuedThreadPool threadPool = (QueuedThreadPool) server.getThreadPool(); - int idleTimeout = threadPool.getIdleTimeout(); - int maxThreads = threadPool.getMaxThreads(); - int minThreads = threadPool.getMinThreads(); - assertThat(this.properties.getJetty().getThreads().getIdleTimeout().toMillis()).isEqualTo(idleTimeout); - assertThat(this.properties.getJetty().getThreads().getMax()).isEqualTo(maxThreads); - assertThat(this.properties.getJetty().getThreads().getMin()).isEqualTo(minThreads); - } - - @Test - void jettyMaxHttpFormPostSizeMatchesDefault() { - JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0); - JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer(); - Server server = jetty.getServer(); - assertThat(this.properties.getJetty().getMaxHttpFormPostSize().toBytes()) - .isEqualTo(((ServletContextHandler) server.getHandler()).getMaxFormContentSize()); - } - - @Test - void jettyMaxFormKeysMatchesDefault() { - JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0); - JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer(); - Server server = jetty.getServer(); - assertThat(this.properties.getJetty().getMaxFormKeys()) - .isEqualTo(((ServletContextHandler) server.getHandler()).getMaxFormKeys()); - } - - @Test - void undertowMaxHttpPostSizeMatchesDefault() { - assertThat(this.properties.getUndertow().getMaxHttpPostSize().toBytes()) - .isEqualTo(UndertowOptions.DEFAULT_MAX_ENTITY_SIZE); - } - - @Test - void nettyMaxInitialLineLengthMatchesHttpDecoderSpecDefault() { - assertThat(this.properties.getNetty().getMaxInitialLineLength().toBytes()) - .isEqualTo(HttpDecoderSpec.DEFAULT_MAX_INITIAL_LINE_LENGTH); - } - - @Test - void nettyValidateHeadersMatchesHttpDecoderSpecDefault() { - assertThat(this.properties.getNetty().isValidateHeaders()).isTrue(); - } - - @Test - void nettyH2cMaxContentLengthMatchesHttpDecoderSpecDefault() { - assertThat(this.properties.getNetty().getH2cMaxContentLength().toBytes()).isZero(); - } - - @Test - void nettyInitialBufferSizeMatchesHttpDecoderSpecDefault() { - assertThat(this.properties.getNetty().getInitialBufferSize().toBytes()) - .isEqualTo(HttpDecoderSpec.DEFAULT_INITIAL_BUFFER_SIZE); - } - - @Test - void shouldDefaultAprToNever() { - assertThat(this.properties.getTomcat().getUseApr()).isEqualTo(UseApr.NEVER); - } - - private Connector getDefaultConnector() { - return new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); - } - - private AbstractProtocol getDefaultProtocol() throws Exception { - return (AbstractProtocol) Class.forName(TomcatServletWebServerFactory.DEFAULT_PROTOCOL) - .getDeclaredConstructor() - .newInstance(); - } - - private void bind(String name, String value) { - bind(Collections.singletonMap(name, value)); - } - - private void bind(Map map) { - ConfigurationPropertySource source = new MapConfigurationPropertySource(map); - new Binder(source).bind("server", Bindable.ofInstance(this.properties)); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizerTests.java deleted file mode 100644 index 920e416a5236..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizerTests.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.embedded; - -import java.time.Duration; -import java.util.Map; - -import io.netty.channel.ChannelOption; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.junit.jupiter.MockitoExtension; -import reactor.netty.http.Http2SettingsSpec; -import reactor.netty.http.server.HttpRequestDecoderSpec; -import reactor.netty.http.server.HttpServer; - -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.netty.NettyServerCustomizer; -import org.springframework.mock.env.MockEnvironment; -import org.springframework.util.unit.DataSize; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; - -/** - * Tests for {@link NettyWebServerFactoryCustomizer}. - * - * @author Brian Clozel - * @author Artsiom Yudovin - * @author Leo Li - */ -@ExtendWith(MockitoExtension.class) -class NettyWebServerFactoryCustomizerTests { - - private MockEnvironment environment; - - private ServerProperties serverProperties; - - private NettyWebServerFactoryCustomizer customizer; - - @Captor - private ArgumentCaptor customizerCaptor; - - @BeforeEach - void setup() { - this.environment = new MockEnvironment(); - this.serverProperties = new ServerProperties(); - ConfigurationPropertySources.attach(this.environment); - this.customizer = new NettyWebServerFactoryCustomizer(this.environment, this.serverProperties); - } - - @Test - void deduceUseForwardHeaders() { - this.environment.setProperty("DYNO", "-"); - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setUseForwardHeaders(true); - } - - @Test - void defaultUseForwardHeaders() { - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setUseForwardHeaders(false); - } - - @Test - void forwardHeadersWhenStrategyIsNativeShouldConfigureValve() { - this.serverProperties.setForwardHeadersStrategy(ServerProperties.ForwardHeadersStrategy.NATIVE); - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setUseForwardHeaders(true); - } - - @Test - void forwardHeadersWhenStrategyIsNoneShouldNotConfigureValve() { - this.environment.setProperty("DYNO", "-"); - this.serverProperties.setForwardHeadersStrategy(ServerProperties.ForwardHeadersStrategy.NONE); - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().setUseForwardHeaders(false); - } - - @Test - void setConnectionTimeout() { - this.serverProperties.getNetty().setConnectionTimeout(Duration.ofSeconds(1)); - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - verifyConnectionTimeout(factory, 1000); - } - - @Test - void setIdleTimeout() { - this.serverProperties.getNetty().setIdleTimeout(Duration.ofSeconds(1)); - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - verifyIdleTimeout(factory, Duration.ofSeconds(1)); - } - - @Test - void setMaxKeepAliveRequests() { - this.serverProperties.getNetty().setMaxKeepAliveRequests(100); - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - verifyMaxKeepAliveRequests(factory, 100); - } - - @Test - void setHttp2MaxRequestHeaderSize() { - DataSize headerSize = DataSize.ofKilobytes(24); - this.serverProperties.getHttp2().setEnabled(true); - this.serverProperties.setMaxHttpRequestHeaderSize(headerSize); - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - verifyHttp2MaxHeaderSize(factory, headerSize.toBytes()); - } - - @Test - void configureHttpRequestDecoder() { - ServerProperties.Netty nettyProperties = this.serverProperties.getNetty(); - this.serverProperties.setMaxHttpRequestHeaderSize(DataSize.ofKilobytes(24)); - nettyProperties.setValidateHeaders(false); - nettyProperties.setInitialBufferSize(DataSize.ofBytes(512)); - nettyProperties.setH2cMaxContentLength(DataSize.ofKilobytes(1)); - nettyProperties.setMaxInitialLineLength(DataSize.ofKilobytes(32)); - NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); - this.customizer.customize(factory); - then(factory).should().addServerCustomizers(this.customizerCaptor.capture()); - NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); - HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); - HttpRequestDecoderSpec decoder = httpServer.configuration().decoder(); - assertThat(decoder.validateHeaders()).isFalse(); - assertThat(decoder.maxHeaderSize()).isEqualTo(this.serverProperties.getMaxHttpRequestHeaderSize().toBytes()); - assertThat(decoder.initialBufferSize()).isEqualTo(nettyProperties.getInitialBufferSize().toBytes()); - assertThat(decoder.h2cMaxContentLength()).isEqualTo(nettyProperties.getH2cMaxContentLength().toBytes()); - assertThat(decoder.maxInitialLineLength()).isEqualTo(nettyProperties.getMaxInitialLineLength().toBytes()); - } - - private void verifyConnectionTimeout(NettyReactiveWebServerFactory factory, Integer expected) { - if (expected == null) { - then(factory).should(never()).addServerCustomizers(any(NettyServerCustomizer.class)); - return; - } - then(factory).should(times(2)).addServerCustomizers(this.customizerCaptor.capture()); - NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); - HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); - Map, ?> options = httpServer.configuration().options(); - assertThat(options.get(ChannelOption.CONNECT_TIMEOUT_MILLIS)).isEqualTo(expected); - } - - private void verifyIdleTimeout(NettyReactiveWebServerFactory factory, Duration expected) { - if (expected == null) { - then(factory).should(never()).addServerCustomizers(any(NettyServerCustomizer.class)); - return; - } - then(factory).should(times(2)).addServerCustomizers(this.customizerCaptor.capture()); - NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); - HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); - Duration idleTimeout = httpServer.configuration().idleTimeout(); - assertThat(idleTimeout).isEqualTo(expected); - } - - private void verifyMaxKeepAliveRequests(NettyReactiveWebServerFactory factory, int expected) { - then(factory).should(times(2)).addServerCustomizers(this.customizerCaptor.capture()); - NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); - HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); - int maxKeepAliveRequests = httpServer.configuration().maxKeepAliveRequests(); - assertThat(maxKeepAliveRequests).isEqualTo(expected); - } - - private void verifyHttp2MaxHeaderSize(NettyReactiveWebServerFactory factory, long expected) { - then(factory).should(times(2)).addServerCustomizers(this.customizerCaptor.capture()); - NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); - HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); - Http2SettingsSpec decoder = httpServer.configuration().http2SettingsSpec(); - assertThat(decoder.maxHeaderListSize()).isEqualTo(expected); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerConfigurationTests.java deleted file mode 100644 index 243ea1561fc6..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerConfigurationTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.embedded; - -import io.undertow.servlet.api.DeploymentInfo; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledForJreRange; -import org.junit.jupiter.api.condition.JRE; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration.UndertowWebServerFactoryCustomizerConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.core.task.VirtualThreadTaskExecutor; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link UndertowWebServerFactoryCustomizerConfiguration}. - * - * @author Moritz Halbritter - */ -class UndertowWebServerFactoryCustomizerConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebApplicationContext::new) - .withConfiguration(AutoConfigurations.of(EmbeddedWebServerFactoryCustomizerAutoConfiguration.class)); - - @EnabledForJreRange(min = JRE.JAVA_21) - @Test - void shouldUseVirtualThreadsIfEnabled() { - this.contextRunner.withPropertyValues("spring.threads.virtual.enabled=true").run((context) -> { - assertThat(context).hasSingleBean(UndertowDeploymentInfoCustomizer.class); - assertThat(context).hasBean("virtualThreadsUndertowDeploymentInfoCustomizer"); - UndertowDeploymentInfoCustomizer customizer = context.getBean(UndertowDeploymentInfoCustomizer.class); - DeploymentInfo deploymentInfo = new DeploymentInfo(); - customizer.customize(deploymentInfo); - assertThat(deploymentInfo.getExecutor()).isInstanceOf(VirtualThreadTaskExecutor.class); - }); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfigurationTests.java deleted file mode 100644 index a0d6b853efec..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfigurationTests.java +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive; - -import io.undertow.Undertow; -import io.undertow.Undertow.Builder; -import org.apache.catalina.Context; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.startup.Tomcat; -import org.eclipse.jetty.server.Server; -import org.junit.jupiter.api.Test; -import reactor.netty.http.server.HttpServer; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; -import org.springframework.boot.ssl.NoSuchSslBundleException; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.netty.NettyServerCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.context.ApplicationContextException; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.web.server.adapter.ForwardedHeaderTransformer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ReactiveWebServerFactoryAutoConfiguration}. - * - * @author Brian Clozel - * @author Raheela Aslam - * @author Madhura Bhave - * @author Scott Frederick - */ -@DirtiesUrlFactories -class ReactiveWebServerFactoryAutoConfigurationTests { - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration( - AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class, SslAutoConfiguration.class)); - - @Test - void createFromConfigClass() { - this.contextRunner.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class) - .run((context) -> { - assertThat(context.getBeansOfType(ReactiveWebServerFactory.class)).hasSize(1); - assertThat(context.getBeansOfType(WebServerFactoryCustomizer.class)).hasSize(2); - assertThat(context.getBeansOfType(ReactiveWebServerFactoryCustomizer.class)).hasSize(1); - }); - } - - @Test - void missingHttpHandler() { - this.contextRunner.withUserConfiguration(MockWebServerConfiguration.class) - .run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(ApplicationContextException.class) - .rootCause() - .hasMessageContaining("missing HttpHandler bean")); - } - - @Test - void multipleHttpHandler() { - this.contextRunner - .withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class, - TooManyHttpHandlers.class) - .run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(ApplicationContextException.class) - .rootCause() - .hasMessageContaining("multiple HttpHandler beans : httpHandler,additionalHttpHandler")); - } - - @Test - void customizeReactiveWebServer() { - this.contextRunner - .withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class, - ReactiveWebServerCustomization.class) - .run((context) -> assertThat(context.getBean(MockReactiveWebServerFactory.class).getPort()) - .isEqualTo(9000)); - } - - @Test - void defaultWebServerIsTomcat() { - // Tomcat should be chosen over Netty if the Tomcat library is present. - this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class) - .withPropertyValues("server.port=0") - .run((context) -> assertThat(context.getBean(ReactiveWebServerFactory.class)) - .isInstanceOf(TomcatReactiveWebServerFactory.class)); - } - - @Test - void webServerFailsWithInvalidSslBundle() { - this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class) - .withPropertyValues("server.port=0", "server.ssl.bundle=test-bundle") - .run((context) -> { - assertThat(context).hasFailed(); - assertThat(context.getStartupFailure().getCause()).isInstanceOf(NoSuchSslBundleException.class) - .withFailMessage("test"); - }); - } - - @Test - void tomcatConnectorCustomizerBeanIsAddedToFactory() { - ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(HttpHandlerConfiguration.class, TomcatConnectorCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); - TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer", - TomcatConnectorCustomizer.class); - assertThat(factory.getTomcatConnectorCustomizers()).contains(customizer); - then(customizer).should().customize(any(Connector.class)); - }); - } - - @Test - void tomcatConnectorCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(HttpHandlerConfiguration.class, - DoubleRegistrationTomcatConnectorCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); - TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer", - TomcatConnectorCustomizer.class); - assertThat(factory.getTomcatConnectorCustomizers()).contains(customizer); - then(customizer).should().customize(any(Connector.class)); - }); - } - - @Test - void tomcatContextCustomizerBeanIsAddedToFactory() { - ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(HttpHandlerConfiguration.class, TomcatContextCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); - TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class); - assertThat(factory.getTomcatContextCustomizers()).contains(customizer); - then(customizer).should().customize(any(Context.class)); - }); - } - - @Test - void tomcatContextCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(HttpHandlerConfiguration.class, - DoubleRegistrationTomcatContextCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); - TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class); - assertThat(factory.getTomcatContextCustomizers()).contains(customizer); - then(customizer).should().customize(any(Context.class)); - }); - } - - @Test - void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() { - ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(HttpHandlerConfiguration.class, TomcatProtocolHandlerCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); - TomcatProtocolHandlerCustomizer customizer = context.getBean("protocolHandlerCustomizer", - TomcatProtocolHandlerCustomizer.class); - assertThat(factory.getTomcatProtocolHandlerCustomizers()).contains(customizer); - then(customizer).should().customize(any()); - }); - } - - @Test - void tomcatProtocolHandlerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( - AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(HttpHandlerConfiguration.class, - DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); - TomcatProtocolHandlerCustomizer customizer = context.getBean("protocolHandlerCustomizer", - TomcatProtocolHandlerCustomizer.class); - assertThat(factory.getTomcatProtocolHandlerCustomizers()).contains(customizer); - then(customizer).should().customize(any()); - }); - } - - @Test - void jettyServerCustomizerBeanIsAddedToFactory() { - new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class)) - .withUserConfiguration(JettyServerCustomizerConfiguration.class, HttpHandlerConfiguration.class) - .run((context) -> { - JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class); - assertThat(factory.getServerCustomizers()).hasSize(1); - }); - } - - @Test - void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class)) - .withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class, - HttpHandlerConfiguration.class) - .withPropertyValues("server.port=0") - .run((context) -> { - JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class); - JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class); - assertThat(factory.getServerCustomizers()).contains(customizer); - then(customizer).should().customize(any(Server.class)); - }); - } - - @Test - void undertowBuilderCustomizerBeanIsAddedToFactory() { - new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class)) - .withUserConfiguration(UndertowBuilderCustomizerConfiguration.class, HttpHandlerConfiguration.class) - .run((context) -> { - UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class); - assertThat(factory.getBuilderCustomizers()).hasSize(1); - }); - } - - @Test - void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class)) - .withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class, - HttpHandlerConfiguration.class) - .withPropertyValues("server.port: 0") - .run((context) -> { - UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class); - UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer", - UndertowBuilderCustomizer.class); - assertThat(factory.getBuilderCustomizers()).contains(customizer); - then(customizer).should().customize(any(Builder.class)); - }); - } - - @Test - void nettyServerCustomizerBeanIsAddedToFactory() { - new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(Tomcat.class, Server.class, Undertow.class)) - .withUserConfiguration(NettyServerCustomizerConfiguration.class, HttpHandlerConfiguration.class) - .run((context) -> { - NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class); - assertThat(factory.getServerCustomizers()).hasSize(1); - }); - } - - @Test - void nettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(Tomcat.class, Server.class, Undertow.class)) - .withUserConfiguration(DoubleRegistrationNettyServerCustomizerConfiguration.class, - HttpHandlerConfiguration.class) - .withPropertyValues("server.port: 0") - .run((context) -> { - NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class); - NettyServerCustomizer customizer = context.getBean("serverCustomizer", NettyServerCustomizer.class); - assertThat(factory.getServerCustomizers()).contains(customizer); - then(customizer).should().apply(any(HttpServer.class)); - }); - } - - @Test - void forwardedHeaderTransformerShouldBeConfigured() { - this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class) - .withPropertyValues("server.forward-headers-strategy=framework", "server.port=0") - .run((context) -> assertThat(context).hasSingleBean(ForwardedHeaderTransformer.class)); - } - - @Test - void forwardedHeaderTransformerWhenStrategyNotFilterShouldNotBeConfigured() { - this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class) - .withPropertyValues("server.forward-headers-strategy=native", "server.port=0") - .run((context) -> assertThat(context).doesNotHaveBean(ForwardedHeaderTransformer.class)); - } - - @Test - void forwardedHeaderTransformerWhenAlreadyRegisteredShouldBackOff() { - this.contextRunner - .withUserConfiguration(ForwardedHeaderTransformerConfiguration.class, HttpHandlerConfiguration.class) - .withPropertyValues("server.forward-headers-strategy=framework", "server.port=0") - .run((context) -> assertThat(context).hasSingleBean(ForwardedHeaderTransformer.class)); - } - - @Configuration(proxyBeanMethods = false) - static class HttpHandlerConfiguration { - - @Bean - HttpHandler httpHandler() { - return mock(HttpHandler.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TooManyHttpHandlers { - - @Bean - HttpHandler additionalHttpHandler() { - return mock(HttpHandler.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ReactiveWebServerCustomization { - - @Bean - WebServerFactoryCustomizer reactiveWebServerCustomizer() { - return (factory) -> factory.setPort(9000); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MockWebServerConfiguration { - - @Bean - MockReactiveWebServerFactory mockReactiveWebServerFactory() { - return new MockReactiveWebServerFactory(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatConnectorCustomizerConfiguration { - - @Bean - TomcatConnectorCustomizer connectorCustomizer() { - return mock(TomcatConnectorCustomizer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationTomcatConnectorCustomizerConfiguration { - - private final TomcatConnectorCustomizer customizer = mock(TomcatConnectorCustomizer.class); - - @Bean - TomcatConnectorCustomizer connectorCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer tomcatCustomizer() { - return (tomcat) -> tomcat.addConnectorCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatContextCustomizerConfiguration { - - @Bean - TomcatContextCustomizer contextCustomizer() { - return mock(TomcatContextCustomizer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationTomcatContextCustomizerConfiguration { - - private final TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class); - - @Bean - TomcatContextCustomizer contextCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer tomcatCustomizer() { - return (tomcat) -> tomcat.addContextCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatProtocolHandlerCustomizerConfiguration { - - @Bean - TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() { - return mock(TomcatProtocolHandlerCustomizer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration { - - private final TomcatProtocolHandlerCustomizer customizer = mock(TomcatProtocolHandlerCustomizer.class); - - @Bean - TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer tomcatCustomizer() { - return (tomcat) -> tomcat.addProtocolHandlerCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class JettyServerCustomizerConfiguration { - - @Bean - JettyServerCustomizer serverCustomizer() { - return (server) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationJettyServerCustomizerConfiguration { - - private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class); - - @Bean - JettyServerCustomizer serverCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer jettyCustomizer() { - return (jetty) -> jetty.addServerCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UndertowBuilderCustomizerConfiguration { - - @Bean - UndertowBuilderCustomizer builderCustomizer() { - return (builder) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationUndertowBuilderCustomizerConfiguration { - - private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class); - - @Bean - UndertowBuilderCustomizer builderCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer undertowCustomizer() { - return (undertow) -> undertow.addBuilderCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UndertowDeploymentInfoCustomizerConfiguration { - - @Bean - UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { - return (deploymentInfo) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class NettyServerCustomizerConfiguration { - - @Bean - NettyServerCustomizer serverCustomizer() { - return (server) -> server; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationNettyServerCustomizerConfiguration { - - private final NettyServerCustomizer customizer = mock(NettyServerCustomizer.class); - - DoubleRegistrationNettyServerCustomizerConfiguration() { - given(this.customizer.apply(any(HttpServer.class))).willAnswer((invocation) -> invocation.getArgument(0)); - } - - @Bean - NettyServerCustomizer serverCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer nettyCustomizer() { - return (netty) -> netty.addServerCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ForwardedHeaderTransformerConfiguration { - - @Bean - ForwardedHeaderTransformer testForwardedHeaderTransformer() { - return new ForwardedHeaderTransformer(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfigurationTests.java deleted file mode 100644 index 46d029bef461..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfigurationTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive.function.client; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.http.client.reactive.ClientHttpConnector; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ClientHttpConnectorAutoConfiguration} - * - * @author Brian Clozel - */ -@SuppressWarnings("removal") -class ClientHttpConnectorAutoConfigurationTests { - - @Test - void shouldApplyReactorNettyHttpClientMapper() { - new ReactiveWebApplicationContextRunner().withConfiguration(AutoConfigurations.of( - ClientHttpConnectorAutoConfiguration.class, - org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorAutoConfiguration.class)) - .withUserConfiguration(CustomReactorNettyHttpClientMapper.class) - .run((context) -> { - context.getBean(ClientHttpConnector.class); - assertThat(CustomReactorNettyHttpClientMapper.called).isTrue(); - }); - } - - static class CustomReactorNettyHttpClientMapper { - - static boolean called = false; - - @Bean - ReactorNettyHttpClientMapper clientMapper() { - return (client) -> { - called = true; - return client.baseUrl("/test"); - }; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ReactorNettyHttpClientMapperTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ReactorNettyHttpClientMapperTests.java deleted file mode 100644 index 43a1e4c35539..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ReactorNettyHttpClientMapperTests.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.reactive.function.client; - -import java.util.Collection; -import java.util.List; - -import org.junit.jupiter.api.Test; -import reactor.netty.http.client.HttpClient; -import reactor.netty.http.client.HttpClientConfig; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link ReactorNettyHttpClientMapper}. - * - * @author Phillip Webb - */ -@SuppressWarnings("removal") -class ReactorNettyHttpClientMapperTests { - - @Test - void ofWithCollectionCreatesComposite() { - ReactorNettyHttpClientMapper one = (httpClient) -> new TestHttpClient(httpClient, "1"); - ReactorNettyHttpClientMapper two = (httpClient) -> new TestHttpClient(httpClient, "2"); - ReactorNettyHttpClientMapper three = (httpClient) -> new TestHttpClient(httpClient, "3"); - ReactorNettyHttpClientMapper compose = ReactorNettyHttpClientMapper.of(List.of(one, two, three)); - TestHttpClient httpClient = (TestHttpClient) compose.configure(new TestHttpClient()); - assertThat(httpClient.getContent()).isEqualTo("123"); - } - - @Test - void ofWhenCollectionIsNullThrowsException() { - Collection mappers = null; - assertThatIllegalArgumentException().isThrownBy(() -> ReactorNettyHttpClientMapper.of(mappers)) - .withMessage("'mappers' must not be null"); - } - - @Test - void ofWithArrayCreatesComposite() { - ReactorNettyHttpClientMapper one = (httpClient) -> new TestHttpClient(httpClient, "1"); - ReactorNettyHttpClientMapper two = (httpClient) -> new TestHttpClient(httpClient, "2"); - ReactorNettyHttpClientMapper three = (httpClient) -> new TestHttpClient(httpClient, "3"); - ReactorNettyHttpClientMapper compose = ReactorNettyHttpClientMapper.of(one, two, three); - TestHttpClient httpClient = (TestHttpClient) compose.configure(new TestHttpClient()); - assertThat(httpClient.getContent()).isEqualTo("123"); - } - - @Test - void ofWhenArrayIsNullThrowsException() { - ReactorNettyHttpClientMapper[] mappers = null; - assertThatIllegalArgumentException().isThrownBy(() -> ReactorNettyHttpClientMapper.of(mappers)) - .withMessage("'mappers' must not be null"); - } - - private static class TestHttpClient extends HttpClient { - - private final String content; - - TestHttpClient() { - this.content = ""; - } - - TestHttpClient(HttpClient httpClient, String content) { - this.content = (httpClient instanceof TestHttpClient testHttpClient) ? testHttpClient.content + content - : content; - } - - @Override - public HttpClientConfig configuration() { - throw new UnsupportedOperationException("Auto-generated method stub"); - } - - @Override - protected HttpClient duplicate() { - throw new UnsupportedOperationException("Auto-generated method stub"); - } - - String getContent() { - return this.content; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/FilterOrderingIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/FilterOrderingIntegrationTests.java deleted file mode 100644 index db10e70ec9c3..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/FilterOrderingIntegrationTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import jakarta.servlet.Filter; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter; -import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; -import org.springframework.boot.web.servlet.server.MockServletWebServer.RegisteredFilter; -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.security.web.FilterChainProxy; -import org.springframework.session.MapSessionRepository; -import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; -import org.springframework.web.filter.DelegatingFilterProxy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Integration tests that verify the ordering of various filters that are auto-configured. - * - * @author Andy Wilkinson - * @author Eddú Meléndez - */ -class FilterOrderingIntegrationTests { - - private AnnotationConfigServletWebServerApplicationContext context; - - @AfterEach - void cleanup() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - void testFilterOrdering() { - load(); - List registeredFilters = this.context.getBean(MockServletWebServerFactory.class) - .getWebServer() - .getRegisteredFilters(); - assertThat(registeredFilters.get(0).getFilter()).isInstanceOf(OrderedCharacterEncodingFilter.class); - assertThat(registeredFilters.get(1).getFilter()).isInstanceOf(DelegatingFilterProxy.class) - .extracting("targetBeanName") - .isEqualTo("springSessionRepositoryFilter"); - assertThat(registeredFilters.get(2).getFilter()).isInstanceOf(Filter.class) - .extracting("beanName") - .isEqualTo("hiddenHttpMethodFilter"); - assertThat(registeredFilters.get(3).getFilter()).isInstanceOf(Filter.class) - .extracting("beanName") - .isEqualTo("formContentFilter"); - assertThat(registeredFilters.get(4).getFilter()).isInstanceOf(OrderedRequestContextFilter.class); - assertThat(registeredFilters.get(5).getFilter()).isInstanceOf(FilterChainProxy.class); - } - - private void load() { - this.context = new AnnotationConfigServletWebServerApplicationContext(); - this.context.register(MockWebServerConfiguration.class, TestSessionConfiguration.class, - TestRedisConfiguration.class, WebMvcAutoConfiguration.class, SecurityAutoConfiguration.class, - SessionAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, HttpEncodingAutoConfiguration.class); - TestPropertyValues.of("spring.mvc.hiddenmethod.filter.enabled:true").applyTo(this.context); - this.context.refresh(); - } - - @Configuration(proxyBeanMethods = false) - static class MockWebServerConfiguration { - - @Bean - MockServletWebServerFactory webServerFactory() { - return new MockServletWebServerFactory(); - } - - @Bean - static WebServerFactoryCustomizerBeanPostProcessor servletWebServerCustomizerBeanPostProcessor() { - return new WebServerFactoryCustomizerBeanPostProcessor(); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableSpringHttpSession - static class TestSessionConfiguration { - - @Bean - MapSessionRepository mapSessionRepository() { - return new MapSessionRepository(new ConcurrentHashMap<>()); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TestRedisConfiguration { - - @Bean - RedisConnectionFactory redisConnectionFactory() { - RedisConnectionFactory connectionFactory = mock(RedisConnectionFactory.class); - RedisConnection connection = mock(RedisConnection.class); - given(connectionFactory.getConnection()).willReturn(connection); - return connectionFactory; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfigurationTests.java deleted file mode 100644 index da96d0227963..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfigurationTests.java +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import io.undertow.Undertow.Builder; -import io.undertow.servlet.api.DeploymentInfo; -import jakarta.servlet.Filter; -import jakarta.servlet.ServletContext; -import org.apache.catalina.Context; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.startup.Tomcat; -import org.eclipse.jetty.server.Server; -import org.junit.jupiter.api.Test; -import reactor.netty.http.server.HttpServer; - -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; -import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; -import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier; -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.ForwardedHeaderFilter; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ServletWebServerFactoryAutoConfiguration}. - * - * @author Dave Syer - * @author Phillip Webb - * @author Stephane Nicoll - * @author Raheela Aslam - * @author Madhura Bhave - */ -class ServletWebServerFactoryAutoConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(WebServerConfiguration.class); - - @Test - void createFromConfigClass() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ServletWebServerFactoryCustomizer.class)); - } - - @Test - void webServerHasNoServletContext() { - this.contextRunner.withUserConfiguration(EnsureWebServerHasNoServletContext.class) - .run((context) -> assertThat(context).hasNotFailed()); - } - - @Test - void webServerFactoryCustomizerBeansAreCalledToCustomizeWebServerFactory() { - this.contextRunner - .withBean(WebServerFactoryCustomizer.class, - () -> (WebServerFactoryCustomizer) (factory) -> factory - .setPort(9000)) - .run((context) -> assertThat(context.getBean(MockServletWebServerFactory.class).getPort()).isEqualTo(9000)); - } - - @Test - void initParametersAreConfiguredOnTheServletContext() { - this.contextRunner - .withPropertyValues("server.servlet.context-parameters.a:alpha", - "server.servlet.context-parameters.b:bravo") - .run((context) -> { - ServletContext servletContext = context.getServletContext(); - assertThat(servletContext.getInitParameter("a")).isEqualTo("alpha"); - assertThat(servletContext.getInitParameter("b")).isEqualTo("bravo"); - }); - } - - @Test - void jettyServerCustomizerBeanIsAddedToFactory() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class)) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(JettyServerCustomizerConfiguration.class) - .withPropertyValues("server.port:0"); - runner.run((context) -> { - JettyServletWebServerFactory factory = context.getBean(JettyServletWebServerFactory.class); - assertThat(factory.getServerCustomizers()).hasSize(1); - }); - } - - @Test - void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class)) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - JettyServletWebServerFactory factory = context.getBean(JettyServletWebServerFactory.class); - JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class); - assertThat(factory.getServerCustomizers()).contains(customizer); - then(customizer).should().customize(any(Server.class)); - }); - } - - @Test - void undertowDeploymentInfoCustomizerBeanIsAddedToFactory() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class)) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(UndertowDeploymentInfoCustomizerConfiguration.class) - .withPropertyValues("server.port:0"); - runner.run((context) -> { - UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); - assertThat(factory.getDeploymentInfoCustomizers()).hasSize(1); - }); - } - - @Test - void undertowDeploymentInfoCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class)) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(DoubleRegistrationUndertowDeploymentInfoCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); - UndertowDeploymentInfoCustomizer customizer = context.getBean("deploymentInfoCustomizer", - UndertowDeploymentInfoCustomizer.class); - assertThat(factory.getDeploymentInfoCustomizers()).contains(customizer); - then(customizer).should().customize(any(DeploymentInfo.class)); - }); - } - - @Test - void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class)) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); - UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer", - UndertowBuilderCustomizer.class); - assertThat(factory.getBuilderCustomizers()).contains(customizer); - then(customizer).should().customize(any(Builder.class)); - }); - } - - @Test - void undertowBuilderCustomizerBeanIsAddedToFactory() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class)) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(UndertowBuilderCustomizerConfiguration.class) - .withPropertyValues("server.port:0"); - runner.run((context) -> { - UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); - assertThat(factory.getBuilderCustomizers()).hasSize(1); - }); - } - - @Test - void undertowServletWebServerFactoryCustomizerIsAutoConfigured() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class)) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(UndertowBuilderCustomizerConfiguration.class) - .withPropertyValues("server.port:0"); - runner.run((context) -> assertThat(context).hasSingleBean(UndertowServletWebServerFactoryCustomizer.class)); - } - - @Test - void tomcatConnectorCustomizerBeanIsAddedToFactory() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(TomcatConnectorCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); - TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer", - TomcatConnectorCustomizer.class); - assertThat(factory.getTomcatConnectorCustomizers()).contains(customizer); - then(customizer).should().customize(any(Connector.class)); - }); - } - - @Test - void tomcatConnectorCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(DoubleRegistrationTomcatConnectorCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); - TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer", - TomcatConnectorCustomizer.class); - assertThat(factory.getTomcatConnectorCustomizers()).contains(customizer); - then(customizer).should().customize(any(Connector.class)); - }); - } - - @Test - void tomcatContextCustomizerBeanIsAddedToFactory() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(TomcatContextCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); - TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class); - assertThat(factory.getTomcatContextCustomizers()).contains(customizer); - then(customizer).should().customize(any(Context.class)); - }); - } - - @Test - void tomcatContextCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(DoubleRegistrationTomcatContextCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); - TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class); - assertThat(factory.getTomcatContextCustomizers()).contains(customizer); - then(customizer).should().customize(any(Context.class)); - }); - } - - @Test - void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(TomcatProtocolHandlerCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); - TomcatProtocolHandlerCustomizer customizer = context.getBean("protocolHandlerCustomizer", - TomcatProtocolHandlerCustomizer.class); - assertThat(factory.getTomcatProtocolHandlerCustomizers()).contains(customizer); - then(customizer).should().customize(any()); - }); - } - - @Test - void tomcatProtocolHandlerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withUserConfiguration(DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration.class) - .withPropertyValues("server.port: 0"); - runner.run((context) -> { - TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); - TomcatProtocolHandlerCustomizer customizer = context.getBean("protocolHandlerCustomizer", - TomcatProtocolHandlerCustomizer.class); - assertThat(factory.getTomcatProtocolHandlerCustomizers()).contains(customizer); - then(customizer).should().customize(any()); - }); - } - - @Test - void forwardedHeaderFilterShouldBeConfigured() { - this.contextRunner.withPropertyValues("server.forward-headers-strategy=framework").run((context) -> { - assertThat(context).hasSingleBean(FilterRegistrationBean.class); - Filter filter = context.getBean(FilterRegistrationBean.class).getFilter(); - assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class); - assertThat(filter).extracting("relativeRedirects").isEqualTo(false); - }); - } - - @Test - void forwardedHeaderFilterWhenStrategyNotFilterShouldNotBeConfigured() { - this.contextRunner.withPropertyValues("server.forward-headers-strategy=native") - .run((context) -> assertThat(context).doesNotHaveBean(FilterRegistrationBean.class)); - } - - @Test - void forwardedHeaderFilterWhenFilterAlreadyRegisteredShouldBackOff() { - this.contextRunner.withUserConfiguration(ForwardedHeaderFilterConfiguration.class) - .withPropertyValues("server.forward-headers-strategy=framework") - .run((context) -> assertThat(context).hasSingleBean(FilterRegistrationBean.class)); - } - - @Test - void cookieSameSiteSuppliersAreApplied() { - this.contextRunner.withUserConfiguration(CookieSameSiteSupplierConfiguration.class).run((context) -> { - AbstractServletWebServerFactory webServerFactory = context.getBean(AbstractServletWebServerFactory.class); - assertThat(webServerFactory.getCookieSameSiteSuppliers()).hasSize(2); - }); - } - - @Test - void relativeRedirectsShouldBeEnabledWhenUsingTomcatContainerAndUseRelativeRedirects() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withPropertyValues("server.forward-headers-strategy=framework", - "server.tomcat.use-relative-redirects=true", "server.port=0"); - runner.run((context) -> { - Filter filter = context.getBean(FilterRegistrationBean.class).getFilter(); - assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class); - assertThat(filter).extracting("relativeRedirects").isEqualTo(true); - }); - } - - @Test - void relativeRedirectsShouldNotBeEnabledWhenUsingTomcatContainerAndNotUsingRelativeRedirects() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withPropertyValues("server.forward-headers-strategy=framework", - "server.tomcat.use-relative-redirects=false", "server.port=0"); - runner.run((context) -> { - Filter filter = context.getBean(FilterRegistrationBean.class).getFilter(); - assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class); - assertThat(filter).extracting("relativeRedirects").isEqualTo(false); - }); - } - - @Test - void relativeRedirectsShouldNotBeEnabledWhenNotUsingTomcatContainer() { - WebApplicationContextRunner runner = new WebApplicationContextRunner( - AnnotationConfigServletWebServerApplicationContext::new) - .withClassLoader(new FilteredClassLoader(Tomcat.class, Server.class)) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class)) - .withPropertyValues("server.forward-headers-strategy=framework", "server.port=0"); - runner.run((context) -> { - Filter filter = context.getBean(FilterRegistrationBean.class).getFilter(); - assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class); - assertThat(filter).extracting("relativeRedirects").isEqualTo(false); - }); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnExpression("true") - static class WebServerConfiguration { - - @Bean - ServletWebServerFactory webServerFactory() { - return new MockServletWebServerFactory(); - } - - } - - @Component - static class EnsureWebServerHasNoServletContext implements BeanPostProcessor { - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) { - if (bean instanceof ConfigurableServletWebServerFactory) { - MockServletWebServerFactory webServerFactory = (MockServletWebServerFactory) bean; - assertThat(webServerFactory.getServletContext()).isNull(); - } - return bean; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) { - return bean; - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatConnectorCustomizerConfiguration { - - @Bean - TomcatConnectorCustomizer connectorCustomizer() { - return mock(TomcatConnectorCustomizer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationTomcatConnectorCustomizerConfiguration { - - private final TomcatConnectorCustomizer customizer = mock(TomcatConnectorCustomizer.class); - - @Bean - TomcatConnectorCustomizer connectorCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer tomcatCustomizer() { - return (tomcat) -> tomcat.addConnectorCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatContextCustomizerConfiguration { - - @Bean - TomcatContextCustomizer contextCustomizer() { - return mock(TomcatContextCustomizer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationTomcatContextCustomizerConfiguration { - - private final TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class); - - @Bean - TomcatContextCustomizer contextCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer tomcatCustomizer() { - return (tomcat) -> tomcat.addContextCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatProtocolHandlerCustomizerConfiguration { - - @Bean - TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() { - return mock(TomcatProtocolHandlerCustomizer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration { - - private final TomcatProtocolHandlerCustomizer customizer = mock(TomcatProtocolHandlerCustomizer.class); - - @Bean - TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer tomcatCustomizer() { - return (tomcat) -> tomcat.addProtocolHandlerCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class JettyServerCustomizerConfiguration { - - @Bean - JettyServerCustomizer serverCustomizer() { - return (server) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationJettyServerCustomizerConfiguration { - - private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class); - - @Bean - JettyServerCustomizer serverCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer jettyCustomizer() { - return (jetty) -> jetty.addServerCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UndertowBuilderCustomizerConfiguration { - - @Bean - UndertowBuilderCustomizer builderCustomizer() { - return (builder) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationUndertowBuilderCustomizerConfiguration { - - private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class); - - @Bean - UndertowBuilderCustomizer builderCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer undertowCustomizer() { - return (undertow) -> undertow.addBuilderCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UndertowDeploymentInfoCustomizerConfiguration { - - @Bean - UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { - return (deploymentInfo) -> { - }; - } - - } - - @Configuration(proxyBeanMethods = false) - static class DoubleRegistrationUndertowDeploymentInfoCustomizerConfiguration { - - private final UndertowDeploymentInfoCustomizer customizer = mock(UndertowDeploymentInfoCustomizer.class); - - @Bean - UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { - return this.customizer; - } - - @Bean - WebServerFactoryCustomizer undertowCustomizer() { - return (undertow) -> undertow.addDeploymentInfoCustomizers(this.customizer); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ForwardedHeaderFilterConfiguration { - - @Bean - FilterRegistrationBean testForwardedHeaderFilter() { - ForwardedHeaderFilter filter = new ForwardedHeaderFilter(); - return new FilterRegistrationBean<>(filter); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CookieSameSiteSupplierConfiguration { - - @Bean - CookieSameSiteSupplier cookieSameSiteSupplier1() { - return CookieSameSiteSupplier.ofLax().whenHasName("test1"); - } - - @Bean - CookieSameSiteSupplier cookieSameSiteSupplier2() { - return CookieSameSiteSupplier.ofNone().whenHasName("test2"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerServletContextListenerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerServletContextListenerTests.java deleted file mode 100644 index 59576ba97b1c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerServletContextListenerTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import java.util.stream.Stream; - -import jakarta.servlet.ServletContextEvent; -import jakarta.servlet.ServletContextListener; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import org.springframework.boot.testsupport.classpath.ForkedClassPath; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link WebServer}s driving {@link ServletContextListener}s correctly - * - * @author Andy Wilkinson - */ -@DirtiesUrlFactories -class ServletWebServerServletContextListenerTests { - - @ParameterizedTest(name = "{0}") - @MethodSource("testConfiguration") - @ForkedClassPath - void registeredServletContextListenerBeanIsCalled(String serverName, Class configuration) { - AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( - ServletListenerRegistrationBeanConfiguration.class, configuration); - ServletContextListener servletContextListener = (ServletContextListener) context - .getBean("registration", ServletListenerRegistrationBean.class) - .getListener(); - then(servletContextListener).should().contextInitialized(any(ServletContextEvent.class)); - context.close(); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("testConfiguration") - @ForkedClassPath - void servletContextListenerBeanIsCalled(String serverName, Class configuration) { - AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( - ServletContextListenerBeanConfiguration.class, configuration); - ServletContextListener servletContextListener = context.getBean("servletContextListener", - ServletContextListener.class); - then(servletContextListener).should().contextInitialized(any(ServletContextEvent.class)); - context.close(); - } - - static Stream testConfiguration() { - return Stream.of(Arguments.of("Jetty", JettyConfiguration.class), - Arguments.of("Tomcat", TomcatConfiguration.class), - Arguments.of("Undertow", UndertowConfiguration.class)); - } - - @Configuration(proxyBeanMethods = false) - static class TomcatConfiguration { - - @Bean - ServletWebServerFactory webServerFactory() { - return new TomcatServletWebServerFactory(0); - } - - } - - @Configuration(proxyBeanMethods = false) - static class JettyConfiguration { - - @Bean - ServletWebServerFactory webServerFactory() { - return new JettyServletWebServerFactory(0); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UndertowConfiguration { - - @Bean - ServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory(0); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ServletContextListenerBeanConfiguration { - - @Bean - ServletContextListener servletContextListener() { - return mock(ServletContextListener.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ServletListenerRegistrationBeanConfiguration { - - @Bean - ServletListenerRegistrationBean registration() { - return new ServletListenerRegistrationBean<>(mock(ServletContextListener.class)); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/UndertowServletWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/UndertowServletWebServerFactoryCustomizerTests.java deleted file mode 100644 index 1a68508d982c..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/UndertowServletWebServerFactoryCustomizerTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link UndertowServletWebServerFactoryCustomizer} - * - * @author Andy Wilkinson - */ -class UndertowServletWebServerFactoryCustomizerTests { - - @Test - void eagerFilterInitCanBeDisabled() { - UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(0); - assertThat(factory.isEagerFilterInit()).isTrue(); - ServerProperties serverProperties = new ServerProperties(); - serverProperties.getUndertow().setEagerFilterInit(false); - new UndertowServletWebServerFactoryCustomizer(serverProperties).customize(factory); - assertThat(factory.isEagerFilterInit()).isFalse(); - } - - @Test - void preservePathOnForwardCanBeEnabled() { - UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(0); - assertThat(factory.isPreservePathOnForward()).isFalse(); - ServerProperties serverProperties = new ServerProperties(); - serverProperties.getUndertow().setPreservePathOnForward(true); - new UndertowServletWebServerFactoryCustomizer(serverProperties).customize(factory); - assertThat(factory.isPreservePathOnForward()).isTrue(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java deleted file mode 100644 index 16fb8345a853..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.web.servlet; - -import java.net.URI; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for the welcome page. - * - * @author Madhura Bhave - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { - "spring.web.resources.chain.strategy.content.enabled=true", - "spring.thymeleaf.prefix=classpath:/org/springframework/boot/autoconfigure/web/servlet/", - "spring.web.resources.static-locations=classpath:/org/springframework/boot/autoconfigure/web/servlet/static" }) -class WelcomePageIntegrationTests { - - @LocalServerPort - private int port; - - private final TestRestTemplate template = new TestRestTemplate(); - - @Test - void contentStrategyWithWelcomePage() throws Exception { - RequestEntity entity = RequestEntity.get(new URI("http://localhost:" + this.port + "/")) - .header("Accept", MediaType.ALL.toString()) - .build(); - ResponseEntity content = this.template.exchange(entity, String.class); - assertThat(content.getBody()).contains("/custom-"); - assertThat(content.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - void notAcceptableWelcomePage() throws Exception { - RequestEntity entity = RequestEntity.get(new URI("http://localhost:" + this.port + "/")) - .header("Accept", "spring/boot") - .build(); - ResponseEntity content = this.template.exchange(entity, String.class); - assertThat(content.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE); - } - - @Configuration - @Import({ PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, ThymeleafAutoConfiguration.class }) - static class TestConfiguration { - - static void main(String[] args) { - new SpringApplicationBuilder(TestConfiguration.class).run(args); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/reactive/WebSocketReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/reactive/WebSocketReactiveAutoConfigurationTests.java deleted file mode 100644 index 9a87395db0a7..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/reactive/WebSocketReactiveAutoConfigurationTests.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.reactive; - -import java.util.function.Function; -import java.util.stream.Stream; - -import jakarta.servlet.ServletContext; -import jakarta.websocket.server.ServerContainer; -import org.apache.catalina.Container; -import org.apache.catalina.Context; -import org.apache.catalina.startup.Tomcat; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import org.springframework.boot.testsupport.classpath.ForkedClassPath; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.jetty.JettyWebServer; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.server.reactive.HttpHandler; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link WebSocketReactiveAutoConfiguration}. - * - * @author Andy Wilkinson - */ -@DirtiesUrlFactories -class WebSocketReactiveAutoConfigurationTests { - - @ParameterizedTest(name = "{0}") - @MethodSource("testConfiguration") - @ForkedClassPath - void serverContainerIsAvailableFromTheServletContext(String server, - Function servletContextAccessor, - Class... configuration) { - try (AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext( - configuration)) { - Object serverContainer = servletContextAccessor.apply(context) - .getAttribute("jakarta.websocket.server.ServerContainer"); - assertThat(serverContainer).isInstanceOf(ServerContainer.class); - } - } - - static Stream testConfiguration() { - return Stream.of(Arguments.of("Jetty", - (Function) WebSocketReactiveAutoConfigurationTests::getJettyServletContext, - new Class[] { JettyConfiguration.class, - WebSocketReactiveAutoConfiguration.JettyWebSocketConfiguration.class }), - Arguments.of("Tomcat", - (Function) WebSocketReactiveAutoConfigurationTests::getTomcatServletContext, - new Class[] { TomcatConfiguration.class, - WebSocketReactiveAutoConfiguration.TomcatWebSocketConfiguration.class })); - } - - private static ServletContext getJettyServletContext(AnnotationConfigReactiveWebServerApplicationContext context) { - return ((ServletContextHandler) ((JettyWebServer) context.getWebServer()).getServer().getHandler()) - .getServletContext(); - } - - private static ServletContext getTomcatServletContext(AnnotationConfigReactiveWebServerApplicationContext context) { - return findContext(((TomcatWebServer) context.getWebServer()).getTomcat()).getServletContext(); - } - - private static Context findContext(Tomcat tomcat) { - for (Container child : tomcat.getHost().findChildren()) { - if (child instanceof Context context) { - return context; - } - } - throw new IllegalStateException("The host does not contain a Context"); - } - - @Configuration(proxyBeanMethods = false) - static class CommonConfiguration { - - @Bean - static WebServerFactoryCustomizerBeanPostProcessor webServerFactoryCustomizerBeanPostProcessor() { - return new WebServerFactoryCustomizerBeanPostProcessor(); - } - - @Bean - HttpHandler echoHandler() { - return (request, response) -> response.writeWith(request.getBody()); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatConfiguration extends CommonConfiguration { - - @Bean - ReactiveWebServerFactory webServerFactory() { - TomcatReactiveWebServerFactory factory = new TomcatReactiveWebServerFactory(); - factory.setPort(0); - return factory; - } - - } - - @Configuration(proxyBeanMethods = false) - static class JettyConfiguration extends CommonConfiguration { - - @Bean - ReactiveWebServerFactory webServerFactory() { - JettyReactiveWebServerFactory factory = new JettyReactiveWebServerFactory(); - factory.setPort(0); - return factory; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfigurationTests.java deleted file mode 100644 index 38542ba9c8e3..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfigurationTests.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.autoconfigure.websocket.servlet; - -import java.io.IOException; -import java.util.Map; -import java.util.stream.Stream; - -import jakarta.servlet.DispatcherType; -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.websocket.DeploymentException; -import jakarta.websocket.server.ServerContainer; -import jakarta.websocket.server.ServerEndpoint; -import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.testsupport.classpath.ForkedClassPath; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; -import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.http.HttpStatus; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link WebSocketServletAutoConfiguration} - * - * @author Andy Wilkinson - */ -@DirtiesUrlFactories -class WebSocketServletAutoConfigurationTests { - - @ParameterizedTest(name = "{0}") - @MethodSource("testConfiguration") - @ForkedClassPath - void serverContainerIsAvailableFromTheServletContext(String server, Class... configuration) { - try (AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( - configuration)) { - Object serverContainer = context.getServletContext() - .getAttribute("jakarta.websocket.server.ServerContainer"); - assertThat(serverContainer).isInstanceOf(ServerContainer.class); - } - } - - @ParameterizedTest(name = "{0}") - @MethodSource("testConfiguration") - @ForkedClassPath - void webSocketUpgradeDoesNotPreventAFilterFromRejectingTheRequest(String server, Class... configuration) - throws DeploymentException { - try (AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( - configuration)) { - ServerContainer serverContainer = (ServerContainer) context.getServletContext() - .getAttribute("jakarta.websocket.server.ServerContainer"); - serverContainer.addEndpoint(TestEndpoint.class); - WebServer webServer = context.getWebServer(); - int port = webServer.getPort(); - TestRestTemplate rest = new TestRestTemplate(); - RequestEntity request = RequestEntity.get("http://localhost:" + port) - .header("Upgrade", "websocket") - .header("Connection", "upgrade") - .header("Sec-WebSocket-Version", "13") - .header("Sec-WebSocket-Key", "key") - .build(); - ResponseEntity response = rest.exchange(request, Void.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); - } - } - - @Test - void jettyWebSocketUpgradeFilterIsAddedToServletContextOfJettyServer() { - try (AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( - JettyConfiguration.class, WebSocketServletAutoConfiguration.JettyWebSocketConfiguration.class)) { - assertThat(context.getServletContext().getFilterRegistration(WebSocketUpgradeFilter.class.getName())) - .isNotNull(); - } - } - - @Test - void jettyWebSocketUpgradeFilterIsNotAddedToServletContextOfTomcatServer() { - try (AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( - TomcatConfiguration.class, WebSocketServletAutoConfiguration.JettyWebSocketConfiguration.class)) { - assertThat(context.getServletContext().getFilterRegistration(WebSocketUpgradeFilter.class.getName())) - .isNull(); - } - } - - @Test - @SuppressWarnings("rawtypes") - void jettyWebSocketUpgradeFilterIsNotExposedAsABean() { - new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(JettyConfiguration.class, - WebSocketServletAutoConfiguration.JettyWebSocketConfiguration.class)) - .run((context) -> { - Map filters = context.getBeansOfType(Filter.class); - assertThat(filters.values()).noneMatch(WebSocketUpgradeFilter.class::isInstance); - Map filterRegistrations = context - .getBeansOfType(AbstractFilterRegistrationBean.class); - assertThat(filterRegistrations.values()).extracting(AbstractFilterRegistrationBean::getFilter) - .noneMatch(WebSocketUpgradeFilter.class::isInstance); - }); - } - - @Test - void jettyWebSocketUpgradeFilterServletContextInitializerBacksOffWhenBeanWithSameNameIsDefined() { - try (AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( - JettyConfiguration.class, CustomWebSocketUpgradeFilterServletContextInitializerConfiguration.class, - WebSocketServletAutoConfiguration.JettyWebSocketConfiguration.class)) { - BeanDefinition definition = context.getBeanFactory() - .getBeanDefinition("websocketUpgradeFilterServletContextInitializer"); - assertThat(definition.getFactoryBeanName()) - .contains("CustomWebSocketUpgradeFilterServletContextInitializerConfiguration"); - } - } - - static Stream testConfiguration() { - String response = "Tomcat"; - return Stream.of( - Arguments.of("Jetty", - new Class[] { JettyConfiguration.class, DispatcherServletAutoConfiguration.class, - WebSocketServletAutoConfiguration.JettyWebSocketConfiguration.class }), - Arguments.of(response, - new Class[] { TomcatConfiguration.class, DispatcherServletAutoConfiguration.class, - WebSocketServletAutoConfiguration.TomcatWebSocketConfiguration.class })); - } - - @Configuration(proxyBeanMethods = false) - static class CommonConfiguration { - - @Bean - FilterRegistrationBean unauthorizedFilter() { - FilterRegistrationBean registration = new FilterRegistrationBean<>(new Filter() { - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - ((HttpServletResponse) response).sendError(HttpStatus.UNAUTHORIZED.value()); - } - - }); - registration.setOrder(Ordered.HIGHEST_PRECEDENCE); - registration.addUrlPatterns("/*"); - registration.setDispatcherTypes(DispatcherType.REQUEST); - return registration; - } - - @Bean - static WebServerFactoryCustomizerBeanPostProcessor servletWebServerCustomizerBeanPostProcessor() { - return new WebServerFactoryCustomizerBeanPostProcessor(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatConfiguration extends CommonConfiguration { - - @Bean - ServletWebServerFactory webServerFactory() { - TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); - factory.setPort(0); - return factory; - } - - } - - @Configuration(proxyBeanMethods = false) - static class JettyConfiguration extends CommonConfiguration { - - @Bean - ServletWebServerFactory webServerFactory() { - JettyServletWebServerFactory JettyServletWebServerFactory = new JettyServletWebServerFactory(); - JettyServletWebServerFactory.setPort(0); - return JettyServletWebServerFactory; - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomWebSocketUpgradeFilterServletContextInitializerConfiguration { - - @Bean - ServletContextInitializer websocketUpgradeFilterServletContextInitializer() { - return (servletContext) -> { - - }; - } - - } - - @ServerEndpoint("/") - public static class TestEndpoint { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider deleted file mode 100644 index b8002e9ea3c2..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.r2dbc.SimpleConnectionFactoryProvider diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 8f545e4f6883..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.r2dbc.core.binding.BindMarkersFactoryResolver$BindMarkerFactoryProvider=org.springframework.boot.autoconfigure.r2dbc.SimpleBindMarkerFactoryProvider diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/another.sql b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/another.sql deleted file mode 100644 index b4974a01bbfa..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/another.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE SPAM ( - id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - name VARCHAR(30) -); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/data.sql b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/data.sql deleted file mode 100644 index 068d7392cbc7..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/data.sql +++ /dev/null @@ -1 +0,0 @@ -INSERT INTO FOO VALUES (1, 'Andy'); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/encoding-data.sql b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/encoding-data.sql deleted file mode 100644 index 030efbf67804..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/encoding-data.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO BAR(id, name) VALUES (1, 'bar'); -INSERT INTO BAR(id, name) VALUES (2, 'ばー'); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/encoding-schema.sql b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/encoding-schema.sql deleted file mode 100644 index 21284cab1d56..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/encoding-schema.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE BAR ( - id INTEGER PRIMARY KEY, - name VARCHAR(30) -); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/lexical-schema-aaa.sql b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/lexical-schema-aaa.sql deleted file mode 100644 index 5d4523e1e17b..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/lexical-schema-aaa.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE FOO ( - id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - todrop VARCHAR(30) -); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/lexical-schema-bbb.sql b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/lexical-schema-bbb.sql deleted file mode 100644 index bd6b7221ec53..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/lexical-schema-bbb.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE FOO DROP COLUMN todrop; -ALTER TABLE FOO ADD COLUMN name VARCHAR(30); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/schema.sql b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/schema.sql deleted file mode 100644 index 1014a04db4a9..000000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jdbc/schema.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE FOO ( - id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - name VARCHAR(30) -); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/cache/autoconfigure/hazelcast-specific.xml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml rename to spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/cache/autoconfigure/hazelcast-specific.xml diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/TestAutoConfigurationPackage.java b/spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/TestAutoConfigurationPackage.java similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/TestAutoConfigurationPackage.java rename to spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/TestAutoConfigurationPackage.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/TestAutoConfigurationPackageRegistrar.java b/spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/TestAutoConfigurationPackageRegistrar.java similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/TestAutoConfigurationPackageRegistrar.java rename to spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/TestAutoConfigurationPackageRegistrar.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/support/MockCachingProvider.java b/spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/cache/support/MockCachingProvider.java similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/support/MockCachingProvider.java rename to spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/cache/support/MockCachingProvider.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jndi/JndiPropertiesHidingClassLoader.java b/spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/jndi/JndiPropertiesHidingClassLoader.java similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jndi/JndiPropertiesHidingClassLoader.java rename to spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/jndi/JndiPropertiesHidingClassLoader.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jndi/TestableInitialContextFactory.java b/spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/jndi/TestableInitialContextFactory.java similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jndi/TestableInitialContextFactory.java rename to spring-boot-project/spring-boot-autoconfigure/src/testFixtures/java/org/springframework/boot/autoconfigure/jndi/TestableInitialContextFactory.java diff --git a/spring-boot-project/spring-boot-batch/build.gradle b/spring-boot-project/spring-boot-batch/build.gradle new file mode 100644 index 000000000000..dbe3563c310a --- /dev/null +++ b/spring-boot-project/spring-boot-batch/build.gradle @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Batch" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-jdbc")) + api("org.springframework.batch:spring-batch-core") + + implementation(project(":spring-boot-project:spring-boot-tx")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-hibernate")) + optional(project(":spring-boot-project:spring-boot-observation")) + + testImplementation(project(":spring-boot-project:spring-boot-flyway")) + testImplementation(project(":spring-boot-project:spring-boot-liquibase")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("io.micrometer:micrometer-observation-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.fasterxml.jackson.core:jackson-databind") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfiguration.java index 152bf3afa2e8..e6cfcce98406 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.util.List; @@ -35,11 +35,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.sql.autoconfigure.init.OnDatabaseInitializationCondition; import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -68,9 +68,10 @@ * @author Lars Uffmann * @author Lasse Wulff * @author Yanming Zhou - * @since 1.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { HibernateJpaAutoConfiguration.class, TransactionAutoConfiguration.class }) +@AutoConfiguration(after = { DataSourceAutoConfiguration.class, TransactionAutoConfiguration.class }, + afterName = "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration") @ConditionalOnClass({ JobLauncher.class, DataSource.class, DatabasePopulator.class }) @ConditionalOnBean({ DataSource.class, PlatformTransactionManager.class }) @ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, annotation = EnableBatchProcessing.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchConversionServiceCustomizer.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchConversionServiceCustomizer.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchConversionServiceCustomizer.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchConversionServiceCustomizer.java index 925149405d57..1bc14c4af4b7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchConversionServiceCustomizer.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchConversionServiceCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration; import org.springframework.core.convert.support.ConfigurableConversionService; @@ -26,7 +26,7 @@ * DefaultBatchConfiguration} while retaining its default auto-configuration. * * @author Claudio Nave - * @since 3.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface BatchConversionServiceCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSource.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchDataSource.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSource.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchDataSource.java index 4552f0e5f4d0..340902221e70 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSource.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchDataSource.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -31,7 +31,7 @@ * {@link Primary @Primary}. * * @author Dmytro Nosan - * @since 2.2.0 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchDataSourceScriptDatabaseInitializer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializer.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchDataSourceScriptDatabaseInitializer.java index f7c9b701c2f4..47617308736c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchDataSourceScriptDatabaseInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.util.List; @@ -33,7 +33,7 @@ * @author Vedran Pavic * @author Andy Wilkinson * @author Phillip Webb - * @since 2.6.0 + * @since 4.0.0 */ public class BatchDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchProperties.java index 0df4277ea10d..29c4b240d3be 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.sql.init.DatabaseInitializationMode; @@ -28,7 +28,7 @@ * @author Vedran Pavic * @author Mukul Kumar Chaundhyan * @author Yanming Zhou - * @since 1.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.batch") public class BatchProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchTaskExecutor.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchTaskExecutor.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchTaskExecutor.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchTaskExecutor.java index 125e16fb313d..3ce81e7d1fb9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchTaskExecutor.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchTaskExecutor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,7 +32,7 @@ * another one marked as {@link Primary @Primary}. * * @author Andy Wilkinson - * @since 3.4.0 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchTransactionManager.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchTransactionManager.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchTransactionManager.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchTransactionManager.java index d8e3c7ffe093..1d33fe8386f2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchTransactionManager.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/BatchTransactionManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,7 +32,7 @@ * there is another one marked as {@link Primary @Primary}. * * @author Lasse Wulff - * @since 3.3.0 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobExecutionEvent.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobExecutionEvent.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobExecutionEvent.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobExecutionEvent.java index 3c11b2d10a02..a0fb9f972991 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobExecutionEvent.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobExecutionEvent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import org.springframework.batch.core.JobExecution; import org.springframework.context.ApplicationEvent; @@ -23,7 +23,7 @@ * Spring {@link ApplicationEvent} encapsulating a {@link JobExecution}. * * @author Dave Syer - * @since 1.0.0 + * @since 4.0.0 */ @SuppressWarnings("serial") public class JobExecutionEvent extends ApplicationEvent { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobExecutionExitCodeGenerator.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobExecutionExitCodeGenerator.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobExecutionExitCodeGenerator.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobExecutionExitCodeGenerator.java index fb5fce52472e..dc9b9ae5c263 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobExecutionExitCodeGenerator.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobExecutionExitCodeGenerator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -27,7 +27,7 @@ * {@link ExitCodeGenerator} for {@link JobExecutionEvent}s. * * @author Dave Syer - * @since 1.0.0 + * @since 4.0.0 */ public class JobExecutionExitCodeGenerator implements ApplicationListener, ExitCodeGenerator { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobLauncherApplicationRunner.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobLauncherApplicationRunner.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobLauncherApplicationRunner.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobLauncherApplicationRunner.java index 3b99d2c016e7..fc425777d390 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobLauncherApplicationRunner.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobLauncherApplicationRunner.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.util.Arrays; import java.util.Collection; @@ -64,7 +64,7 @@ * @author Mahmoud Ben Hassine * @author Stephane Nicoll * @author Akshay Dubey - * @since 2.3.0 + * @since 4.0.0 */ public class JobLauncherApplicationRunner implements ApplicationRunner, InitializingBean, Ordered, ApplicationEventPublisherAware { @@ -120,11 +120,6 @@ public void afterPropertiesSet() { } } - @Deprecated(since = "3.0.10", forRemoval = true) - public void validate() { - afterPropertiesSet(); - } - public void setOrder(int order) { this.order = order; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobRepositoryDependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobRepositoryDependsOnDatabaseInitializationDetector.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobRepositoryDependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobRepositoryDependsOnDatabaseInitializationDetector.java index cac573f72b77..0ccfbca7c31a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobRepositoryDependsOnDatabaseInitializationDetector.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/JobRepositoryDependsOnDatabaseInitializationDetector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.util.Collections; import java.util.Set; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/batch/BatchObservationAutoConfiguration.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/observation/BatchObservationAutoConfiguration.java similarity index 82% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/batch/BatchObservationAutoConfiguration.java rename to spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/observation/BatchObservationAutoConfiguration.java index 39cef205c374..02bc17990a5b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/batch/BatchObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/observation/BatchObservationAutoConfiguration.java @@ -14,12 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation.batch; +package org.springframework.boot.batch.autoconfigure.observation; import io.micrometer.observation.ObservationRegistry; import org.springframework.batch.core.configuration.annotation.BatchObservabilityBeanPostProcessor; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -32,16 +31,16 @@ * Jobs. * * @author Mark Bonnekessel - * @since 3.0.6 + * @since 4.0.0 */ -@AutoConfiguration(after = ObservationAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration") @ConditionalOnBean(ObservationRegistry.class) @ConditionalOnClass({ ObservationRegistry.class, BatchObservabilityBeanPostProcessor.class }) public class BatchObservationAutoConfiguration { - @ConditionalOnMissingBean @Bean - public static BatchObservabilityBeanPostProcessor batchObservabilityBeanPostProcessor() { + @ConditionalOnMissingBean + static BatchObservabilityBeanPostProcessor batchObservabilityBeanPostProcessor() { return new BatchObservabilityBeanPostProcessor(); } diff --git a/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/observation/package-info.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/observation/package-info.java new file mode 100644 index 000000000000..e293f04e2936 --- /dev/null +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/observation/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Batch observations. + */ +package org.springframework.boot.batch.autoconfigure.observation; diff --git a/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/package-info.java b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/package-info.java new file mode 100644 index 000000000000..3da7e4d17026 --- /dev/null +++ b/spring-boot-project/spring-boot-batch/src/main/java/org/springframework/boot/batch/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Batch. + */ +package org.springframework.boot.batch.autoconfigure; diff --git a/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..2cce21b301e0 --- /dev/null +++ b/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,43 @@ +{ + "properties": [ + { + "name": "spring.batch.initialize-schema", + "type": "org.springframework.boot.sql.init.DatabaseInitializationMode", + "deprecation": { + "replacement": "spring.batch.jdbc.initialize-schema", + "level": "error" + } + }, + { + "name": "spring.batch.initializer.enabled", + "type": "java.lang.Boolean", + "description": "Create the required batch tables on startup if necessary. Enabled automatically\n if no custom table prefix is set or if a custom schema is configured.", + "deprecation": { + "replacement": "spring.batch.jdbc.initialize-schema", + "level": "error" + } + }, + { + "name": "spring.batch.job.enabled", + "type": "java.lang.Boolean", + "description": "Execute all Spring Batch jobs in the context on startup.", + "defaultValue": true + }, + { + "name": "spring.batch.schema", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.batch.jdbc.schema", + "level": "error" + } + }, + { + "name": "spring.batch.table-prefix", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.batch.jdbc.table-prefix", + "level": "error" + } + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..f1572ab57313 --- /dev/null +++ b/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Depends on Database Initialization Detectors +org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ +org.springframework.boot.batch.autoconfigure.JobRepositoryDependsOnDatabaseInitializationDetector diff --git a/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..6f6b4d9629a8 --- /dev/null +++ b/spring-boot-project/spring-boot-batch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.batch.autoconfigure.BatchAutoConfiguration +org.springframework.boot.batch.autoconfigure.observation.BatchObservationAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java rename to spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfigurationTests.java index d9446d273d66..4933d96c6cd6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.util.Arrays; import java.util.Collection; @@ -58,18 +58,16 @@ import org.springframework.boot.DefaultApplicationArguments; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration.SpringBootBatchConfiguration; -import org.springframework.boot.autoconfigure.batch.domain.City; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration; +import org.springframework.boot.batch.autoconfigure.BatchAutoConfiguration.SpringBootBatchConfiguration; +import org.springframework.boot.batch.autoconfigure.domain.City; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.boot.sql.init.DatabaseInitializationMode; import org.springframework.boot.sql.init.DatabaseInitializationSettings; import org.springframework.boot.test.context.FilteredClassLoader; @@ -77,6 +75,8 @@ import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -569,13 +569,13 @@ static class BatchDataSourceConfiguration { @Bean DataSource normalDataSource() { - return DataSourceBuilder.create().url("jdbc:hsqldb:mem:normal").username("sa").build(); + return DataSourceBuilder.create().url("jdbc:h2:mem:normal").username("sa").build(); } @BatchDataSource @Bean(defaultCandidate = false) DataSource batchDataSource() { - return DataSourceBuilder.create().url("jdbc:hsqldb:mem:batchdatasource").username("sa").build(); + return DataSourceBuilder.create().url("jdbc:h2:mem:batchdatasource").username("sa").build(); } } @@ -585,7 +585,7 @@ static class BatchTransactionManagerConfiguration { @Bean DataSource dataSource() { - return DataSourceBuilder.create().url("jdbc:hsqldb:mem:database").username("sa").build(); + return DataSourceBuilder.create().url("jdbc:h2:mem:database").username("sa").build(); } @Bean diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJpaTests.java b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfigurationWithoutJpaTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJpaTests.java rename to spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfigurationWithoutJpaTests.java index d074a9b15aca..c72c4f35b06a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJpaTests.java +++ b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchAutoConfigurationWithoutJpaTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import javax.sql.DataSource; @@ -26,15 +26,15 @@ import org.springframework.batch.core.repository.JobRepository; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration.SpringBootBatchConfiguration; -import org.springframework.boot.autoconfigure.batch.domain.City; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.boot.batch.autoconfigure.BatchAutoConfiguration.SpringBootBatchConfiguration; +import org.springframework.boot.batch.autoconfigure.domain.City; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; import org.springframework.boot.sql.init.DatabaseInitializationMode; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.annotation.Isolation; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchDataSourceScriptDatabaseInitializerTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializerTests.java rename to spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchDataSourceScriptDatabaseInitializerTests.java index c8a880e5dae9..6d9ddbdad01d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchDataSourceScriptDatabaseInitializerTests.java +++ b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchDataSourceScriptDatabaseInitializerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.io.IOException; import java.sql.Connection; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchPropertiesTests.java b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchPropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchPropertiesTests.java rename to spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchPropertiesTests.java index 1261a8552c4f..2c50688d0ca3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchPropertiesTests.java +++ b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/BatchPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/JobExecutionExitCodeGeneratorTests.java b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/JobExecutionExitCodeGeneratorTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/JobExecutionExitCodeGeneratorTests.java rename to spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/JobExecutionExitCodeGeneratorTests.java index e470821b8dbb..680786828c5f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/JobExecutionExitCodeGeneratorTests.java +++ b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/JobExecutionExitCodeGeneratorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/JobLauncherApplicationRunnerTests.java b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/JobLauncherApplicationRunnerTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/JobLauncherApplicationRunnerTests.java rename to spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/JobLauncherApplicationRunnerTests.java index 2dd1ddc68fef..7ac0672f8c5d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/JobLauncherApplicationRunnerTests.java +++ b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/JobLauncherApplicationRunnerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.batch; +package org.springframework.boot.batch.autoconfigure; import java.util.Arrays; import java.util.List; @@ -40,12 +40,12 @@ import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; import org.springframework.boot.sql.init.DatabaseInitializationSettings; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/domain/City.java b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/domain/City.java new file mode 100644 index 000000000000..b8ce06337ba2 --- /dev/null +++ b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/domain/City.java @@ -0,0 +1,78 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.batch.autoconfigure.domain; + +import java.io.Serializable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + @Column(nullable = false) + private String country; + + @Column(nullable = false) + private String map; + + protected City() { + } + + public City(String name, String state, String country, String map) { + this.name = name; + this.state = state; + this.country = country; + this.map = map; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/batch/BatchObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/observation/BatchObservationAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/batch/BatchObservationAutoConfigurationTests.java rename to spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/observation/BatchObservationAutoConfigurationTests.java index 634e6584adf3..f2d1875560e3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/batch/BatchObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-batch/src/test/java/org/springframework/boot/batch/autoconfigure/observation/BatchObservationAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation.batch; +package org.springframework.boot.batch.autoconfigure.observation; import io.micrometer.observation.tck.TestObservationRegistry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/batch/custom-schema.sql b/spring-boot-project/spring-boot-batch/src/test/resources/org/springframework/boot/batch/autoconfigure/custom-schema.sql similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/batch/custom-schema.sql rename to spring-boot-project/spring-boot-batch/src/test/resources/org/springframework/boot/batch/autoconfigure/custom-schema.sql diff --git a/spring-boot-project/spring-boot-cache/build.gradle b/spring-boot-project/spring-boot-cache/build.gradle new file mode 100644 index 000000000000..081593d87021 --- /dev/null +++ b/spring-boot-project/spring-boot-cache/build.gradle @@ -0,0 +1,72 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Cache" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-context-support") + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-data-couchbase")) + optional(project(":spring-boot-project:spring-boot-data-redis")) + optional(project(":spring-boot-project:spring-boot-hazelcast")) + optional(project(":spring-boot-project:spring-boot-hibernate")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional("com.hazelcast:hazelcast-spring") + optional("io.micrometer:micrometer-core") + optional("javax.cache:cache-api") + optional("org.cache2k:cache2k-micrometer") + optional("org.cache2k:cache2k-spring") + optional("org.ehcache:ehcache") { + artifact { + classifier = 'jakarta' + } + } + optional("org.hibernate.orm:hibernate-core") + optional("org.hibernate.orm:hibernate-jcache") + optional("org.infinispan:infinispan-commons") + optional("org.infinispan:infinispan-component-annotations") + optional("org.infinispan:infinispan-core") + optional("org.infinispan:infinispan-jcache") + optional("org.infinispan:infinispan-spring6-embedded") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation("com.redis:testcontainers-redis") + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:testcontainers") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMetricsTests.java b/spring-boot-project/spring-boot-cache/src/dockerTest/java/org/springframework/boot/cache/metrics/RedisCacheMetricsTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMetricsTests.java rename to spring-boot-project/spring-boot-cache/src/dockerTest/java/org/springframework/boot/cache/metrics/RedisCacheMetricsTests.java index de153f783172..7723a37ff7b1 100644 --- a/spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMetricsTests.java +++ b/spring-boot-project/spring-boot-cache/src/dockerTest/java/org/springframework/boot/cache/metrics/RedisCacheMetricsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.util.UUID; import java.util.function.BiConsumer; @@ -28,8 +28,8 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/CachesEndpoint.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpoint.java similarity index 99% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/CachesEndpoint.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpoint.java index a11e2f943fb5..e33e8245d787 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/CachesEndpoint.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpoint.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cache; +package org.springframework.boot.cache.actuate.endpoint; import java.util.LinkedHashMap; import java.util.List; @@ -36,7 +36,7 @@ * * @author Johannes Edmeier * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @Endpoint(id = "caches") public class CachesEndpoint { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/CachesEndpointWebExtension.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointWebExtension.java similarity index 93% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/CachesEndpointWebExtension.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointWebExtension.java index 5fca11b1f0c6..cd28c5611470 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/CachesEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointWebExtension.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cache; +package org.springframework.boot.cache.actuate.endpoint; -import org.springframework.boot.actuate.cache.CachesEndpoint.CacheEntryDescriptor; import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; import org.springframework.boot.actuate.endpoint.annotation.OptionalParameter; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpoint.CacheEntryDescriptor; /** * {@link EndpointWebExtension @EndpointWebExtension} for the {@link CachesEndpoint}. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @EndpointWebExtension(endpoint = CachesEndpoint.class) public class CachesEndpointWebExtension { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/NonUniqueCacheException.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/NonUniqueCacheException.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/NonUniqueCacheException.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/NonUniqueCacheException.java index a40eb14ae87e..75cc18f98304 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cache/NonUniqueCacheException.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/NonUniqueCacheException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cache; +package org.springframework.boot.cache.actuate.endpoint; import java.util.Collection; import java.util.Collections; @@ -23,7 +23,7 @@ * Exception thrown when multiple caches exist with the same name. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ public class NonUniqueCacheException extends RuntimeException { diff --git a/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/package-info.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/package-info.java new file mode 100644 index 000000000000..6eb5d0e82f50 --- /dev/null +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/actuate/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator endpoint for caches. + */ +package org.springframework.boot.cache.actuate.endpoint; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/Cache2kBuilderCustomizer.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/Cache2kBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/Cache2kBuilderCustomizer.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/Cache2kBuilderCustomizer.java index 4bd1b3364662..bcbdc85e4484 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/Cache2kBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/Cache2kBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import org.cache2k.Cache2kBuilder; @@ -25,7 +25,7 @@ * * @author Jens Wilke * @author Stephane Nicoll - * @since 2.7.0 + * @since 4.0.0 */ public interface Cache2kBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/Cache2kCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/Cache2kCacheConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/Cache2kCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/Cache2kCacheConfiguration.java index cccc680e2e1b..33a6c899f7bd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/Cache2kCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/Cache2kCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.Collection; import java.util.function.Function; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheAutoConfiguration.java similarity index 78% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheAutoConfiguration.java index aef0edb7cea5..10bcd6f2d5f3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheAutoConfiguration.java @@ -14,27 +14,25 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.CacheConfigurationImportSelector; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.CacheManagerEntityManagerFactoryDependsOnPostProcessor; +import org.springframework.boot.autoconfigure.cache.CacheType; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration.CacheConfigurationImportSelector; +import org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration.CacheManagerEntityManagerFactoryDependsOnConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryDependsOnPostProcessor; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.CacheAspectSupport; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; @@ -50,16 +48,18 @@ * Cache store can be auto-detected or specified explicitly through configuration. * * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 * @see EnableCaching */ -@AutoConfiguration(after = { CouchbaseDataAutoConfiguration.class, HazelcastAutoConfiguration.class, - HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class }) +@AutoConfiguration(afterName = { "org.springframework.boot.data.couchbase.autoconfigure.CouchbaseDataAutoConfiguration", + "org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration", + "org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration", + "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration" }) @ConditionalOnClass(CacheManager.class) @ConditionalOnBean(CacheAspectSupport.class) @ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver") @EnableConfigurationProperties(CacheProperties.class) -@Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class }) +@Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnConfiguration.class }) public class CacheAutoConfiguration { @Bean @@ -74,8 +74,15 @@ public CacheManagerValidator cacheAutoConfigurationValidator(CacheProperties cac return new CacheManagerValidator(cacheProperties, cacheManager); } - @ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class) + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ EntityManagerFactoryDependsOnPostProcessor.class, + LocalContainerEntityManagerFactoryBean.class }) @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) + @Import(CacheManagerEntityManagerFactoryDependsOnPostProcessor.class) + static class CacheManagerEntityManagerFactoryDependsOnConfiguration { + + } + static class CacheManagerEntityManagerFactoryDependsOnPostProcessor extends EntityManagerFactoryDependsOnPostProcessor { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheCondition.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheCondition.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheCondition.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheCondition.java index 26bc3bc0cbaa..546ebee3e4c0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheCondition.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheCondition.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; +import org.springframework.boot.autoconfigure.cache.CacheType; import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheConfigurations.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheConfigurations.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheConfigurations.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheConfigurations.java index 2f4d67306531..83f66c46a831 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheConfigurations.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheConfigurations.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.Collections; import java.util.EnumMap; import java.util.Map; +import org.springframework.boot.autoconfigure.cache.CacheType; import org.springframework.util.Assert; /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizer.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizer.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizer.java index 91026ef09390..2bff26ff015f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizer.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import org.springframework.cache.CacheManager; @@ -24,7 +24,7 @@ * * @param the type of the {@link CacheManager} * @author Stephane Nicoll - * @since 1.3.3 + * @since 4.0.0 */ @FunctionalInterface public interface CacheManagerCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizers.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizers.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizers.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizers.java index 50aee0c32243..a7b565f5e925 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizers.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizers.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.ArrayList; import java.util.Collections; @@ -28,7 +28,7 @@ * given {@link CacheManager}. * * @author Stephane Nicoll - * @since 1.5.0 + * @since 4.0.0 */ public class CacheManagerCustomizers { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheProperties.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheProperties.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheProperties.java index 5f3e307061bc..3d8b68db7901 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheProperties.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CacheProperties.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.time.Duration; import java.util.ArrayList; import java.util.List; +import org.springframework.boot.autoconfigure.cache.CacheType; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.io.Resource; import org.springframework.util.Assert; @@ -30,7 +31,7 @@ * @author Stephane Nicoll * @author Eddú Meléndez * @author Ryon Day - * @since 1.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.cache") public class CacheProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CaffeineCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CaffeineCacheConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CaffeineCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CaffeineCacheConfiguration.java index 4c9761d37f04..a5bda5afdaa8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CaffeineCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CaffeineCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CouchbaseCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CouchbaseCacheConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CouchbaseCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CouchbaseCacheConfiguration.java index 503577be3e09..ca627549edbe 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CouchbaseCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CouchbaseCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.LinkedHashSet; import java.util.List; @@ -22,10 +22,10 @@ import com.couchbase.client.java.Cluster; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.cache.CacheProperties.Couchbase; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; +import org.springframework.boot.cache.autoconfigure.CacheProperties.Couchbase; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CouchbaseCacheManagerBuilderCustomizer.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CouchbaseCacheManagerBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CouchbaseCacheManagerBuilderCustomizer.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CouchbaseCacheManagerBuilderCustomizer.java index a33c116bb88c..061e2e0f50d5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CouchbaseCacheManagerBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/CouchbaseCacheManagerBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import org.springframework.data.couchbase.cache.CouchbaseCacheManager; import org.springframework.data.couchbase.cache.CouchbaseCacheManager.CouchbaseCacheManagerBuilder; @@ -25,7 +25,7 @@ * {@link CouchbaseCacheManager}. * * @author Stephane Nicoll - * @since 2.3.3 + * @since 4.0.0 */ @FunctionalInterface public interface CouchbaseCacheManagerBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/GenericCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/GenericCacheConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/GenericCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/GenericCacheConfiguration.java index 54d6c58ad845..89310f113163 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/GenericCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/GenericCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.Collection; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/HazelcastCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/HazelcastCacheConfiguration.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/HazelcastCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/HazelcastCacheConfiguration.java index 15e69cfca90a..7884b6d35271 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/HazelcastCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/HazelcastCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.spring.cache.HazelcastCacheManager; @@ -22,8 +22,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastConfigResourceCondition; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastConfigResourceCondition; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/HazelcastJCacheCustomizationConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/HazelcastJCacheCustomizationConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/HazelcastJCacheCustomizationConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/HazelcastJCacheCustomizationConfiguration.java index 122ad38e361f..721cbe80c0e8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/HazelcastJCacheCustomizationConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/HazelcastJCacheCustomizationConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.io.IOException; import java.net.URI; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/InfinispanCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/InfinispanCacheConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/InfinispanCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/InfinispanCacheConfiguration.java index 59d810b9a641..3e80e843c54c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/InfinispanCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/InfinispanCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.io.IOException; import java.io.InputStream; @@ -41,7 +41,7 @@ * @author Eddú Meléndez * @author Stephane Nicoll * @author Raja Kolli - * @since 1.3.0 + * @since 4.0.0 */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass(SpringEmbeddedCacheManager.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCacheCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCacheCacheConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCacheCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCacheCacheConfiguration.java index 8c73f0432611..c476252add26 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCacheCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCacheCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.io.IOException; import java.util.Iterator; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCacheManagerCustomizer.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCacheManagerCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCacheManagerCustomizer.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCacheManagerCustomizer.java index 9cb2d5bf58be..d38c9c6edaa4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCacheManagerCustomizer.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCacheManagerCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import javax.cache.CacheManager; @@ -23,7 +23,7 @@ * manager before it is used, in particular to create additional caches. * * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface JCacheManagerCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCachePropertiesCustomizer.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCachePropertiesCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCachePropertiesCustomizer.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCachePropertiesCustomizer.java index b5e396515791..a121bbf3c6ed 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCachePropertiesCustomizer.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/JCachePropertiesCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.Properties; @@ -26,7 +26,7 @@ * used by the {@link CachingProvider} to create the {@link CacheManager}. * * @author Stephane Nicoll - * @since 3.4.0 + * @since 4.0.0 * @see CachingProvider#getCacheManager(java.net.URI, ClassLoader, Properties) */ public interface JCachePropertiesCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/NoOpCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/NoOpCacheConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/NoOpCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/NoOpCacheConfiguration.java index 8ff48f268e2d..ee034c1728fd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/NoOpCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/NoOpCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cache.CacheManager; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/RedisCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/RedisCacheConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/RedisCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/RedisCacheConfiguration.java index c7d92c894ad1..bf97fb06fecc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/RedisCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/RedisCacheConfiguration.java @@ -14,18 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.LinkedHashSet; import java.util.List; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.cache.CacheProperties.Redis; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.cache.autoconfigure.CacheProperties.Redis; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -46,7 +45,7 @@ */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass(RedisConnectionFactory.class) -@AutoConfigureAfter(RedisAutoConfiguration.class) +@AutoConfigureAfter(name = "org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration") @ConditionalOnBean(RedisConnectionFactory.class) @ConditionalOnMissingBean(CacheManager.class) @Conditional(CacheCondition.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/RedisCacheManagerBuilderCustomizer.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/RedisCacheManagerBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/RedisCacheManagerBuilderCustomizer.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/RedisCacheManagerBuilderCustomizer.java index 1766bf22192b..e8160092e384 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/RedisCacheManagerBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/RedisCacheManagerBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import org.springframework.data.redis.cache.RedisCacheManager.RedisCacheManagerBuilder; @@ -22,7 +22,7 @@ * Callback interface that can be used to customize a {@link RedisCacheManagerBuilder}. * * @author Dmytro Nosan - * @since 2.2.0 + * @since 4.0.0 */ @FunctionalInterface public interface RedisCacheManagerBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/SimpleCacheConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/SimpleCacheConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/SimpleCacheConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/SimpleCacheConfiguration.java index 6a41e9f9a912..e471409f9ee5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/SimpleCacheConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/SimpleCacheConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/endpoint/CachesEndpointAutoConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/endpoint/CachesEndpointAutoConfiguration.java index cd9d478a389f..2bcc50455545 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/endpoint/CachesEndpointAutoConfiguration.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure.endpoint; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; -import org.springframework.boot.actuate.cache.CachesEndpoint; -import org.springframework.boot.actuate.cache.CachesEndpointWebExtension; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpoint; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpointWebExtension; +import org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; @@ -36,10 +36,10 @@ * * @author Johannes Edmeier * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = CacheAutoConfiguration.class) -@ConditionalOnClass(CacheManager.class) +@ConditionalOnClass({ CacheManager.class, ConditionalOnAvailableEndpoint.class }) @ConditionalOnAvailableEndpoint(CachesEndpoint.class) public class CachesEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/endpoint/package-info.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/endpoint/package-info.java new file mode 100644 index 000000000000..b52c170dcc93 --- /dev/null +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for the cache abstraction endpoints. + */ +package org.springframework.boot.cache.autoconfigure.endpoint; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMeterBinderProvidersConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMeterBinderProvidersConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMeterBinderProvidersConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMeterBinderProvidersConfiguration.java index b858077f15da..0456a0d29dd0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMeterBinderProvidersConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMeterBinderProvidersConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.cache; +package org.springframework.boot.cache.autoconfigure.metrics; import com.hazelcast.core.Hazelcast; import com.hazelcast.spring.cache.HazelcastCache; @@ -23,13 +23,13 @@ import org.cache2k.extra.micrometer.Cache2kCacheMetrics; import org.cache2k.extra.spring.SpringCache2kCache; -import org.springframework.boot.actuate.metrics.cache.Cache2kCacheMeterBinderProvider; -import org.springframework.boot.actuate.metrics.cache.CacheMeterBinderProvider; -import org.springframework.boot.actuate.metrics.cache.CaffeineCacheMeterBinderProvider; -import org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider; -import org.springframework.boot.actuate.metrics.cache.JCacheCacheMeterBinderProvider; -import org.springframework.boot.actuate.metrics.cache.RedisCacheMeterBinderProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.cache.metrics.Cache2kCacheMeterBinderProvider; +import org.springframework.boot.cache.metrics.CacheMeterBinderProvider; +import org.springframework.boot.cache.metrics.CaffeineCacheMeterBinderProvider; +import org.springframework.boot.cache.metrics.HazelcastCacheMeterBinderProvider; +import org.springframework.boot.cache.metrics.JCacheCacheMeterBinderProvider; +import org.springframework.boot.cache.metrics.RedisCacheMeterBinderProvider; import org.springframework.cache.caffeine.CaffeineCache; import org.springframework.cache.jcache.JCacheCache; import org.springframework.context.annotation.Bean; @@ -42,7 +42,7 @@ * @author Stephane Nicoll */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass(MeterBinder.class) +@ConditionalOnClass({ MeterBinder.class, CacheMeterBinderProvider.class }) class CacheMeterBinderProvidersConfiguration { @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsAutoConfiguration.java new file mode 100644 index 000000000000..90a986fd7132 --- /dev/null +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsAutoConfiguration.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cache.autoconfigure.metrics; + +import io.micrometer.core.instrument.MeterRegistry; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for metrics on all available + * {@link Cache caches}. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration(after = { CacheAutoConfiguration.class }, + afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") +@ConditionalOnBean(CacheManager.class) +@ConditionalOnClass(MeterRegistry.class) +@Import({ CacheMeterBinderProvidersConfiguration.class, CacheMetricsRegistrarConfiguration.class }) +public class CacheMetricsAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsRegistrarConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsRegistrarConfiguration.java index 123b5b2f3abe..1f0008428ba3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsRegistrarConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.cache; +package org.springframework.boot.cache.autoconfigure.metrics; import java.util.Collection; import java.util.Map; @@ -24,9 +24,9 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver; -import org.springframework.boot.actuate.metrics.cache.CacheMeterBinderProvider; -import org.springframework.boot.actuate.metrics.cache.CacheMetricsRegistrar; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.cache.metrics.CacheMeterBinderProvider; +import org.springframework.boot.cache.metrics.CacheMetricsRegistrar; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..f8bed736dc6f --- /dev/null +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for the cache abstraction metrics. + */ +package org.springframework.boot.cache.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/package-info.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/package-info.java new file mode 100644 index 000000000000..986e95dbc89e --- /dev/null +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for the cache abstraction. + */ +package org.springframework.boot.cache.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/Cache2kCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/Cache2kCacheMeterBinderProvider.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/Cache2kCacheMeterBinderProvider.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/Cache2kCacheMeterBinderProvider.java index a4bd5b95cd05..d8975727f595 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/Cache2kCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/Cache2kCacheMeterBinderProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; @@ -25,7 +25,7 @@ * {@link CacheMeterBinderProvider} implementation for cache2k. * * @author Jens Wilke - * @since 2.7.0 + * @since 4.0.0 */ public class Cache2kCacheMeterBinderProvider implements CacheMeterBinderProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CacheMeterBinderProvider.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CacheMeterBinderProvider.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CacheMeterBinderProvider.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CacheMeterBinderProvider.java index 08e1b47e1dc3..b808a8f6571b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CacheMeterBinderProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; @@ -26,7 +26,7 @@ * * @param the cache type * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface CacheMeterBinderProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CacheMetricsRegistrar.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CacheMetricsRegistrar.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CacheMetricsRegistrar.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CacheMetricsRegistrar.java index c12f2f8ecfd8..4948b339c491 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CacheMetricsRegistrar.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CacheMetricsRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.util.Collection; import java.util.Objects; @@ -33,7 +33,7 @@ * Register supported {@link Cache} to a {@link MeterRegistry}. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public class CacheMetricsRegistrar { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CaffeineCacheMeterBinderProvider.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CaffeineCacheMeterBinderProvider.java index c03aadd40803..437481b39959 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/CaffeineCacheMeterBinderProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; @@ -26,7 +26,7 @@ * {@link CacheMeterBinderProvider} implementation for Caffeine. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public class CaffeineCacheMeterBinderProvider implements CacheMeterBinderProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/HazelcastCacheMeterBinderProvider.java similarity index 93% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/HazelcastCacheMeterBinderProvider.java index e55a92d303a9..b95809e24265 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/HazelcastCacheMeterBinderProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -27,7 +27,7 @@ import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; +import org.springframework.boot.cache.metrics.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; @@ -36,7 +36,7 @@ * {@link CacheMeterBinderProvider} implementation for Hazelcast. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(HazelcastCacheMeterBinderProviderRuntimeHints.class) public class HazelcastCacheMeterBinderProvider implements CacheMeterBinderProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/JCacheCacheMeterBinderProvider.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/JCacheCacheMeterBinderProvider.java index 5d4ae4d270d3..7c7988cadf25 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/JCacheCacheMeterBinderProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; @@ -26,7 +26,7 @@ * {@link CacheMeterBinderProvider} implementation for JCache. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public class JCacheCacheMeterBinderProvider implements CacheMeterBinderProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/RedisCacheMeterBinderProvider.java similarity index 93% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMeterBinderProvider.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/RedisCacheMeterBinderProvider.java index 9487fda8fb81..0c752bc463d6 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/RedisCacheMeterBinderProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; @@ -25,7 +25,7 @@ * {@link CacheMeterBinderProvider} implementation for Redis. * * @author Stephane Nicoll - * @since 2.4.0 + * @since 4.0.0 */ public class RedisCacheMeterBinderProvider implements CacheMeterBinderProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMetrics.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/RedisCacheMetrics.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMetrics.java rename to spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/RedisCacheMetrics.java index 0769ae055c9d..73fc4eb5b186 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMetrics.java +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/RedisCacheMetrics.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.util.concurrent.TimeUnit; @@ -30,7 +30,7 @@ * {@link CacheMeterBinder} for {@link RedisCache}. * * @author Stephane Nicoll - * @since 2.4.0 + * @since 4.0.0 */ public class RedisCacheMetrics extends CacheMeterBinder { diff --git a/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/package-info.java b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/package-info.java new file mode 100644 index 000000000000..6402e588069e --- /dev/null +++ b/spring-boot-project/spring-boot-cache/src/main/java/org/springframework/boot/cache/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Metrics for caches. + */ +package org.springframework.boot.cache.metrics; diff --git a/spring-boot-project/spring-boot-cache/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-cache/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..d58a9ce0f05a --- /dev/null +++ b/spring-boot-project/spring-boot-cache/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,17 @@ +{ + "groups": [], + "properties": [], + "hints": [ + { + "name": "spring.cache.jcache.provider", + "providers": [ + { + "name": "class-reference", + "parameters": { + "target": "javax.cache.spi.CachingProvider" + } + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-cache/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-cache/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..5818459d0b0c --- /dev/null +++ b/spring-boot-project/spring-boot-cache/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration +org.springframework.boot.cache.autoconfigure.endpoint.CachesEndpointAutoConfiguration +org.springframework.boot.cache.autoconfigure.metrics.CacheMetricsAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cache/CachesEndpointTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cache/CachesEndpointTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointTests.java index d9820dc0ff98..0a68fbfb2cd6 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cache/CachesEndpointTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cache; +package org.springframework.boot.cache.actuate.endpoint; import java.util.Arrays; import java.util.Collections; @@ -24,8 +24,8 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.cache.CachesEndpoint.CacheEntryDescriptor; -import org.springframework.boot.actuate.cache.CachesEndpoint.CacheManagerDescriptor; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpoint.CacheEntryDescriptor; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpoint.CacheManagerDescriptor; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.concurrent.ConcurrentMapCacheManager; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cache/CachesEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointWebIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cache/CachesEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointWebIntegrationTests.java index d8c5e5b251fd..6189d4582719 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cache/CachesEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/actuate/endpoint/CachesEndpointWebIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cache; +package org.springframework.boot.cache.actuate.endpoint; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/AbstractCacheAutoConfigurationTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/AbstractCacheAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/AbstractCacheAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/AbstractCacheAutoConfigurationTests.java index 7b192e799af5..aa010fc51765 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/AbstractCacheAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/AbstractCacheAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.ArrayList; import java.util.Arrays; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfigurationTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/CacheAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/CacheAutoConfigurationTests.java index 03bd593cc7af..59a64c8fc3e8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/CacheAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -49,7 +49,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.cache.support.MockCachingProvider; import org.springframework.boot.autoconfigure.cache.support.MockCachingProvider.MockCacheManager; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.cache.Cache; @@ -431,7 +431,7 @@ void jCacheCacheWithUnknownProvider() { @Test void jCacheCacheWithConfig() { String cachingProviderFqn = MockCachingProvider.class.getName(); - String configLocation = "org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml"; + String configLocation = "org/springframework/boot/cache/autoconfigure/hazelcast-specific.xml"; this.contextRunner.withUserConfiguration(JCacheCustomConfiguration.class) .withPropertyValues("spring.cache.type=jcache", "spring.cache.jcache.provider=" + cachingProviderFqn, "spring.cache.jcache.config=" + configLocation) @@ -445,7 +445,7 @@ void jCacheCacheWithConfig() { @Test void jCacheCacheWithWrongConfig() { String cachingProviderFqn = MockCachingProvider.class.getName(); - String configLocation = "org/springframework/boot/autoconfigure/cache/does-not-exist.xml"; + String configLocation = "org/springframework/boot/cache/autoconfigure/does-not-exist.xml"; this.contextRunner.withUserConfiguration(JCacheCustomConfiguration.class) .withPropertyValues("spring.cache.type=jcache", "spring.cache.jcache.provider=" + cachingProviderFqn, "spring.cache.jcache.config=" + configLocation) @@ -519,7 +519,7 @@ void hazelcastCacheWithExistingHazelcastInstance() { @Test void hazelcastCacheWithHazelcastAutoConfiguration() { - String hazelcastConfig = "org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml"; + String hazelcastConfig = "org/springframework/boot/cache/autoconfigure/hazelcast-specific.xml"; this.contextRunner.withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class)) .withUserConfiguration(DefaultCacheConfiguration.class) .withPropertyValues("spring.cache.type=hazelcast", "spring.hazelcast.config=" + hazelcastConfig) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizersTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizersTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizersTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizersTests.java index e67f064087ef..6bf57ab7047a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheManagerCustomizersTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/CacheManagerCustomizersTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import java.util.ArrayList; import java.util.Arrays; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/EhCache3CacheAutoConfigurationTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/EhCache3CacheAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/EhCache3CacheAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/EhCache3CacheAutoConfigurationTests.java index d61433c31632..ed5383153b57 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/EhCache3CacheAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/EhCache3CacheAutoConfigurationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure; import org.ehcache.jsr107.EhcacheCachingProvider; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfigurationTests.DefaultCacheConfiguration; +import org.springframework.boot.cache.autoconfigure.CacheAutoConfigurationTests.DefaultCacheConfiguration; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.cache.jcache.JCacheCacheManager; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/endpoint/CachesEndpointAutoConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/endpoint/CachesEndpointAutoConfigurationTests.java index d0c85372ec06..72916d71cff8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/endpoint/CachesEndpointAutoConfigurationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cache; +package org.springframework.boot.cache.autoconfigure.endpoint; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.cache.CachesEndpoint; -import org.springframework.boot.actuate.cache.CachesEndpointWebExtension; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpoint; +import org.springframework.boot.cache.actuate.endpoint.CachesEndpointWebExtension; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cache.CacheManager; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsAutoConfigurationTests.java index 89b97b541d71..53c01969f37f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/autoconfigure/metrics/CacheMetricsAutoConfigurationTests.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.cache; +package org.springframework.boot.cache.autoconfigure.metrics; import java.util.Collections; import java.util.List; import com.github.benmanes.caffeine.cache.CaffeineSpec; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; +import org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurer; @@ -44,7 +44,8 @@ */ class CacheMetricsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class) .withUserConfiguration(CachingConfiguration.class) .withConfiguration(AutoConfigurations.of(CacheAutoConfiguration.class, CacheMetricsAutoConfiguration.class)); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/Cache2kCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/Cache2kCacheMeterBinderProviderTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/Cache2kCacheMeterBinderProviderTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/Cache2kCacheMeterBinderProviderTests.java index a3e06d64f927..24f92586cad7 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/Cache2kCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/Cache2kCacheMeterBinderProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CacheMetricsRegistrarTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/CacheMetricsRegistrarTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CacheMetricsRegistrarTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/CacheMetricsRegistrarTests.java index c3c2fd0aa6c1..996a1fb3c72d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CacheMetricsRegistrarTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/CacheMetricsRegistrarTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/CaffeineCacheMeterBinderProviderTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/CaffeineCacheMeterBinderProviderTests.java index 947ec5538246..95165f3ce331 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/CaffeineCacheMeterBinderProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/HazelcastCacheMeterBinderProviderTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/HazelcastCacheMeterBinderProviderTests.java index 6249ff92bf53..6f2aa704c403 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/HazelcastCacheMeterBinderProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.util.Collections; @@ -26,7 +26,7 @@ import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; +import org.springframework.boot.cache.metrics.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/JCacheCacheMeterBinderProviderTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/JCacheCacheMeterBinderProviderTests.java index cfa67134f628..d8c4de0ca6c2 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/JCacheCacheMeterBinderProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.net.URI; import java.net.URISyntaxException; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/RedisCacheMeterBinderProviderTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMeterBinderProviderTests.java rename to spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/RedisCacheMeterBinderProviderTests.java index 8af8b800bef7..75c11fe10119 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/RedisCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-cache/src/test/java/org/springframework/boot/cache/metrics/RedisCacheMeterBinderProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.cache; +package org.springframework.boot.cache.metrics; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/services/javax.cache.spi.CachingProvider b/spring-boot-project/spring-boot-cache/src/test/resources/META-INF/services/javax.cache.spi.CachingProvider similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/services/javax.cache.spi.CachingProvider rename to spring-boot-project/spring-boot-cache/src/test/resources/META-INF/services/javax.cache.spi.CachingProvider diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml b/spring-boot-project/spring-boot-cache/src/test/resources/org/springframework/boot/cache/autoconfigure/hazelcast-specific.xml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml rename to spring-boot-project/spring-boot-cache/src/test/resources/org/springframework/boot/cache/autoconfigure/hazelcast-specific.xml diff --git a/spring-boot-project/spring-boot-cassandra/build.gradle b/spring-boot-project/spring-boot-cassandra/build.gradle new file mode 100644 index 000000000000..e0c460a87555 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/build.gradle @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Cassandra" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.apache.cassandra:java-driver-core") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("io.projectreactor:reactor-core") + optional("org.testcontainers:cassandra") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:cassandra") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("io.projectreactor:reactor-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationIntegrationTests.java index b70d0f00a11a..7e76c16a1e94 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.config.DriverConfigLoader; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationWithPasswordAuthenticationIntegrationTests.java b/spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationWithPasswordAuthenticationIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationWithPasswordAuthenticationIntegrationTests.java rename to spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationWithPasswordAuthenticationIntegrationTests.java index 11f92509cae9..09880e9100be 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationWithPasswordAuthenticationIntegrationTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationWithPasswordAuthenticationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/docker/compose/CassandraDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 90% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/docker/compose/CassandraDockerComposeConnectionDetailsFactoryIntegrationTests.java index dc20d1012a9e..7e81077e1d05 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/docker/compose/CassandraDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.cassandra; +package org.springframework.boot.cassandra.docker.compose; import java.util.List; -import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails; -import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails.Node; +import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails; +import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails.Node; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/cassandra/CassandraContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/testcontainers/CassandraContainerConnectionDetailsFactoryTests.java similarity index 91% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/cassandra/CassandraContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/testcontainers/CassandraContainerConnectionDetailsFactoryTests.java index 4b1bebe50ebe..7cbd5440cad5 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/cassandra/CassandraContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/dockerTest/java/org/springframework/boot/cassandra/testcontainers/CassandraContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.cassandra; +package org.springframework.boot.cassandra.testcontainers; import com.datastax.oss.driver.api.core.CqlSession; import org.junit.jupiter.api.Test; @@ -24,8 +24,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/cassandra/cassandra-bitnami-compose.yaml b/spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/org/springframework/boot/cassandra/docker/compose/cassandra-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/cassandra/cassandra-bitnami-compose.yaml rename to spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/org/springframework/boot/cassandra/docker/compose/cassandra-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/cassandra/cassandra-compose.yaml b/spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/org/springframework/boot/cassandra/docker/compose/cassandra-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/cassandra/cassandra-compose.yaml rename to spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/org/springframework/boot/cassandra/docker/compose/cassandra-compose.yaml diff --git a/spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfiguration.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfiguration.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfiguration.java index 67d69263b602..b6922c9fc9b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfiguration.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import java.io.IOException; import java.time.Duration; @@ -39,14 +39,14 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraProperties.Connection; -import org.springframework.boot.autoconfigure.cassandra.CassandraProperties.Controlconnection; -import org.springframework.boot.autoconfigure.cassandra.CassandraProperties.Request; -import org.springframework.boot.autoconfigure.cassandra.CassandraProperties.Ssl; -import org.springframework.boot.autoconfigure.cassandra.CassandraProperties.Throttler; -import org.springframework.boot.autoconfigure.cassandra.CassandraProperties.ThrottlerType; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.cassandra.autoconfigure.CassandraProperties.Connection; +import org.springframework.boot.cassandra.autoconfigure.CassandraProperties.Controlconnection; +import org.springframework.boot.cassandra.autoconfigure.CassandraProperties.Request; +import org.springframework.boot.cassandra.autoconfigure.CassandraProperties.Ssl; +import org.springframework.boot.cassandra.autoconfigure.CassandraProperties.Throttler; +import org.springframework.boot.cassandra.autoconfigure.CassandraProperties.ThrottlerType; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.ssl.SslBundle; @@ -72,7 +72,7 @@ * @author Andy Wilkinson * @author Phillip Webb * @author Scott Frederick - * @since 1.3.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(CqlSession.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraConnectionDetails.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraConnectionDetails.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraConnectionDetails.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraConnectionDetails.java index 1c614febce08..e0019dbdefa7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraConnectionDetails.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import java.util.List; @@ -27,7 +27,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface CassandraConnectionDetails extends ConnectionDetails { @@ -63,7 +63,6 @@ default String getPassword() { /** * SSL bundle to use. * @return the SSL bundle to use - * @since 3.5.0 */ default SslBundle getSslBundle() { return null; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraProperties.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraProperties.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraProperties.java index 13841174942a..039005cd0af1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraProperties.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CassandraProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import java.time.Duration; import java.util.List; @@ -32,7 +32,7 @@ * @author Mark Paluch * @author Stephane Nicoll * @author Scott Frederick - * @since 1.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.cassandra") public class CassandraProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CqlSessionBuilderCustomizer.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CqlSessionBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CqlSessionBuilderCustomizer.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CqlSessionBuilderCustomizer.java index ce0b1e7a153f..6f14a1750337 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CqlSessionBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/CqlSessionBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.CqlSessionBuilder; @@ -25,7 +25,7 @@ * auto-configuration. * * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface CqlSessionBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/DriverConfigLoaderBuilderCustomizer.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/DriverConfigLoaderBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/DriverConfigLoaderBuilderCustomizer.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/DriverConfigLoaderBuilderCustomizer.java index 71e21a0e233f..2c774a3c83fa 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/DriverConfigLoaderBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/DriverConfigLoaderBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.config.DriverConfigLoader; import com.datastax.oss.driver.api.core.config.ProgrammaticDriverConfigLoaderBuilder; @@ -25,7 +25,7 @@ * retaining default auto-configuration. * * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ public interface DriverConfigLoaderBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorAutoConfiguration.java new file mode 100644 index 000000000000..bac76210cfb9 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorAutoConfiguration.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cassandra.autoconfigure.health; + +import com.datastax.oss.driver.api.core.CqlSession; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.health.CassandraHealthContributorConfigurations.CassandraDriverConfiguration; +import org.springframework.boot.cassandra.health.CassandraDriverHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link CassandraDriverHealthIndicator}. + * + * @author Julien Dubois + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration( + after = { CassandraReactiveHealthContributorAutoConfiguration.class, CassandraAutoConfiguration.class }) +@ConditionalOnClass({ CqlSession.class, CassandraDriverHealthIndicator.class, + ConditionalOnEnabledHealthIndicator.class }) +@ConditionalOnEnabledHealthIndicator("cassandra") +@Import(CassandraDriverConfiguration.class) +public class CassandraHealthContributorAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorConfigurations.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorConfigurations.java similarity index 79% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorConfigurations.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorConfigurations.java index a001a7b85cc2..582d775145ef 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorConfigurations.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorConfigurations.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure.health; import java.util.Map; import com.datastax.oss.driver.api.core.CqlSession; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration; -import org.springframework.boot.actuate.cassandra.CassandraDriverHealthIndicator; -import org.springframework.boot.actuate.cassandra.CassandraDriverReactiveHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.cassandra.health.CassandraDriverHealthIndicator; +import org.springframework.boot.cassandra.health.CassandraDriverReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfiguration; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraReactiveHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraReactiveHealthContributorAutoConfiguration.java new file mode 100644 index 000000000000..e87192fd5bf2 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraReactiveHealthContributorAutoConfiguration.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cassandra.autoconfigure.health; + +import com.datastax.oss.driver.api.core.CqlSession; +import reactor.core.publisher.Flux; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.health.CassandraHealthContributorConfigurations.CassandraReactiveDriverConfiguration; +import org.springframework.boot.cassandra.health.CassandraDriverReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link CassandraDriverReactiveHealthIndicator}. + * + * @author Artsiom Yudovin + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration(after = CassandraAutoConfiguration.class) +@ConditionalOnClass({ CqlSession.class, Flux.class, CassandraDriverReactiveHealthIndicator.class, + ConditionalOnEnabledHealthIndicator.class }) +@ConditionalOnEnabledHealthIndicator("cassandra") +@Import(CassandraReactiveDriverConfiguration.class) +public class CassandraReactiveHealthContributorAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..198ea52bc983 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Cassandra health. + */ +package org.springframework.boot.cassandra.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/package-info.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/package-info.java new file mode 100644 index 000000000000..85133e9ce134 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Cassandra. + */ +package org.springframework.boot.cassandra.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/CassandraDockerComposeConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/CassandraDockerComposeConnectionDetailsFactory.java index 689485bee814..c31f83447cf7 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/CassandraDockerComposeConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.cassandra; +package org.springframework.boot.cassandra.docker.compose; import java.util.List; -import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails; +import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraEnvironment.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/CassandraEnvironment.java similarity index 92% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraEnvironment.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/CassandraEnvironment.java index 559959b52213..ffa7fcf77ba7 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraEnvironment.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/CassandraEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.cassandra; +package org.springframework.boot.cassandra.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/package-info.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/package-info.java new file mode 100644 index 000000000000..d2e20b2ba074 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Cassandra service connections. + */ +package org.springframework.boot.cassandra.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/CassandraDriverHealthIndicator.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/CassandraDriverHealthIndicator.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/CassandraDriverHealthIndicator.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/CassandraDriverHealthIndicator.java index 19e713eef392..a83e1d0cd8b9 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/CassandraDriverHealthIndicator.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/CassandraDriverHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cassandra; +package org.springframework.boot.cassandra.health; import java.util.Collection; import java.util.Optional; @@ -23,10 +23,10 @@ import com.datastax.oss.driver.api.core.metadata.Node; import com.datastax.oss.driver.api.core.metadata.NodeState; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.util.Assert; /** @@ -35,7 +35,7 @@ * * @author Alexandre Dutra * @author Tomasz Lelek - * @since 2.4.0 + * @since 4.0.0 */ public class CassandraDriverHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/CassandraDriverReactiveHealthIndicator.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/CassandraDriverReactiveHealthIndicator.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/CassandraDriverReactiveHealthIndicator.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/CassandraDriverReactiveHealthIndicator.java index b10bf44b772c..3be8d4637a43 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/CassandraDriverReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/CassandraDriverReactiveHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cassandra; +package org.springframework.boot.cassandra.health; import java.util.Collection; import java.util.Optional; @@ -24,10 +24,10 @@ import com.datastax.oss.driver.api.core.metadata.NodeState; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.util.Assert; /** @@ -36,7 +36,7 @@ * * @author Alexandre Dutra * @author Tomasz Lelek - * @since 2.4.0 + * @since 4.0.0 */ public class CassandraDriverReactiveHealthIndicator extends AbstractReactiveHealthIndicator { diff --git a/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/package-info.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/package-info.java new file mode 100644 index 000000000000..a50479056a4b --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for Cassandra. + */ +package org.springframework.boot.cassandra.health; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/CassandraContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/testcontainers/CassandraContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/CassandraContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/testcontainers/CassandraContainerConnectionDetailsFactory.java index 8899ae0ea0af..c38028a70e18 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/CassandraContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/testcontainers/CassandraContainerConnectionDetailsFactory.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.cassandra; +package org.springframework.boot.cassandra.testcontainers; import java.net.InetSocketAddress; import java.util.List; import org.testcontainers.cassandra.CassandraContainer; -import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails; +import org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; diff --git a/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/testcontainers/package-info.java b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/testcontainers/package-info.java new file mode 100644 index 000000000000..d6a63858c6ad --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/java/org/springframework/boot/cassandra/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Cassandra service connections. + */ +package org.springframework.boot.cassandra.testcontainers; diff --git a/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..aa96aa44b323 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,74 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.health.cassandra.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Cassandra health check.", + "defaultValue": true + }, + { + "name": "spring.cassandra.compression", + "defaultValue": "none" + }, + { + "name": "spring.cassandra.connection.connect-timeout", + "defaultValue": "5s" + }, + { + "name": "spring.cassandra.connection.init-query-timeout", + "defaultValue": "5s" + }, + { + "name": "spring.cassandra.contact-points", + "defaultValue": [ + "127.0.0.1:9042" + ] + }, + { + "name": "spring.cassandra.controlconnection.timeout", + "defaultValue": "5s" + }, + { + "name": "spring.cassandra.pool.heartbeat-interval", + "defaultValue": "30s" + }, + { + "name": "spring.cassandra.pool.idle-timeout", + "defaultValue": "5s" + }, + { + "name": "spring.cassandra.request.page-size", + "defaultValue": 5000 + }, + { + "name": "spring.cassandra.request.throttler.type", + "defaultValue": "none" + }, + { + "name": "spring.cassandra.request.timeout", + "defaultValue": "2s" + }, + { + "name": "spring.cassandra.ssl", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.cassandra.ssl.enabled", + "level": "error" + } + } + ], + "hints": [ + { + "name": "spring.cassandra.schema-action", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "org.springframework.data.cassandra.config.SchemaAction" + } + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..feea7d785dd0 --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.cassandra.docker.compose.CassandraDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.cassandra.testcontainers.CassandraContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..8a7816e460ee --- /dev/null +++ b/spring-boot-project/spring-boot-cassandra/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration +org.springframework.boot.cassandra.autoconfigure.health.CassandraHealthContributorAutoConfiguration +org.springframework.boot.cassandra.autoconfigure.health.CassandraReactiveHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationTests.java b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationTests.java index c0537c577655..e61ccc3a955b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/CassandraAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import java.time.Duration; import java.util.Collections; @@ -34,8 +34,8 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration.PropertiesCassandraConnectionDetails; import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration.PropertiesCassandraConnectionDetails; import org.springframework.boot.ssl.NoSuchSslBundleException; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; @@ -346,7 +346,7 @@ void driverConfigLoaderCustomizeRateLimitingRequestThrottler() { @Test void driverConfigLoaderWithConfigComplementSettings() { - String configLocation = "org/springframework/boot/autoconfigure/cassandra/simple.conf"; + String configLocation = "org/springframework/boot/cassandra/autoconfigure/simple.conf"; this.contextRunner .withPropertyValues("spring.cassandra.session-name=testcluster", "spring.cassandra.config=" + configLocation) @@ -365,7 +365,7 @@ void driverConfigLoaderWithConfigComplementSettings() { @Test // gh-31238 void driverConfigLoaderWithConfigOverridesDefaults() { - String configLocation = "org/springframework/boot/autoconfigure/cassandra/override-defaults.conf"; + String configLocation = "org/springframework/boot/cassandra/autoconfigure/override-defaults.conf"; this.contextRunner.withPropertyValues("spring.cassandra.config=" + configLocation).run((context) -> { DriverExecutionProfile actual = context.getBean(DriverConfigLoader.class) .getInitialConfig() @@ -400,7 +400,7 @@ void placeholdersInReferenceConfAreResolvedAgainstConfigDerivedFromSpringCassand @Test void driverConfigLoaderWithConfigCreateProfiles() { - String configLocation = "org/springframework/boot/autoconfigure/cassandra/profiles.conf"; + String configLocation = "org/springframework/boot/cassandra/autoconfigure/profiles.conf"; this.contextRunner.withPropertyValues("spring.cassandra.config=" + configLocation).run((context) -> { assertThat(context).hasSingleBean(DriverConfigLoader.class); DriverConfig driverConfig = context.getBean(DriverConfigLoader.class).getInitialConfig(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cassandra/CassandraPropertiesTests.java b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/CassandraPropertiesTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cassandra/CassandraPropertiesTests.java rename to spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/CassandraPropertiesTests.java index 05f583d17682..aed4b5dea9e7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cassandra/CassandraPropertiesTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/CassandraPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorAutoConfigurationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorAutoConfigurationTests.java index 8c719b8dc842..019ffb76d0c7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraHealthContributorAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure.health; import com.datastax.oss.driver.api.core.CqlSession; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.cassandra.CassandraDriverHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.cassandra.health.CassandraDriverHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraReactiveHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraReactiveHealthContributorAutoConfigurationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraReactiveHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraReactiveHealthContributorAutoConfigurationTests.java index d980eadc0cba..f8011ab7be0c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraReactiveHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/autoconfigure/health/CassandraReactiveHealthContributorAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cassandra; +package org.springframework.boot.cassandra.autoconfigure.health; import com.datastax.oss.driver.api.core.CqlSession; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.cassandra.CassandraDriverReactiveHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.cassandra.health.CassandraDriverReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraEnvironmentTests.java b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/docker/compose/CassandraEnvironmentTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraEnvironmentTests.java rename to spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/docker/compose/CassandraEnvironmentTests.java index d008617d3c3b..3ad89026cf43 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/cassandra/CassandraEnvironmentTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/docker/compose/CassandraEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.cassandra; +package org.springframework.boot.cassandra.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cassandra/CassandraDriverHealthIndicatorTests.java b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/health/CassandraDriverHealthIndicatorTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cassandra/CassandraDriverHealthIndicatorTests.java rename to spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/health/CassandraDriverHealthIndicatorTests.java index 0ead0bd47d3e..fe6ac9ea7254 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cassandra/CassandraDriverHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/health/CassandraDriverHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cassandra; +package org.springframework.boot.cassandra.health; import java.util.ArrayList; import java.util.Collections; @@ -31,8 +31,8 @@ import com.datastax.oss.driver.api.core.metadata.NodeState; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cassandra/CassandraDriverReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/health/CassandraDriverReactiveHealthIndicatorTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cassandra/CassandraDriverReactiveHealthIndicatorTests.java rename to spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/health/CassandraDriverReactiveHealthIndicatorTests.java index 5799572e667c..c8472006b27c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cassandra/CassandraDriverReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-cassandra/src/test/java/org/springframework/boot/cassandra/health/CassandraDriverReactiveHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.cassandra; +package org.springframework.boot.cassandra.health; import java.time.Duration; import java.util.ArrayList; @@ -34,8 +34,8 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cassandra/override-defaults.conf b/spring-boot-project/spring-boot-cassandra/src/test/resources/org/springframework/boot/cassandra/autoconfigure/override-defaults.conf similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cassandra/override-defaults.conf rename to spring-boot-project/spring-boot-cassandra/src/test/resources/org/springframework/boot/cassandra/autoconfigure/override-defaults.conf diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cassandra/profiles.conf b/spring-boot-project/spring-boot-cassandra/src/test/resources/org/springframework/boot/cassandra/autoconfigure/profiles.conf similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cassandra/profiles.conf rename to spring-boot-project/spring-boot-cassandra/src/test/resources/org/springframework/boot/cassandra/autoconfigure/profiles.conf diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cassandra/simple.conf b/spring-boot-project/spring-boot-cassandra/src/test/resources/org/springframework/boot/cassandra/autoconfigure/simple.conf similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cassandra/simple.conf rename to spring-boot-project/spring-boot-cassandra/src/test/resources/org/springframework/boot/cassandra/autoconfigure/simple.conf diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cassandra/test.jks b/spring-boot-project/spring-boot-cassandra/src/test/resources/org/springframework/boot/cassandra/autoconfigure/test.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/cassandra/test.jks rename to spring-boot-project/spring-boot-cassandra/src/test/resources/org/springframework/boot/cassandra/autoconfigure/test.jks diff --git a/spring-boot-project/spring-boot-cloudfoundry/build.gradle b/spring-boot-project/spring-boot-cloudfoundry/build.gradle new file mode 100644 index 000000000000..af39ade15067 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/build.gradle @@ -0,0 +1,55 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Cloud Foundry" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-actuator")) + api(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + + implementation(project(":spring-boot-project:spring-boot-security")) + + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-restclient")) + optional(project(":spring-boot-project:spring-boot-webclient")) + optional(project(":spring-boot-project:spring-boot-webflux")) + optional(project(":spring-boot-project:spring-boot-webmvc")) + optional("io.projectreactor:reactor-core") + optional("io.projectreactor.netty:reactor-netty-http") + optional("jakarta.servlet:jakarta.servlet-api") + + testImplementation(project(":spring-boot-project:spring-boot-http-converter")) + testImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) + testImplementation(project(":spring-boot-project:spring-boot-restclient-test")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("com.squareup.okhttp3:mockwebserver") + testImplementation("io.projectreactor:reactor-test") + testImplementation("org.springframework.security:spring-security-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/AccessLevel.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/AccessLevel.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/AccessLevel.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/AccessLevel.java index 28736bdd8a49..db53b99d5462 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/AccessLevel.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/AccessLevel.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import java.util.Arrays; import java.util.List; @@ -24,7 +24,7 @@ * endpoints. * * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ public enum AccessLevel { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryAuthorizationException.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryAuthorizationException.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryAuthorizationException.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryAuthorizationException.java index 2bbaf44a24fc..de572b5addce 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryAuthorizationException.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryAuthorizationException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import org.springframework.http.HttpStatus; @@ -22,7 +22,7 @@ * Authorization exceptions thrown to limit access to the endpoints. * * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ public class CloudFoundryAuthorizationException extends RuntimeException { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointExposureOutcomeContributor.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointExposureOutcomeContributor.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointExposureOutcomeContributor.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointExposureOutcomeContributor.java index f30ea80e1a19..385699415007 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointExposureOutcomeContributor.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointExposureOutcomeContributor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import java.util.Set; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointFilter.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointFilter.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointFilter.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointFilter.java index 4b18347877f0..e5fb83f59dbc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointFilter.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import org.springframework.boot.actuate.endpoint.EndpointFilter; import org.springframework.boot.actuate.endpoint.annotation.DiscovererEndpointFilter; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryWebEndpointDiscoverer.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryWebEndpointDiscoverer.java new file mode 100644 index 000000000000..f6c52faa326f --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryWebEndpointDiscoverer.java @@ -0,0 +1,99 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; + +import java.util.Collection; +import java.util.List; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.boot.actuate.endpoint.EndpointFilter; +import org.springframework.boot.actuate.endpoint.OperationFilter; +import org.springframework.boot.actuate.endpoint.invoke.OperationInvokerAdvisor; +import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; +import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; +import org.springframework.boot.actuate.endpoint.web.PathMapper; +import org.springframework.boot.actuate.endpoint.web.WebOperation; +import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryWebEndpointDiscoverer.CloudFoundryWebEndpointDiscovererRuntimeHints; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.core.annotation.MergedAnnotations; + +/** + * {@link WebEndpointDiscoverer} for Cloud Foundry that uses Cloud Foundry specific + * extensions for the {@link HealthEndpoint}. + * + * @author Madhura Bhave + * @since 4.0.0 + */ +@ImportRuntimeHints(CloudFoundryWebEndpointDiscovererRuntimeHints.class) +public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer { + + /** + * Create a new {@link WebEndpointDiscoverer} instance. + * @param applicationContext the source application context + * @param parameterValueMapper the parameter value mapper + * @param endpointMediaTypes the endpoint media types + * @param endpointPathMappers the endpoint path mappers + * @param invokerAdvisors invoker advisors to apply + * @param endpointFilters endpoint filters to apply + * @param operationFilters operation filters to apply + */ + public CloudFoundryWebEndpointDiscoverer(ApplicationContext applicationContext, + ParameterValueMapper parameterValueMapper, EndpointMediaTypes endpointMediaTypes, + List endpointPathMappers, Collection invokerAdvisors, + Collection> endpointFilters, + Collection> operationFilters) { + super(applicationContext, parameterValueMapper, endpointMediaTypes, endpointPathMappers, null, invokerAdvisors, + endpointFilters, operationFilters); + } + + @Override + protected boolean isExtensionTypeExposed(Class extensionBeanType) { + // Filter regular health endpoint extensions so a CF version can replace them + return !isHealthEndpointExtension(extensionBeanType) + || isCloudFoundryHealthEndpointExtension(extensionBeanType); + } + + private boolean isHealthEndpointExtension(Class extensionBeanType) { + return MergedAnnotations.from(extensionBeanType) + .get(EndpointWebExtension.class) + .getValue("endpoint", Class.class) + .map(HealthEndpoint.class::isAssignableFrom) + .orElse(false); + } + + private boolean isCloudFoundryHealthEndpointExtension(Class extensionBeanType) { + return MergedAnnotations.from(extensionBeanType).isPresent(EndpointCloudFoundryExtension.class); + } + + static class CloudFoundryWebEndpointDiscovererRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection() + .registerType(CloudFoundryEndpointFilter.class, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/EndpointCloudFoundryExtension.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/EndpointCloudFoundryExtension.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/EndpointCloudFoundryExtension.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/EndpointCloudFoundryExtension.java index 64419ce0a01b..9465df2437f3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/EndpointCloudFoundryExtension.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/EndpointCloudFoundryExtension.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,7 +32,7 @@ * * @author Phillip Webb * @author Madhura Bhave - * @since 2.2.0 + * @since 4.0.0 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/SecurityResponse.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/SecurityResponse.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/SecurityResponse.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/SecurityResponse.java index fb55ee976b4e..1dc501ef73b6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/SecurityResponse.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/SecurityResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import org.springframework.http.HttpStatus; @@ -22,7 +22,7 @@ * Response from the Cloud Foundry security interceptors. * * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ public class SecurityResponse { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/Token.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/Token.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/Token.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/Token.java index 7401682c43c2..ff1aa77aef19 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/Token.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/Token.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; import java.util.Map; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; import org.springframework.boot.json.JsonParserFactory; import org.springframework.util.StringUtils; @@ -29,7 +29,7 @@ * The JSON web token provided with each request that originates from Cloud Foundry. * * @author Madhura Bhave - * @since 1.5.22 + * @since 4.0.0 */ public class Token { diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/package-info.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/package-info.java new file mode 100644 index 000000000000..b68f0463dc67 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Cloud Foundry endpoints. + */ +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveActuatorAutoConfiguration.java new file mode 100644 index 000000000000..56ac8edb62f4 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveActuatorAutoConfiguration.java @@ -0,0 +1,204 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; +import org.springframework.boot.actuate.endpoint.ExposableEndpoint; +import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; +import org.springframework.boot.actuate.info.GitInfoContributor; +import org.springframework.boot.actuate.info.InfoContributor; +import org.springframework.boot.actuate.info.InfoEndpoint; +import org.springframework.boot.actuate.info.InfoPropertiesInfoContributor; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.cloud.CloudPlatform; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryWebEndpointDiscoverer; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet.CloudFoundryInfoEndpointWebExtension; +import org.springframework.boot.info.GitProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.security.web.server.MatcherSecurityWebFilterChain; +import org.springframework.security.web.server.WebFilterChainProxy; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; +import org.springframework.util.function.SingletonSupplier; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.server.WebFilter; + +/** + * {@link EnableAutoConfiguration Auto-configuration} to expose actuator endpoints for + * Cloud Foundry to use in a reactive environment. + * + * @author Madhura Bhave + * @since 4.0.0 + */ +@AutoConfiguration(after = { HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class }) +@ConditionalOnBooleanProperty(name = "management.cloudfoundry.enabled", matchIfMissing = true) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY) +public class CloudFoundryReactiveActuatorAutoConfiguration { + + private static final String BASE_PATH = "/cloudfoundryapplication"; + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + @ConditionalOnBean({ HealthEndpoint.class, ReactiveHealthEndpointWebExtension.class }) + public CloudFoundryReactiveHealthEndpointWebExtension cloudFoundryReactiveHealthEndpointWebExtension( + ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension) { + return new CloudFoundryReactiveHealthEndpointWebExtension(reactiveHealthEndpointWebExtension); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + @ConditionalOnBean({ InfoEndpoint.class, GitProperties.class }) + public CloudFoundryInfoEndpointWebExtension cloudFoundryInfoEndpointWebExtension(GitProperties properties, + ObjectProvider infoContributors) { + List contributors = infoContributors.orderedStream() + .map((infoContributor) -> (infoContributor instanceof GitInfoContributor) + ? new GitInfoContributor(properties, InfoPropertiesInfoContributor.Mode.FULL) : infoContributor) + .toList(); + return new CloudFoundryInfoEndpointWebExtension(new InfoEndpoint(contributors)); + } + + @Bean + @SuppressWarnings("removal") + public CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebFluxEndpointHandlerMapping( + ParameterValueMapper parameterMapper, EndpointMediaTypes endpointMediaTypes, + WebClient.Builder webClientBuilder, + org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier controllerEndpointsSupplier, + ApplicationContext applicationContext) { + CloudFoundryWebEndpointDiscoverer endpointDiscoverer = new CloudFoundryWebEndpointDiscoverer(applicationContext, + parameterMapper, endpointMediaTypes, null, Collections.emptyList(), Collections.emptyList(), + Collections.emptyList()); + SecurityInterceptor securityInterceptor = getSecurityInterceptor(webClientBuilder, + applicationContext.getEnvironment()); + Collection webEndpoints = endpointDiscoverer.getEndpoints(); + List> allEndpoints = new ArrayList<>(); + allEndpoints.addAll(webEndpoints); + allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); + return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping(BASE_PATH), webEndpoints, + endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints); + } + + private SecurityInterceptor getSecurityInterceptor(WebClient.Builder webClientBuilder, Environment environment) { + SecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService(webClientBuilder, environment); + TokenValidator tokenValidator = new TokenValidator(cloudfoundrySecurityService); + return new SecurityInterceptor(tokenValidator, cloudfoundrySecurityService, + environment.getProperty("vcap.application.application_id")); + } + + private SecurityService getCloudFoundrySecurityService(WebClient.Builder webClientBuilder, + Environment environment) { + String cloudControllerUrl = environment.getProperty("vcap.application.cf_api"); + boolean skipSslValidation = environment.getProperty("management.cloudfoundry.skip-ssl-validation", + Boolean.class, false); + return (cloudControllerUrl != null) + ? new SecurityService(webClientBuilder, cloudControllerUrl, skipSslValidation) : null; + } + + private CorsConfiguration getCorsConfiguration() { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL); + corsConfiguration.setAllowedMethods(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name())); + corsConfiguration + .setAllowedHeaders(Arrays.asList(HttpHeaders.AUTHORIZATION, "X-Cf-App-Instance", HttpHeaders.CONTENT_TYPE)); + return corsConfiguration; + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(MatcherSecurityWebFilterChain.class) + static class IgnoredPathsSecurityConfiguration { + + @Bean + static WebFilterChainPostProcessor webFilterChainPostProcessor( + ObjectProvider handlerMapping) { + return new WebFilterChainPostProcessor(handlerMapping); + } + + } + + static class WebFilterChainPostProcessor implements BeanPostProcessor { + + private final Supplier pathMappedEndpoints; + + WebFilterChainPostProcessor(ObjectProvider handlerMapping) { + this.pathMappedEndpoints = SingletonSupplier + .of(() -> new PathMappedEndpoints(BASE_PATH, () -> handlerMapping.getObject().getAllEndpoints())); + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof WebFilterChainProxy webFilterChainProxy) { + return postProcess(webFilterChainProxy); + } + return bean; + } + + private WebFilterChainProxy postProcess(WebFilterChainProxy existing) { + List paths = getPaths(this.pathMappedEndpoints.get()); + ServerWebExchangeMatcher cloudFoundryRequestMatcher = ServerWebExchangeMatchers + .pathMatchers(paths.toArray(new String[] {})); + WebFilter noOpFilter = (exchange, chain) -> chain.filter(exchange); + MatcherSecurityWebFilterChain ignoredRequestFilterChain = new MatcherSecurityWebFilterChain( + cloudFoundryRequestMatcher, Collections.singletonList(noOpFilter)); + MatcherSecurityWebFilterChain allRequestsFilterChain = new MatcherSecurityWebFilterChain( + ServerWebExchangeMatchers.anyExchange(), Collections.singletonList(existing)); + return new WebFilterChainProxy(ignoredRequestFilterChain, allRequestsFilterChain); + } + + private static List getPaths(PathMappedEndpoints pathMappedEndpoints) { + List paths = new ArrayList<>(); + pathMappedEndpoints.getAllPaths().forEach((path) -> paths.add(path + "/**")); + paths.add(BASE_PATH); + paths.add(BASE_PATH + "/"); + return paths; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryReactiveHealthEndpointWebExtension.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveHealthEndpointWebExtension.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryReactiveHealthEndpointWebExtension.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveHealthEndpointWebExtension.java index ecab820d3db2..527b81b15cc3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryReactiveHealthEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveHealthEndpointWebExtension.java @@ -14,11 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.EndpointCloudFoundryExtension; import org.springframework.boot.actuate.endpoint.ApiVersion; import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension; @@ -26,16 +25,17 @@ import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.annotation.Selector.Match; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; -import org.springframework.boot.actuate.health.HealthComponent; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.EndpointCloudFoundryExtension; +import org.springframework.boot.health.contributor.ContributedHealth; /** * Reactive {@link EndpointExtension @EndpointExtension} for the {@link HealthEndpoint} * that always exposes full health details. * * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ @EndpointCloudFoundryExtension(endpoint = HealthEndpoint.class) public class CloudFoundryReactiveHealthEndpointWebExtension { @@ -47,12 +47,12 @@ public CloudFoundryReactiveHealthEndpointWebExtension(ReactiveHealthEndpointWebE } @ReadOperation - public Mono> health(ApiVersion apiVersion) { + public Mono> health(ApiVersion apiVersion) { return this.delegate.health(apiVersion, null, SecurityContext.NONE, true); } @ReadOperation - public Mono> health(ApiVersion apiVersion, + public Mono> health(ApiVersion apiVersion, @Selector(match = Match.ALL_REMAINING) String... path) { return this.delegate.health(apiVersion, null, SecurityContext.NONE, true, path); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java index c8643f797da5..8cadc032088d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; import java.util.Collection; import java.util.Collections; @@ -30,9 +30,6 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.annotation.Reflective; import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; @@ -41,7 +38,10 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; import org.springframework.boot.actuate.endpoint.web.WebOperation; -import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.SecurityResponse; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -61,7 +61,7 @@ @ImportRuntimeHints(CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints.class) class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandlerMapping { - private final CloudFoundrySecurityInterceptor securityInterceptor; + private final SecurityInterceptor securityInterceptor; private final EndpointLinksResolver linksResolver; @@ -69,7 +69,7 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH CloudFoundryWebFluxEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, - CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor, + CorsConfiguration corsConfiguration, SecurityInterceptor securityInterceptor, Collection> allEndpoints) { super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, true); this.linksResolver = new EndpointLinksResolver(allEndpoints); @@ -135,11 +135,11 @@ private static class SecureReactiveWebOperation implements ReactiveWebOperation private final ReactiveWebOperation delegate; - private final CloudFoundrySecurityInterceptor securityInterceptor; + private final SecurityInterceptor securityInterceptor; private final EndpointId endpointId; - SecureReactiveWebOperation(ReactiveWebOperation delegate, CloudFoundrySecurityInterceptor securityInterceptor, + SecureReactiveWebOperation(ReactiveWebOperation delegate, SecurityInterceptor securityInterceptor, EndpointId endpointId) { this.delegate = delegate; this.securityInterceptor = securityInterceptor; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityInterceptor.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityInterceptor.java new file mode 100644 index 000000000000..033b563befe3 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityInterceptor.java @@ -0,0 +1,113 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.util.Locale; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Mono; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.SecurityResponse; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.Token; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.util.StringUtils; +import org.springframework.web.cors.reactive.CorsUtils; +import org.springframework.web.server.ServerWebExchange; + +/** + * Security interceptor to validate the cloud foundry token. + * + * @author Madhura Bhave + */ +class SecurityInterceptor { + + private static final Log logger = LogFactory.getLog(SecurityInterceptor.class); + + private final TokenValidator tokenValidator; + + private final SecurityService cloudFoundrySecurityService; + + private final String applicationId; + + private static final Mono SUCCESS = Mono.just(SecurityResponse.success()); + + SecurityInterceptor(TokenValidator tokenValidator, SecurityService cloudFoundrySecurityService, + String applicationId) { + this.tokenValidator = tokenValidator; + this.cloudFoundrySecurityService = cloudFoundrySecurityService; + this.applicationId = applicationId; + } + + Mono preHandle(ServerWebExchange exchange, String id) { + ServerHttpRequest request = exchange.getRequest(); + if (CorsUtils.isPreFlightRequest(request)) { + return SUCCESS; + } + if (!StringUtils.hasText(this.applicationId)) { + return Mono.error(new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, + "Application id is not available")); + } + if (this.cloudFoundrySecurityService == null) { + return Mono.error(new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, + "Cloud controller URL is not available")); + } + return check(exchange, id).then(SUCCESS).doOnError(this::logError).onErrorResume(this::getErrorResponse); + } + + private void logError(Throwable ex) { + logger.error(ex.getMessage(), ex); + } + + private Mono check(ServerWebExchange exchange, String id) { + try { + Token token = getToken(exchange.getRequest()); + return this.tokenValidator.validate(token) + .then(this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId)) + .filter((accessLevel) -> accessLevel.isAccessAllowed(id)) + .switchIfEmpty( + Mono.error(new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"))) + .doOnSuccess((accessLevel) -> exchange.getAttributes().put("cloudFoundryAccessLevel", accessLevel)) + .then(); + } + catch (CloudFoundryAuthorizationException ex) { + return Mono.error(ex); + } + } + + private Mono getErrorResponse(Throwable throwable) { + if (throwable instanceof CloudFoundryAuthorizationException cfException) { + return Mono.just(new SecurityResponse(cfException.getStatusCode(), + "{\"security_error\":\"" + cfException.getMessage() + "\"}")); + } + return Mono.just(new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR, throwable.getMessage())); + } + + private Token getToken(ServerHttpRequest request) { + String authorization = request.getHeaders().getFirst("Authorization"); + String bearerPrefix = "bearer "; + if (authorization == null || !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) { + throw new CloudFoundryAuthorizationException(Reason.MISSING_AUTHORIZATION, + "Authorization header is missing or invalid"); + } + return new Token(authorization.substring(bearerPrefix.length())); + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityService.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityService.java new file mode 100644 index 000000000000..8e34c1d6ba92 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityService.java @@ -0,0 +1,160 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.netty.handler.ssl.SslProvider; +import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import reactor.core.publisher.Mono; +import reactor.netty.http.Http11SslContextSpec; +import reactor.netty.http.client.HttpClient; +import reactor.netty.tcp.SslProvider.GenericSslContextSpec; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.util.Assert; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec; +import org.springframework.web.reactive.function.client.WebClientResponseException; + +/** + * Reactive Cloud Foundry security service to handle REST calls to the cloud controller + * and UAA. + * + * @author Madhura Bhave + */ +class SecurityService { + + private static final ParameterizedTypeReference> STRING_OBJECT_MAP = new ParameterizedTypeReference<>() { + }; + + private final WebClient webClient; + + private final String cloudControllerUrl; + + SecurityService(WebClient.Builder webClientBuilder, String cloudControllerUrl, boolean skipSslValidation) { + Assert.notNull(webClientBuilder, "'webClientBuilder' must not be null"); + Assert.notNull(cloudControllerUrl, "'cloudControllerUrl' must not be null"); + if (skipSslValidation) { + webClientBuilder.clientConnector(buildTrustAllSslConnector()); + } + this.webClient = webClientBuilder.build(); + this.cloudControllerUrl = cloudControllerUrl; + } + + protected ReactorClientHttpConnector buildTrustAllSslConnector() { + HttpClient client = HttpClient.create().secure((spec) -> spec.sslContext(createSslContextSpec())); + return new ReactorClientHttpConnector(client); + } + + private GenericSslContextSpec createSslContextSpec() { + return Http11SslContextSpec.forClient() + .configure((builder) -> builder.sslProvider(SslProvider.JDK) + .trustManager(InsecureTrustManagerFactory.INSTANCE)); + } + + /** + * Return a Mono of the access level that should be granted to the given token. + * @param token the token + * @param applicationId the cloud foundry application ID + * @return a Mono of the access level that should be granted + * @throws CloudFoundryAuthorizationException if the token is not authorized + */ + Mono getAccessLevel(String token, String applicationId) throws CloudFoundryAuthorizationException { + String uri = getPermissionsUri(applicationId); + return this.webClient.get() + .uri(uri) + .header("Authorization", "bearer " + token) + .retrieve() + .bodyToMono(Map.class) + .map(this::getAccessLevel) + .onErrorMap(this::mapError); + } + + private Throwable mapError(Throwable throwable) { + if (throwable instanceof WebClientResponseException webClientResponseException) { + HttpStatusCode statusCode = webClientResponseException.getStatusCode(); + if (statusCode.equals(HttpStatus.FORBIDDEN)) { + return new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"); + } + if (statusCode.is4xxClientError()) { + return new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Invalid token", throwable); + } + } + return new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "Cloud controller not reachable"); + } + + private AccessLevel getAccessLevel(Map body) { + if (Boolean.TRUE.equals(body.get("read_sensitive_data"))) { + return AccessLevel.FULL; + } + return AccessLevel.RESTRICTED; + } + + private String getPermissionsUri(String applicationId) { + return this.cloudControllerUrl + "/v2/apps/" + applicationId + "/permissions"; + } + + /** + * Return a Mono of all token keys known by the UAA. + * @return a Mono of token keys + */ + Mono> fetchTokenKeys() { + return getUaaUrl().flatMap(this::fetchTokenKeys); + } + + private Mono> fetchTokenKeys(String url) { + RequestHeadersSpec uri = this.webClient.get().uri(url + "/token_keys"); + return uri.retrieve() + .bodyToMono(STRING_OBJECT_MAP) + .map(this::extractTokenKeys) + .onErrorMap(((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, ex.getMessage()))); + } + + private Map extractTokenKeys(Map response) { + Map tokenKeys = new HashMap<>(); + for (Object key : (List) response.get("keys")) { + Map tokenKey = (Map) key; + tokenKeys.put((String) tokenKey.get("kid"), (String) tokenKey.get("value")); + } + return tokenKeys; + } + + /** + * Return a Mono of URL of the UAA. + * @return the UAA url Mono + */ + Mono getUaaUrl() { + return this.webClient.get() + .uri(this.cloudControllerUrl + "/info") + .retrieve() + .bodyToMono(Map.class) + .map((response) -> (String) response.get("token_endpoint")) + .cache() + .onErrorMap((ex) -> new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, + "Unable to fetch token keys from UAA.")); + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/TokenValidator.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/TokenValidator.java new file mode 100644 index 000000000000..3d761185822c --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/TokenValidator.java @@ -0,0 +1,144 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.Signature; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import reactor.core.publisher.Mono; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.Token; + +/** + * Validator used to ensure that a signed {@link Token} has not been tampered with. + * + * @author Madhura Bhave + */ +class TokenValidator { + + private final SecurityService securityService; + + private volatile Map cachedTokenKeys = Collections.emptyMap(); + + TokenValidator(SecurityService securityService) { + this.securityService = securityService; + } + + Mono validate(Token token) { + return validateAlgorithm(token).then(validateKeyIdAndSignature(token)) + .then(validateExpiry(token)) + .then(validateIssuer(token)) + .then(validateAudience(token)); + } + + private Mono validateAlgorithm(Token token) { + String algorithm = token.getSignatureAlgorithm(); + if (algorithm == null) { + return Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, + "Signing algorithm cannot be null")); + } + if (!algorithm.equals("RS256")) { + return Mono.error(new CloudFoundryAuthorizationException(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM, + "Signing algorithm " + algorithm + " not supported")); + } + return Mono.empty(); + } + + private Mono validateKeyIdAndSignature(Token token) { + return getTokenKey(token).filter((tokenKey) -> hasValidSignature(token, tokenKey)) + .switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, + "RSA Signature did not match content"))) + .then(); + } + + private Mono getTokenKey(Token token) { + String keyId = token.getKeyId(); + String cached = this.cachedTokenKeys.get(keyId); + if (cached != null) { + return Mono.just(cached); + } + return this.securityService.fetchTokenKeys() + .doOnSuccess(this::cacheTokenKeys) + .filter((tokenKeys) -> tokenKeys.containsKey(keyId)) + .map((tokenKeys) -> tokenKeys.get(keyId)) + .switchIfEmpty(Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_KEY_ID, + "Key Id present in token header does not match"))); + } + + private void cacheTokenKeys(Map tokenKeys) { + this.cachedTokenKeys = Map.copyOf(tokenKeys); + } + + private boolean hasValidSignature(Token token, String key) { + try { + PublicKey publicKey = getPublicKey(key); + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initVerify(publicKey); + signature.update(token.getContent()); + return signature.verify(token.getSignature()); + } + catch (GeneralSecurityException ex) { + return false; + } + } + + private PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException { + key = key.replace("-----BEGIN PUBLIC KEY-----\n", ""); + key = key.replace("-----END PUBLIC KEY-----", ""); + key = key.trim().replace("\n", ""); + byte[] bytes = Base64.getDecoder().decode(key); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes); + return KeyFactory.getInstance("RSA").generatePublic(keySpec); + } + + private Mono validateExpiry(Token token) { + long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()); + if (currentTime > token.getExpiry()) { + return Mono.error(new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED, "Token expired")); + } + return Mono.empty(); + } + + private Mono validateIssuer(Token token) { + return this.securityService.getUaaUrl() + .map((uaaUrl) -> String.format("%s/oauth/token", uaaUrl)) + .filter((issuerUri) -> issuerUri.equals(token.getIssuer())) + .switchIfEmpty(Mono + .error(new CloudFoundryAuthorizationException(Reason.INVALID_ISSUER, "Token issuer does not match"))) + .then(); + } + + private Mono validateAudience(Token token) { + if (!token.getScope().contains("actuator.read")) { + return Mono.error(new CloudFoundryAuthorizationException(Reason.INVALID_AUDIENCE, + "Token does not have audience actuator")); + } + return Mono.empty(); + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/package-info.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/package-info.java new file mode 100644 index 000000000000..6bb756a3eb9a --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Cloud Foundry WebFlux endpoints. + */ +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryActuatorAutoConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryActuatorAutoConfiguration.java index d98cedcce773..9dc535842286 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryActuatorAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import java.util.ArrayList; import java.util.Arrays; @@ -23,11 +23,9 @@ import java.util.List; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebEndpointDiscoverer; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; @@ -49,8 +47,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.cloud.CloudPlatform; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryWebEndpointDiscoverer; import org.springframework.boot.info.GitProperties; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -74,10 +73,10 @@ * Cloud Foundry to use. * * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { ServletManagementContextAutoConfiguration.class, HealthEndpointAutoConfiguration.class, - InfoEndpointAutoConfiguration.class }) +@AutoConfiguration(after = { HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class }, + afterName = "org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration") @ConditionalOnBooleanProperty(name = "management.cloudfoundry.enabled", matchIfMissing = true) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass(DispatcherServlet.class) @@ -120,7 +119,7 @@ public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServl CloudFoundryWebEndpointDiscoverer discoverer = new CloudFoundryWebEndpointDiscoverer(applicationContext, parameterMapper, endpointMediaTypes, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - CloudFoundrySecurityInterceptor securityInterceptor = getSecurityInterceptor(restTemplateBuilder, + SecurityInterceptor securityInterceptor = getSecurityInterceptor(restTemplateBuilder, applicationContext.getEnvironment()); Collection webEndpoints = discoverer.getEndpoints(); List> allEndpoints = new ArrayList<>(); @@ -131,22 +130,21 @@ public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServl endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints); } - private CloudFoundrySecurityInterceptor getSecurityInterceptor(RestTemplateBuilder restTemplateBuilder, + private SecurityInterceptor getSecurityInterceptor(RestTemplateBuilder restTemplateBuilder, Environment environment) { - CloudFoundrySecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService(restTemplateBuilder, - environment); + SecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService(restTemplateBuilder, environment); TokenValidator tokenValidator = new TokenValidator(cloudfoundrySecurityService); - return new CloudFoundrySecurityInterceptor(tokenValidator, cloudfoundrySecurityService, + return new SecurityInterceptor(tokenValidator, cloudfoundrySecurityService, environment.getProperty("vcap.application.application_id")); } - private CloudFoundrySecurityService getCloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder, + private SecurityService getCloudFoundrySecurityService(RestTemplateBuilder restTemplateBuilder, Environment environment) { String cloudControllerUrl = environment.getProperty("vcap.application.cf_api"); boolean skipSslValidation = environment.getProperty("management.cloudfoundry.skip-ssl-validation", Boolean.class, false); return (cloudControllerUrl != null) - ? new CloudFoundrySecurityService(restTemplateBuilder, cloudControllerUrl, skipSslValidation) : null; + ? new SecurityService(restTemplateBuilder, cloudControllerUrl, skipSslValidation) : null; } private CorsConfiguration getCorsConfiguration() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryHealthEndpointWebExtension.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryHealthEndpointWebExtension.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryHealthEndpointWebExtension.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryHealthEndpointWebExtension.java index 3d28bc8fd52c..41bca287a82e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryHealthEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryHealthEndpointWebExtension.java @@ -14,9 +14,8 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.EndpointCloudFoundryExtension; import org.springframework.boot.actuate.endpoint.ApiVersion; import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension; @@ -24,16 +23,17 @@ import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.annotation.Selector.Match; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; -import org.springframework.boot.actuate.health.HealthComponent; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointWebExtension; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.EndpointCloudFoundryExtension; +import org.springframework.boot.health.contributor.ContributedHealth; /** * {@link EndpointExtension @EndpointExtension} for the {@link HealthEndpoint} that always * exposes full health details. * * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ @EndpointCloudFoundryExtension(endpoint = HealthEndpoint.class) public class CloudFoundryHealthEndpointWebExtension { @@ -45,12 +45,12 @@ public CloudFoundryHealthEndpointWebExtension(HealthEndpointWebExtension delegat } @ReadOperation - public WebEndpointResponse health(ApiVersion apiVersion) { + public WebEndpointResponse health(ApiVersion apiVersion) { return this.delegate.health(apiVersion, null, SecurityContext.NONE, true); } @ReadOperation - public WebEndpointResponse health(ApiVersion apiVersion, + public WebEndpointResponse health(ApiVersion apiVersion, @Selector(match = Match.ALL_REMAINING) String... path) { return this.delegate.health(apiVersion, null, SecurityContext.NONE, true, path); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryInfoEndpointWebExtension.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryInfoEndpointWebExtension.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryInfoEndpointWebExtension.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryInfoEndpointWebExtension.java index 7e3e2bc14f72..d5c128936af6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryInfoEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryInfoEndpointWebExtension.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import java.util.Map; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.EndpointCloudFoundryExtension; import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.info.InfoEndpoint; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.EndpointCloudFoundryExtension; /** * {@link EndpointExtension @EndpointExtension} for the {@link InfoEndpoint} that always * exposes full git details. * * @author Madhura Bhave - * @since 2.2.0 + * @since 4.0.0 */ @EndpointCloudFoundryExtension(endpoint = InfoEndpoint.class) public class CloudFoundryInfoEndpointWebExtension { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryWebEndpointServletHandlerMapping.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryWebEndpointServletHandlerMapping.java index f9aeed9a374f..e2725aa16070 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryWebEndpointServletHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import java.util.Collection; import java.util.Collections; @@ -32,9 +32,6 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.annotation.Reflective; import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryWebEndpointServletHandlerMappingRuntimeHints; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; @@ -43,7 +40,10 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; import org.springframework.boot.actuate.endpoint.web.WebOperation; -import org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.SecurityResponse; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryWebEndpointServletHandlerMappingRuntimeHints; +import org.springframework.boot.webmvc.actuate.endpoint.web.AbstractWebMvcEndpointHandlerMapping; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -64,7 +64,7 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin private static final Log logger = LogFactory.getLog(CloudFoundryWebEndpointServletHandlerMapping.class); - private final CloudFoundrySecurityInterceptor securityInterceptor; + private final SecurityInterceptor securityInterceptor; private final EndpointLinksResolver linksResolver; @@ -72,7 +72,7 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin CloudFoundryWebEndpointServletHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, - CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor, + CorsConfiguration corsConfiguration, SecurityInterceptor securityInterceptor, Collection> allEndpoints) { super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, true); this.securityInterceptor = securityInterceptor; @@ -143,11 +143,11 @@ private static class SecureServletWebOperation implements ServletWebOperation { private final ServletWebOperation delegate; - private final CloudFoundrySecurityInterceptor securityInterceptor; + private final SecurityInterceptor securityInterceptor; private final EndpointId endpointId; - SecureServletWebOperation(ServletWebOperation delegate, CloudFoundrySecurityInterceptor securityInterceptor, + SecureServletWebOperation(ServletWebOperation delegate, SecurityInterceptor securityInterceptor, EndpointId endpointId) { this.delegate = delegate; this.securityInterceptor = securityInterceptor; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityInterceptor.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityInterceptor.java new file mode 100644 index 000000000000..3513c0b41641 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityInterceptor.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; + +import java.util.Locale; + +import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.SecurityResponse; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.Token; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.util.StringUtils; +import org.springframework.web.cors.CorsUtils; + +/** + * Security interceptor to validate the cloud foundry token. + * + * @author Madhura Bhave + */ +class SecurityInterceptor { + + private static final Log logger = LogFactory.getLog(SecurityInterceptor.class); + + private final TokenValidator tokenValidator; + + private final SecurityService cloudFoundrySecurityService; + + private final String applicationId; + + private static final SecurityResponse SUCCESS = SecurityResponse.success(); + + SecurityInterceptor(TokenValidator tokenValidator, SecurityService cloudFoundrySecurityService, + String applicationId) { + this.tokenValidator = tokenValidator; + this.cloudFoundrySecurityService = cloudFoundrySecurityService; + this.applicationId = applicationId; + } + + SecurityResponse preHandle(HttpServletRequest request, EndpointId endpointId) { + if (CorsUtils.isPreFlightRequest(request)) { + return SecurityResponse.success(); + } + try { + if (!StringUtils.hasText(this.applicationId)) { + throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, + "Application id is not available"); + } + if (this.cloudFoundrySecurityService == null) { + throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, + "Cloud controller URL is not available"); + } + if (HttpMethod.OPTIONS.matches(request.getMethod())) { + return SUCCESS; + } + check(request, endpointId); + } + catch (Exception ex) { + logger.error(ex); + if (ex instanceof CloudFoundryAuthorizationException cfException) { + return new SecurityResponse(cfException.getStatusCode(), + "{\"security_error\":\"" + cfException.getMessage() + "\"}"); + } + return new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage()); + } + return SecurityResponse.success(); + } + + private void check(HttpServletRequest request, EndpointId endpointId) { + Token token = getToken(request); + this.tokenValidator.validate(token); + AccessLevel accessLevel = this.cloudFoundrySecurityService.getAccessLevel(token.toString(), this.applicationId); + if (!accessLevel.isAccessAllowed((endpointId != null) ? endpointId.toLowerCaseString() : "")) { + throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"); + } + request.setAttribute(AccessLevel.REQUEST_ATTRIBUTE, accessLevel); + } + + private Token getToken(HttpServletRequest request) { + String authorization = request.getHeader("Authorization"); + String bearerPrefix = "bearer "; + if (authorization == null || !authorization.toLowerCase(Locale.ENGLISH).startsWith(bearerPrefix)) { + throw new CloudFoundryAuthorizationException(Reason.MISSING_AUTHORIZATION, + "Authorization header is missing or invalid"); + } + return new Token(authorization.substring(bearerPrefix.length())); + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityService.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityService.java new file mode 100644 index 000000000000..94639e414099 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityService.java @@ -0,0 +1,137 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.util.Assert; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestTemplate; + +/** + * Cloud Foundry security service to handle REST calls to the cloud controller and UAA. + * + * @author Madhura Bhave + */ +class SecurityService { + + private final RestTemplate restTemplate; + + private final String cloudControllerUrl; + + private String uaaUrl; + + SecurityService(RestTemplateBuilder restTemplateBuilder, String cloudControllerUrl, boolean skipSslValidation) { + Assert.notNull(restTemplateBuilder, "'restTemplateBuilder' must not be null"); + Assert.notNull(cloudControllerUrl, "'cloudControllerUrl' must not be null"); + if (skipSslValidation) { + restTemplateBuilder = restTemplateBuilder.requestFactory(SkipSslVerificationHttpRequestFactory.class); + } + this.restTemplate = restTemplateBuilder.build(); + this.cloudControllerUrl = cloudControllerUrl; + } + + /** + * Return the access level that should be granted to the given token. + * @param token the token + * @param applicationId the cloud foundry application ID + * @return the access level that should be granted + * @throws CloudFoundryAuthorizationException if the token is not authorized + */ + AccessLevel getAccessLevel(String token, String applicationId) throws CloudFoundryAuthorizationException { + try { + URI uri = getPermissionsUri(applicationId); + RequestEntity request = RequestEntity.get(uri).header("Authorization", "bearer " + token).build(); + Map body = this.restTemplate.exchange(request, Map.class).getBody(); + if (Boolean.TRUE.equals(body.get("read_sensitive_data"))) { + return AccessLevel.FULL; + } + return AccessLevel.RESTRICTED; + } + catch (HttpClientErrorException ex) { + if (ex.getStatusCode().equals(HttpStatus.FORBIDDEN)) { + throw new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"); + } + throw new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN, "Invalid token", ex); + } + catch (HttpServerErrorException ex) { + throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "Cloud controller not reachable"); + } + } + + private URI getPermissionsUri(String applicationId) { + try { + return new URI(this.cloudControllerUrl + "/v2/apps/" + applicationId + "/permissions"); + } + catch (URISyntaxException ex) { + throw new IllegalStateException(ex); + } + } + + /** + * Return all token keys known by the UAA. + * @return a map of token keys + */ + Map fetchTokenKeys() { + try { + return extractTokenKeys(this.restTemplate.getForObject(getUaaUrl() + "/token_keys", Map.class)); + } + catch (HttpStatusCodeException ex) { + throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, "UAA not reachable"); + } + } + + private Map extractTokenKeys(Map response) { + Map tokenKeys = new HashMap<>(); + for (Object key : (List) response.get("keys")) { + Map tokenKey = (Map) key; + tokenKeys.put((String) tokenKey.get("kid"), (String) tokenKey.get("value")); + } + return tokenKeys; + } + + /** + * Return the URL of the UAA. + * @return the UAA url + */ + String getUaaUrl() { + if (this.uaaUrl == null) { + try { + Map response = this.restTemplate.getForObject(this.cloudControllerUrl + "/info", Map.class); + this.uaaUrl = (String) response.get("token_endpoint"); + } + catch (HttpStatusCodeException ex) { + throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE, + "Unable to fetch token keys from UAA"); + } + } + return this.uaaUrl; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/SkipSslVerificationHttpRequestFactory.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SkipSslVerificationHttpRequestFactory.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/SkipSslVerificationHttpRequestFactory.java rename to spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SkipSslVerificationHttpRequestFactory.java index 93edf84f8b8b..c78fdd20c446 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/SkipSslVerificationHttpRequestFactory.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SkipSslVerificationHttpRequestFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import java.io.IOException; import java.net.HttpURLConnection; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/TokenValidator.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/TokenValidator.java new file mode 100644 index 000000000000..3c11810a0865 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/TokenValidator.java @@ -0,0 +1,134 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; + +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.Signature; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.Token; + +/** + * Validator used to ensure that a signed {@link Token} has not been tampered with. + * + * @author Madhura Bhave + */ +class TokenValidator { + + private final SecurityService securityService; + + private Map tokenKeys; + + TokenValidator(SecurityService cloudFoundrySecurityService) { + this.securityService = cloudFoundrySecurityService; + } + + void validate(Token token) { + validateAlgorithm(token); + validateKeyIdAndSignature(token); + validateExpiry(token); + validateIssuer(token); + validateAudience(token); + } + + private void validateAlgorithm(Token token) { + String algorithm = token.getSignatureAlgorithm(); + if (algorithm == null) { + throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, "Signing algorithm cannot be null"); + } + if (!algorithm.equals("RS256")) { + throw new CloudFoundryAuthorizationException(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM, + "Signing algorithm " + algorithm + " not supported"); + } + } + + private void validateKeyIdAndSignature(Token token) { + String keyId = token.getKeyId(); + if (this.tokenKeys == null || !hasValidKeyId(keyId)) { + this.tokenKeys = this.securityService.fetchTokenKeys(); + if (!hasValidKeyId(keyId)) { + throw new CloudFoundryAuthorizationException(Reason.INVALID_KEY_ID, + "Key Id present in token header does not match"); + } + } + + if (!hasValidSignature(token, this.tokenKeys.get(keyId))) { + throw new CloudFoundryAuthorizationException(Reason.INVALID_SIGNATURE, + "RSA Signature did not match content"); + } + } + + private boolean hasValidKeyId(String tokenKey) { + return this.tokenKeys.containsKey(tokenKey); + } + + private boolean hasValidSignature(Token token, String key) { + try { + PublicKey publicKey = getPublicKey(key); + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initVerify(publicKey); + signature.update(token.getContent()); + return signature.verify(token.getSignature()); + } + catch (GeneralSecurityException ex) { + return false; + } + } + + private PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException { + key = key.replace("-----BEGIN PUBLIC KEY-----\n", ""); + key = key.replace("-----END PUBLIC KEY-----", ""); + key = key.trim().replace("\n", ""); + byte[] bytes = Base64.getDecoder().decode(key); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes); + return KeyFactory.getInstance("RSA").generatePublic(keySpec); + } + + private void validateExpiry(Token token) { + long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()); + if (currentTime > token.getExpiry()) { + throw new CloudFoundryAuthorizationException(Reason.TOKEN_EXPIRED, "Token expired"); + } + } + + private void validateIssuer(Token token) { + String uaaUrl = this.securityService.getUaaUrl(); + String issuerUri = String.format("%s/oauth/token", uaaUrl); + if (!issuerUri.equals(token.getIssuer())) { + throw new CloudFoundryAuthorizationException(Reason.INVALID_ISSUER, + "Token issuer does not match " + uaaUrl + "/oauth/token"); + } + } + + private void validateAudience(Token token) { + if (!token.getScope().contains("actuator.read")) { + throw new CloudFoundryAuthorizationException(Reason.INVALID_AUDIENCE, + "Token does not have audience actuator"); + } + + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/package-info.java b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/package-info.java new file mode 100644 index 000000000000..f9befe27a4d1 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Cloud Foundry Servlet endpoints. + */ +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-cloudfoundry/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..942f8c685142 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Endpoint Exposure Outcome Contributors +org.springframework.boot.actuate.autoconfigure.endpoint.condition.EndpointExposureOutcomeContributor=\ +org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryEndpointExposureOutcomeContributor diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-cloudfoundry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..ffa859e0e797 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive.CloudFoundryReactiveActuatorAutoConfiguration +org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet.CloudFoundryActuatorAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/AccessLevelTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/AccessLevelTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/AccessLevelTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/AccessLevelTests.java index 3ea514eb2711..e99d1bc67040 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/AccessLevelTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/AccessLevelTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryAuthorizationExceptionTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryAuthorizationExceptionTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryAuthorizationExceptionTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryAuthorizationExceptionTests.java index a4da7b28c7cf..060d34050e07 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryAuthorizationExceptionTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryAuthorizationExceptionTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; import org.springframework.http.HttpStatus; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryConditionalOnAvailableEndpointTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryConditionalOnAvailableEndpointTests.java new file mode 100644 index 000000000000..868e26cb1ba6 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryConditionalOnAvailableEndpointTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.convert.ApplicationConversionService; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ConditionalOnAvailableEndpoint @ConditionalOnAvailableEndpoint} when + * running on Cloud Foundry. + * + * @author Brian Clozel + */ +class CloudFoundryConditionalOnAvailableEndpointTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withUserConfiguration(AllEndpointsConfiguration.class) + .withInitializer( + (context) -> context.getEnvironment().setConversionService(new ApplicationConversionService())); + + @Test + void outcomeOnCloudFoundryShouldMatchAll() { + this.contextRunner.withPropertyValues("VCAP_APPLICATION:---") + .run((context) -> assertThat(context).hasBean("info").hasBean("health").hasBean("spring").hasBean("test")); + } + + @Endpoint(id = "health") + static class HealthEndpoint { + + } + + @Endpoint(id = "info") + static class InfoEndpoint { + + } + + @Endpoint(id = "spring") + static class SpringEndpoint { + + } + + @Endpoint(id = "test") + static class TestEndpoint { + + } + + @Endpoint(id = "shutdown", defaultAccess = Access.NONE) + static class ShutdownEndpoint { + + } + + @Configuration(proxyBeanMethods = false) + static class AllEndpointsConfiguration { + + @Bean + @ConditionalOnAvailableEndpoint + HealthEndpoint health() { + return new HealthEndpoint(); + } + + @Bean + @ConditionalOnAvailableEndpoint + InfoEndpoint info() { + return new InfoEndpoint(); + } + + @Bean + @ConditionalOnAvailableEndpoint + SpringEndpoint spring() { + return new SpringEndpoint(); + } + + @Bean + @ConditionalOnAvailableEndpoint + TestEndpoint test() { + return new TestEndpoint(); + } + + @Bean + @ConditionalOnAvailableEndpoint + ShutdownEndpoint shutdown() { + return new ShutdownEndpoint(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointFilterTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointFilterTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointFilterTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointFilterTests.java index e9c2121e398d..efa9155a0a5b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryEndpointFilterTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryEndpointFilterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryWebEndpointDiscovererTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryWebEndpointDiscovererTests.java index dfdec4c3490f..29d3cebb56c7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/CloudFoundryWebEndpointDiscovererTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import java.util.Collection; import java.util.Collections; @@ -26,7 +26,6 @@ import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebEndpointDiscoverer.CloudFoundryWebEndpointDiscovererRuntimeHints; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.InvocationContext; import org.springframework.boot.actuate.endpoint.SecurityContext; @@ -39,9 +38,10 @@ import org.springframework.boot.actuate.endpoint.web.PathMapper; import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; -import org.springframework.boot.actuate.health.HealthContributorRegistry; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryWebEndpointDiscoverer.CloudFoundryWebEndpointDiscovererRuntimeHints; +import org.springframework.boot.health.registry.HealthContributorRegistry; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/TokenTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/TokenTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/TokenTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/TokenTests.java index b68803a27c25..e1221f889621 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/TokenTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/TokenTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint; import java.util.Base64; import java.util.function.Consumer; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveActuatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveActuatorAutoConfigurationTests.java new file mode 100644 index 000000000000..e696bb47ecf4 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveActuatorAutoConfigurationTests.java @@ -0,0 +1,397 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.io.IOException; +import java.time.Duration; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.SSLException; + +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import reactor.netty.http.HttpResources; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.ApiVersion; +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; +import org.springframework.boot.actuate.endpoint.web.WebOperation; +import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet.CloudFoundryInfoEndpointWebExtension; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.ssl.jks.JksSslStoreBundle; +import org.springframework.boot.ssl.jks.JksSslStoreDetails; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.webclient.WebClientCustomizer; +import org.springframework.boot.webclient.autoconfigure.WebClientAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.security.web.server.WebFilterChainProxy; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link CloudFoundryReactiveActuatorAutoConfiguration}. + * + * @author Madhura Bhave + * @author Moritz Halbritter + */ +class CloudFoundryReactiveActuatorAutoConfigurationTests { + + private static final String V2_JSON = ApiVersion.V2.getProducedMimeType().toString(); + + private static final String V3_JSON = ApiVersion.V3.getProducedMimeType().toString(); + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class, + WebFluxAutoConfiguration.class, JacksonAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, + WebClientCustomizerConfig.class, WebClientAutoConfiguration.class, + ManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class, + WebEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + InfoContributorAutoConfiguration.class, InfoEndpointAutoConfiguration.class, + ProjectInfoAutoConfiguration.class, CloudFoundryReactiveActuatorAutoConfiguration.class)) + .withUserConfiguration(UserDetailsServiceConfiguration.class); + + private static final String BASE_PATH = "/cloudfoundryapplication"; + + @AfterEach + void close() { + HttpResources.reset(); + } + + @Test + void cloudFoundryPlatformActive() { + this.contextRunner + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> { + CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context); + assertThat(handlerMapping).extracting("endpointMapping.path").isEqualTo("/cloudfoundryapplication"); + assertThat(handlerMapping) + .extracting("corsConfiguration", InstanceOfAssertFactories.type(CorsConfiguration.class)) + .satisfies((corsConfiguration) -> { + assertThat(corsConfiguration.getAllowedOrigins()).contains("*"); + assertThat(corsConfiguration.getAllowedMethods()) + .containsAll(Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name())); + assertThat(corsConfiguration.getAllowedHeaders()) + .containsAll(Arrays.asList("Authorization", "X-Cf-App-Instance", "Content-Type")); + }); + }); + } + + @Test + void cloudfoundryapplicationProducesActuatorMediaType() { + this.contextRunner + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> { + WebTestClient webTestClient = WebTestClient.bindToApplicationContext(context).build(); + webTestClient.get().uri("/cloudfoundryapplication").header("Content-Type", V2_JSON + ";charset=UTF-8"); + }); + } + + @Test + void cloudFoundryPlatformActiveSetsApplicationId() { + this.contextRunner + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> assertThat(getHandlerMapping(context)).extracting("securityInterceptor.applicationId") + .isEqualTo("my-app-id")); + } + + @Test + void cloudFoundryPlatformActiveSetsCloudControllerUrl() { + this.contextRunner + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> assertThat(getHandlerMapping(context)) + .extracting("securityInterceptor.cloudFoundrySecurityService.cloudControllerUrl") + .isEqualTo("https://my-cloud-controller.com")); + } + + @Test + void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() { + this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id") + .run((context) -> assertThat(context.getBean("cloudFoundryWebFluxEndpointHandlerMapping", + CloudFoundryWebFluxEndpointHandlerMapping.class)) + .extracting("securityInterceptor.cloudFoundrySecurityService") + .isNull()); + } + + @Test + @SuppressWarnings("unchecked") + void cloudFoundryPathsIgnoredBySpringSecurity() { + this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new) + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> { + assertThat(context.getBean(WebFilterChainProxy.class)) + .extracting("filters", InstanceOfAssertFactories.list(SecurityWebFilterChain.class)) + .satisfies((filters) -> { + Boolean cfBaseRequestMatches = getMatches(filters, BASE_PATH); + Boolean cfBaseWithTrailingSlashRequestMatches = getMatches(filters, BASE_PATH + "/"); + Boolean cfRequestMatches = getMatches(filters, BASE_PATH + "/test"); + Boolean cfRequestWithAdditionalPathMatches = getMatches(filters, BASE_PATH + "/test/a"); + Boolean otherCfRequestMatches = getMatches(filters, BASE_PATH + "/other-path"); + Boolean otherRequestMatches = getMatches(filters, "/some-other-path"); + assertThat(cfBaseRequestMatches).isTrue(); + assertThat(cfBaseWithTrailingSlashRequestMatches).isTrue(); + assertThat(cfRequestMatches).isTrue(); + assertThat(cfRequestWithAdditionalPathMatches).isTrue(); + assertThat(otherCfRequestMatches).isFalse(); + assertThat(otherRequestMatches).isFalse(); + otherRequestMatches = filters.get(1) + .matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build())) + .block(Duration.ofSeconds(30)); + assertThat(otherRequestMatches).isTrue(); + }); + }); + } + + private static Boolean getMatches(List filters, String urlTemplate) { + return filters.get(0) + .matches(MockServerWebExchange.from(MockServerHttpRequest.get(urlTemplate).build())) + .block(Duration.ofSeconds(30)); + } + + @Test + void cloudFoundryPlatformInactive() { + this.contextRunner + .run((context) -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping")).isFalse()); + } + + @Test + void cloudFoundryManagementEndpointsDisabled() { + this.contextRunner.withPropertyValues("VCAP_APPLICATION=---", "management.cloudfoundry.enabled:false") + .run((context) -> assertThat(context.containsBean("cloudFoundryWebFluxEndpointHandlerMapping")).isFalse()); + } + + @Test + void allEndpointsAvailableUnderCloudFoundryWithoutEnablingWebIncludes() { + this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new) + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> { + CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context); + Collection endpoints = handlerMapping.getEndpoints(); + List endpointIds = endpoints.stream().map(ExposableWebEndpoint::getEndpointId).toList(); + assertThat(endpointIds).contains(EndpointId.of("test")); + }); + } + + @Test + void endpointPathCustomizationIsNotApplied() { + this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new) + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> { + CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context); + Collection endpoints = handlerMapping.getEndpoints(); + ExposableWebEndpoint endpoint = endpoints.stream() + .filter((candidate) -> EndpointId.of("test").equals(candidate.getEndpointId())) + .findFirst() + .get(); + assertThat(endpoint.getOperations()).hasSize(1); + WebOperation operation = endpoint.getOperations().iterator().next(); + assertThat(operation.getRequestPredicate().getPath()).isEqualTo("test"); + }); + } + + @Test + void healthEndpointInvokerShouldBeCloudFoundryWebExtension() { + this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class)) + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> { + Collection endpoints = getHandlerMapping(context).getEndpoints(); + ExposableWebEndpoint endpoint = endpoints.iterator().next(); + assertThat(endpoint.getOperations()).hasSize(2); + WebOperation webOperation = findOperationWithRequestPath(endpoint, "health"); + assertThat(webOperation).extracting("invoker") + .extracting("target") + .isInstanceOf(CloudFoundryReactiveHealthEndpointWebExtension.class); + }); + } + + @Test + @WithResource(name = "git.properties", content = """ + #Generated by Git-Commit-Id-Plugin + #Thu May 23 09:26:42 BST 2013 + git.commit.id.abbrev=e02a4f3 + git.commit.user.email=dsyer@vmware.com + git.commit.message.full=Update Spring + git.commit.id=e02a4f3b6f452cdbf6dd311f1362679eb4c31ced + git.commit.message.short=Update Spring + git.commit.user.name=Dave Syer + git.build.user.name=Dave Syer + git.build.user.email=dsyer@vmware.com + git.branch=develop + git.commit.time=2013-04-24T08\\:42\\:13+0100 + git.build.time=2013-05-23T09\\:26\\:42+0100 + """) + @SuppressWarnings("unchecked") + void gitFullDetailsAlwaysPresent() { + this.contextRunner.withPropertyValues("VCAP_APPLICATION:---").run((context) -> { + CloudFoundryInfoEndpointWebExtension extension = context + .getBean(CloudFoundryInfoEndpointWebExtension.class); + Map git = (Map) extension.info().get("git"); + Map commit = (Map) git.get("commit"); + assertThat(commit).hasSize(4); + }); + } + + @Test + @WithPackageResources("test.jks") + void skipSslValidation() throws IOException { + JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails("JKS", null, "classpath:test.jks", "secret"); + SslBundle sslBundle = SslBundle.of(new JksSslStoreBundle(keyStoreDetails, keyStoreDetails)); + try (MockWebServer server = new MockWebServer()) { + server.useHttps(sslBundle.createSslContext().getSocketFactory(), false); + server.enqueue(new MockResponse().setResponseCode(204)); + server.start(); + this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class)) + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com", + "management.cloudfoundry.skip-ssl-validation:true") + .run((context) -> assertThat(getHandlerMapping(context)) + .extracting("securityInterceptor.cloudFoundrySecurityService.webClient", + InstanceOfAssertFactories.type(WebClient.class)) + .satisfies((webClient) -> { + ResponseEntity response = webClient.get() + .uri(server.url("/").uri()) + .retrieve() + .toBodilessEntity() + .block(Duration.ofSeconds(30)); + assertThat(response.getStatusCode()).isEqualTo(HttpStatusCode.valueOf(204)); + })); + } + } + + @Test + @WithPackageResources("test.jks") + void sslValidationNotSkippedByDefault() throws IOException { + JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails("JKS", null, "classpath:test.jks", "secret"); + SslBundle sslBundle = SslBundle.of(new JksSslStoreBundle(keyStoreDetails, keyStoreDetails)); + try (MockWebServer server = new MockWebServer()) { + server.useHttps(sslBundle.createSslContext().getSocketFactory(), false); + server.enqueue(new MockResponse().setResponseCode(204)); + server.start(); + this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class)) + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", + "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> assertThat(getHandlerMapping(context)) + .extracting("securityInterceptor.cloudFoundrySecurityService.webClient", + InstanceOfAssertFactories.type(WebClient.class)) + .satisfies((webClient) -> assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> webClient.get() + .uri(server.url("/").uri()) + .retrieve() + .toBodilessEntity() + .block(Duration.ofSeconds(30))) + .withCauseInstanceOf(SSLException.class))); + } + } + + private CloudFoundryWebFluxEndpointHandlerMapping getHandlerMapping(ApplicationContext context) { + return context.getBean("cloudFoundryWebFluxEndpointHandlerMapping", + CloudFoundryWebFluxEndpointHandlerMapping.class); + } + + private WebOperation findOperationWithRequestPath(ExposableWebEndpoint endpoint, String requestPath) { + for (WebOperation operation : endpoint.getOperations()) { + WebOperationRequestPredicate predicate = operation.getRequestPredicate(); + if (predicate.getPath().equals(requestPath) && predicate.getProduces().contains(V3_JSON)) { + return operation; + } + } + throw new IllegalStateException( + "No operation found with request path " + requestPath + " from " + endpoint.getOperations()); + } + + @Endpoint(id = "test") + static class TestEndpoint { + + @ReadOperation + String hello() { + return "hello world"; + } + + } + + @Configuration(proxyBeanMethods = false) + static class WebClientCustomizerConfig { + + @Bean + WebClientCustomizer webClientCustomizer() { + return mock(WebClientCustomizer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class UserDetailsServiceConfiguration { + + @Bean + MapReactiveUserDetailsService userDetailsService() { + return new MapReactiveUserDetailsService( + User.withUsername("alice").password("secret").roles("admin").build()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveHealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveHealthEndpointWebExtensionTests.java new file mode 100644 index 000000000000..3e49a6d46a44 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryReactiveHealthEndpointWebExtensionTests.java @@ -0,0 +1,99 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.time.Duration; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.ApiVersion; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.webclient.autoconfigure.WebClientAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CloudFoundryReactiveHealthEndpointWebExtension}. + * + * @author Madhura Bhave + */ +class CloudFoundryReactiveHealthEndpointWebExtensionTests { + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withPropertyValues("VCAP_APPLICATION={}") + .withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class, + WebFluxAutoConfiguration.class, JacksonAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, + CloudFoundryReactiveActuatorAutoConfigurationTests.WebClientCustomizerConfig.class, + WebClientAutoConfiguration.class, ManagementContextAutoConfiguration.class, + EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, + HealthContributorAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, CloudFoundryReactiveActuatorAutoConfiguration.class)) + .withUserConfiguration(TestHealthIndicator.class, UserDetailsServiceConfiguration.class); + + @Test + void healthComponentsAlwaysPresent() { + this.contextRunner.run((context) -> { + CloudFoundryReactiveHealthEndpointWebExtension extension = context + .getBean(CloudFoundryReactiveHealthEndpointWebExtension.class); + ContributedHealth body = extension.health(ApiVersion.V3).block(Duration.ofSeconds(30)).getBody(); + ContributedHealth health = ((CompositeHealth) body).getComponents().entrySet().iterator().next().getValue(); + assertThat(((Health) health).getDetails()).containsEntry("spring", "boot"); + }); + } + + private static final class TestHealthIndicator implements HealthIndicator { + + @Override + public Health health() { + return Health.up().withDetail("spring", "boot").build(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class UserDetailsServiceConfiguration { + + @Bean + MapReactiveUserDetailsService userDetailsService() { + return new MapReactiveUserDetailsService( + User.withUsername("alice").password("secret").roles("admin").build()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java similarity index 78% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java index 87dab527167b..d0c6b89deefd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryLinksHandler; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints; import org.springframework.boot.actuate.endpoint.web.Link; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryLinksHandler; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java index 2f2aaa9bed6c..8fc150c0264c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; import java.time.Duration; import java.util.ArrayList; @@ -29,9 +29,6 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; @@ -44,13 +41,16 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -75,17 +75,17 @@ */ class CloudFoundryWebFluxEndpointIntegrationTests { - private final ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class); + private final TokenValidator tokenValidator = mock(TokenValidator.class); - private final ReactiveCloudFoundrySecurityService securityService = mock(ReactiveCloudFoundrySecurityService.class); + private final SecurityService securityService = mock(SecurityService.class); private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner( AnnotationConfigReactiveWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class, - ReactiveWebServerFactoryAutoConfiguration.class)) + NettyReactiveWebServerAutoConfiguration.class)) .withUserConfiguration(TestEndpointConfiguration.class) - .withBean(ReactiveTokenValidator.class, () -> this.tokenValidator) - .withBean(ReactiveCloudFoundrySecurityService.class, () -> this.securityService) + .withBean(TokenValidator.class, () -> this.tokenValidator) + .withBean(SecurityService.class, () -> this.securityService) .withPropertyValues("server.port=0"); @Test @@ -233,9 +233,8 @@ private String mockAccessToken() { static class CloudFoundryReactiveConfiguration { @Bean - CloudFoundrySecurityInterceptor interceptor(ReactiveTokenValidator tokenValidator, - ReactiveCloudFoundrySecurityService securityService) { - return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id"); + SecurityInterceptor interceptor(TokenValidator tokenValidator, SecurityService securityService) { + return new SecurityInterceptor(tokenValidator, securityService, "app-id"); } @Bean @@ -247,7 +246,7 @@ EndpointMediaTypes EndpointMediaTypes() { @Bean CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebEndpointServletHandlerMapping( WebEndpointDiscoverer webEndpointDiscoverer, EndpointMediaTypes endpointMediaTypes, - CloudFoundrySecurityInterceptor interceptor) { + SecurityInterceptor interceptor) { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com")); corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST")); diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityInterceptorTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityInterceptorTests.java new file mode 100644 index 000000000000..4945bc3c06ec --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityInterceptorTests.java @@ -0,0 +1,169 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.time.Duration; +import java.util.Base64; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; + +/** + * Tests for {@link SecurityInterceptor}. + * + * @author Madhura Bhave + */ +@ExtendWith(MockitoExtension.class) +class SecurityInterceptorTests { + + @Mock + private TokenValidator tokenValidator; + + @Mock + private SecurityService securityService; + + private SecurityInterceptor interceptor; + + @BeforeEach + void setup() { + this.interceptor = new SecurityInterceptor(this.tokenValidator, this.securityService, "my-app-id"); + } + + @Test + void preHandleWhenRequestIsPreFlightShouldBeOk() { + MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.options("/a") + .header(HttpHeaders.ORIGIN, "https://example.com") + .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET") + .build()); + StepVerifier.create(this.interceptor.preHandle(request, "/a")) + .consumeNextWith((response) -> assertThat(response.getStatus()).isEqualTo(HttpStatus.OK)) + .expectComplete() + .verify(Duration.ofSeconds(30)); + } + + @Test + void preHandleWhenTokenIsMissingShouldReturnMissingAuthorization() { + MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a").build()); + StepVerifier.create(this.interceptor.preHandle(request, "/a")) + .consumeNextWith( + (response) -> assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus())) + .expectComplete() + .verify(Duration.ofSeconds(30)); + } + + @Test + void preHandleWhenTokenIsNotBearerShouldReturnMissingAuthorization() { + MockServerWebExchange request = MockServerWebExchange + .from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build()); + StepVerifier.create(this.interceptor.preHandle(request, "/a")) + .consumeNextWith( + (response) -> assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus())) + .expectComplete() + .verify(Duration.ofSeconds(30)); + } + + @Test + void preHandleWhenApplicationIdIsNullShouldReturnError() { + this.interceptor = new SecurityInterceptor(this.tokenValidator, this.securityService, null); + MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a") + .header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()) + .build()); + StepVerifier.create(this.interceptor.preHandle(request, "/a")) + .consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason()) + .isEqualTo(Reason.SERVICE_UNAVAILABLE)) + .verify(); + } + + @Test + void preHandleWhenCloudFoundrySecurityServiceIsNullShouldReturnError() { + this.interceptor = new SecurityInterceptor(this.tokenValidator, null, "my-app-id"); + MockServerWebExchange request = MockServerWebExchange + .from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build()); + StepVerifier.create(this.interceptor.preHandle(request, "/a")) + .consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason()) + .isEqualTo(Reason.SERVICE_UNAVAILABLE)) + .verify(); + } + + @Test + void preHandleWhenAccessIsNotAllowedShouldReturnAccessDenied() { + given(this.securityService.getAccessLevel(mockAccessToken(), "my-app-id")) + .willReturn(Mono.just(AccessLevel.RESTRICTED)); + given(this.tokenValidator.validate(any())).willReturn(Mono.empty()); + MockServerWebExchange request = MockServerWebExchange.from(MockServerHttpRequest.get("/a") + .header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()) + .build()); + StepVerifier.create(this.interceptor.preHandle(request, "/a")) + .consumeNextWith((response) -> assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus())) + .expectComplete() + .verify(Duration.ofSeconds(30)); + } + + @Test + void preHandleSuccessfulWithFullAccess() { + String accessToken = mockAccessToken(); + given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(Mono.just(AccessLevel.FULL)); + given(this.tokenValidator.validate(any())).willReturn(Mono.empty()); + MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/a") + .header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()) + .build()); + StepVerifier.create(this.interceptor.preHandle(exchange, "/a")).consumeNextWith((response) -> { + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); + assertThat((AccessLevel) exchange.getAttribute("cloudFoundryAccessLevel")).isEqualTo(AccessLevel.FULL); + }).expectComplete().verify(Duration.ofSeconds(30)); + } + + @Test + void preHandleSuccessfulWithRestrictedAccess() { + String accessToken = mockAccessToken(); + given(this.securityService.getAccessLevel(accessToken, "my-app-id")) + .willReturn(Mono.just(AccessLevel.RESTRICTED)); + given(this.tokenValidator.validate(any())).willReturn(Mono.empty()); + MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/info") + .header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken()) + .build()); + StepVerifier.create(this.interceptor.preHandle(exchange, "info")).consumeNextWith((response) -> { + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); + assertThat((AccessLevel) exchange.getAttribute("cloudFoundryAccessLevel")) + .isEqualTo(AccessLevel.RESTRICTED); + }).expectComplete().verify(Duration.ofSeconds(30)); + } + + private String mockAccessToken() { + return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu" + + "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ." + + Base64.getEncoder().encodeToString("signature".getBytes()); + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityServiceTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityServiceTests.java new file mode 100644 index 000000000000..0a340e302290 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/SecurityServiceTests.java @@ -0,0 +1,245 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.util.function.Consumer; + +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.http.HttpHeaders; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SecurityService}. + * + * @author Madhura Bhave + */ +class SecurityServiceTests { + + private static final String CLOUD_CONTROLLER = "/my-cloud-controller.com"; + + private static final String CLOUD_CONTROLLER_PERMISSIONS = CLOUD_CONTROLLER + "/v2/apps/my-app-id/permissions"; + + private static final String UAA_URL = "https://my-cloud-controller.com/uaa"; + + private SecurityService securityService; + + private MockWebServer server; + + @BeforeEach + void setup() { + this.server = new MockWebServer(); + WebClient.Builder builder = WebClient.builder().baseUrl(this.server.url("/").toString()); + this.securityService = new SecurityService(builder, CLOUD_CONTROLLER, false); + } + + @AfterEach + void shutdown() throws Exception { + this.server.shutdown(); + } + + @Test + void getAccessLevelWhenSpaceDeveloperShouldReturnFull() throws Exception { + String responseBody = "{\"read_sensitive_data\": true,\"read_basic_data\": true}"; + prepareResponse((response) -> response.setBody(responseBody).setHeader("Content-Type", "application/json")); + StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) + .consumeNextWith((accessLevel) -> assertThat(accessLevel).isEqualTo(AccessLevel.FULL)) + .expectComplete() + .verify(); + expectRequest((request) -> { + assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); + assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); + }); + } + + @Test + void getAccessLevelWhenNotSpaceDeveloperShouldReturnRestricted() throws Exception { + String responseBody = "{\"read_sensitive_data\": false,\"read_basic_data\": true}"; + prepareResponse((response) -> response.setBody(responseBody).setHeader("Content-Type", "application/json")); + StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) + .consumeNextWith((accessLevel) -> assertThat(accessLevel).isEqualTo(AccessLevel.RESTRICTED)) + .expectComplete() + .verify(); + expectRequest((request) -> { + assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); + assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); + }); + } + + @Test + void getAccessLevelWhenTokenIsNotValidShouldThrowException() throws Exception { + prepareResponse((response) -> response.setResponseCode(401)); + StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) + .consumeErrorWith((throwable) -> { + assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) + .isEqualTo(Reason.INVALID_TOKEN); + }) + .verify(); + expectRequest((request) -> { + assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); + assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); + }); + } + + @Test + void getAccessLevelWhenForbiddenShouldThrowException() throws Exception { + prepareResponse((response) -> response.setResponseCode(403)); + StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) + .consumeErrorWith((throwable) -> { + assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) + .isEqualTo(Reason.ACCESS_DENIED); + }) + .verify(); + expectRequest((request) -> { + assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); + assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); + }); + } + + @Test + void getAccessLevelWhenCloudControllerIsNotReachableThrowsException() throws Exception { + prepareResponse((response) -> response.setResponseCode(500)); + StepVerifier.create(this.securityService.getAccessLevel("my-access-token", "my-app-id")) + .consumeErrorWith((throwable) -> { + assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) + .isEqualTo(Reason.SERVICE_UNAVAILABLE); + }) + .verify(); + expectRequest((request) -> { + assertThat(request.getHeader(HttpHeaders.AUTHORIZATION)).isEqualTo("bearer my-access-token"); + assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER_PERMISSIONS); + }); + } + + @Test + void fetchTokenKeysWhenSuccessfulShouldReturnListOfKeysFromUAA() throws Exception { + String tokenKeyValue = """ + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO + rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7 + fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB + LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO + kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo + jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI + JwIDAQAB + -----END PUBLIC KEY-----"""; + prepareResponse((response) -> { + response.setBody("{\"token_endpoint\":\"/my-uaa.com\"}"); + response.setHeader("Content-Type", "application/json"); + }); + String responseBody = "{\"keys\" : [ {\"kid\":\"test-key\",\"value\" : \"" + tokenKeyValue.replace("\n", "\\n") + + "\"} ]}"; + prepareResponse((response) -> { + response.setBody(responseBody); + response.setHeader("Content-Type", "application/json"); + }); + StepVerifier.create(this.securityService.fetchTokenKeys()) + .consumeNextWith((tokenKeys) -> assertThat(tokenKeys.get("test-key")).isEqualTo(tokenKeyValue)) + .expectComplete() + .verify(); + expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info")); + expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys")); + } + + @Test + void fetchTokenKeysWhenNoKeysReturnedFromUAA() throws Exception { + prepareResponse((response) -> { + response.setBody("{\"token_endpoint\":\"/my-uaa.com\"}"); + response.setHeader("Content-Type", "application/json"); + }); + String responseBody = "{\"keys\": []}"; + prepareResponse((response) -> { + response.setBody(responseBody); + response.setHeader("Content-Type", "application/json"); + }); + StepVerifier.create(this.securityService.fetchTokenKeys()) + .consumeNextWith((tokenKeys) -> assertThat(tokenKeys).isEmpty()) + .expectComplete() + .verify(); + expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info")); + expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys")); + } + + @Test + void fetchTokenKeysWhenUnsuccessfulShouldThrowException() throws Exception { + prepareResponse((response) -> { + response.setBody("{\"token_endpoint\":\"/my-uaa.com\"}"); + response.setHeader("Content-Type", "application/json"); + }); + prepareResponse((response) -> response.setResponseCode(500)); + StepVerifier.create(this.securityService.fetchTokenKeys()) + .consumeErrorWith((throwable) -> assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) + .isEqualTo(Reason.SERVICE_UNAVAILABLE)) + .verify(); + expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-cloud-controller.com/info")); + expectRequest((request) -> assertThat(request.getPath()).isEqualTo("/my-uaa.com/token_keys")); + } + + @Test + void getUaaUrlShouldCallCloudControllerInfoOnlyOnce() throws Exception { + prepareResponse((response) -> { + response.setBody("{\"token_endpoint\":\"" + UAA_URL + "\"}"); + response.setHeader("Content-Type", "application/json"); + }); + StepVerifier.create(this.securityService.getUaaUrl()) + .consumeNextWith((uaaUrl) -> assertThat(uaaUrl).isEqualTo(UAA_URL)) + .expectComplete() + .verify(); + expectRequest((request) -> assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER + "/info")); + expectRequestCount(1); + } + + @Test + void getUaaUrlWhenCloudControllerUrlIsNotReachableShouldThrowException() throws Exception { + prepareResponse((response) -> response.setResponseCode(500)); + StepVerifier.create(this.securityService.getUaaUrl()).consumeErrorWith((throwable) -> { + assertThat(throwable).isInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) throwable).getReason()) + .isEqualTo(Reason.SERVICE_UNAVAILABLE); + }).verify(); + expectRequest((request) -> assertThat(request.getPath()).isEqualTo(CLOUD_CONTROLLER + "/info")); + } + + private void prepareResponse(Consumer consumer) { + MockResponse response = new MockResponse(); + consumer.accept(response); + this.server.enqueue(response); + } + + private void expectRequest(Consumer consumer) throws InterruptedException { + consumer.accept(this.server.takeRequest()); + } + + private void expectRequestCount(int count) { + assertThat(count).isEqualTo(this.server.getRequestCount()); + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/TokenValidatorTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/TokenValidatorTests.java new file mode 100644 index 000000000000..3f744681500d --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/TokenValidatorTests.java @@ -0,0 +1,321 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.reactive; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.Signature; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.time.Duration; +import java.util.Base64; +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; +import reactor.test.publisher.PublisherProbe; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.Token; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.util.StreamUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +/** + * Tests for {@link TokenValidator}. + * + * @author Madhura Bhave + */ +@ExtendWith(MockitoExtension.class) +class TokenValidatorTests { + + private static final byte[] DOT = ".".getBytes(); + + @Mock + private SecurityService securityService; + + private TokenValidator tokenValidator; + + private static final String VALID_KEY = """ + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO + rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7 + fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB + LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO + kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo + jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI + JwIDAQAB + -----END PUBLIC KEY-----"""; + + private static final String INVALID_KEY = """ + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzYuc22QSst/dS7geYYK + 5l5kLxU0tayNdixkEQ17ix+CUcUbKIsnyftZxaCYT46rQtXgCaYRdJcbB3hmyrOa + vkhTpX79xJZnQmfuamMbZBqitvscxW9zRR9tBUL6vdi/0rpoUwPMEh8+Bw7CgYR0 + FK0DhWYBNDfe9HKcyZEv3max8Cdq18htxjEsdYO0iwzhtKRXomBWTdhD5ykd/fAC + VTr4+KEY+IeLvubHVmLUhbE5NgWXxrRpGasDqzKhCTmsa2Ysf712rl57SlH0Wz/M + r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s + YwIDAQAB + -----END PUBLIC KEY-----"""; + + private static final Map INVALID_KEYS = new ConcurrentHashMap<>(); + + private static final Map VALID_KEYS = new ConcurrentHashMap<>(); + + @BeforeEach + void setup() { + VALID_KEYS.put("valid-key", VALID_KEY); + INVALID_KEYS.put("invalid-key", INVALID_KEY); + this.tokenValidator = new TokenValidator(this.securityService); + } + + @Test + void validateTokenWhenKidValidationFailsTwiceShouldThrowException() throws Exception { + PublisherProbe> fetchTokenKeys = PublisherProbe.of(Mono.just(VALID_KEYS)); + ReflectionTestUtils.setField(this.tokenValidator, "cachedTokenKeys", VALID_KEYS); + given(this.securityService.fetchTokenKeys()).willReturn(fetchTokenKeys.mono()); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{\"alg\": \"RS256\", \"kid\": \"invalid-key\",\"typ\": \"JWT\"}"; + String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .consumeErrorWith((ex) -> { + assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_KEY_ID); + }) + .verify(); + assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS); + fetchTokenKeys.assertWasSubscribed(); + } + + @Test + void validateTokenWhenKidValidationSucceedsInTheSecondAttempt() throws Exception { + PublisherProbe> fetchTokenKeys = PublisherProbe.of(Mono.just(VALID_KEYS)); + ReflectionTestUtils.setField(this.tokenValidator, "cachedTokenKeys", INVALID_KEYS); + given(this.securityService.fetchTokenKeys()).willReturn(fetchTokenKeys.mono()); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .expectComplete() + .verify(Duration.ofSeconds(30)); + assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS); + fetchTokenKeys.assertWasSubscribed(); + } + + @Test + void validateTokenWhenCacheIsEmptyShouldFetchTokenKeys() throws Exception { + PublisherProbe> fetchTokenKeys = PublisherProbe.of(Mono.just(VALID_KEYS)); + given(this.securityService.fetchTokenKeys()).willReturn(fetchTokenKeys.mono()); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .expectComplete() + .verify(Duration.ofSeconds(30)); + assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS); + fetchTokenKeys.assertWasSubscribed(); + } + + @Test + void validateTokenWhenCacheEmptyAndInvalidKeyShouldThrowException() throws Exception { + PublisherProbe> fetchTokenKeys = PublisherProbe.of(Mono.just(VALID_KEYS)); + given(this.securityService.fetchTokenKeys()).willReturn(fetchTokenKeys.mono()); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{\"alg\": \"RS256\", \"kid\": \"invalid-key\",\"typ\": \"JWT\"}"; + String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .consumeErrorWith((ex) -> { + assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_KEY_ID); + }) + .verify(); + assertThat(this.tokenValidator).hasFieldOrPropertyWithValue("cachedTokenKeys", VALID_KEYS); + fetchTokenKeys.assertWasSubscribed(); + } + + @Test + void validateTokenWhenCacheValidShouldNotFetchTokenKeys() throws Exception { + PublisherProbe> fetchTokenKeys = PublisherProbe.empty(); + ReflectionTestUtils.setField(this.tokenValidator, "cachedTokenKeys", VALID_KEYS); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .expectComplete() + .verify(Duration.ofSeconds(30)); + fetchTokenKeys.assertWasNotSubscribed(); + } + + @Test + void validateTokenWhenSignatureInvalidShouldThrowException() throws Exception { + Map KEYS = Collections.singletonMap("valid-key", INVALID_KEY); + given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(KEYS)); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .consumeErrorWith((ex) -> { + assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_SIGNATURE); + }) + .verify(); + } + + @Test + void validateTokenWhenTokenAlgorithmIsNotRS256ShouldThrowException() throws Exception { + given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(VALID_KEYS)); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{ \"alg\": \"HS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .consumeErrorWith((ex) -> { + assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) ex).getReason()) + .isEqualTo(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM); + }) + .verify(); + } + + @Test + void validateTokenWhenExpiredShouldThrowException() throws Exception { + given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(VALID_KEYS)); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; + String claims = "{ \"jti\": \"0236399c350c47f3ae77e67a75e75e7d\", \"exp\": 1477509977, \"scope\": [\"actuator.read\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .consumeErrorWith((ex) -> { + assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.TOKEN_EXPIRED); + }) + .verify(); + } + + @Test + void validateTokenWhenIssuerIsNotValidShouldThrowException() throws Exception { + given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(VALID_KEYS)); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("https://other-uaa.com")); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\", \"scope\": [\"actuator.read\"]}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .consumeErrorWith((ex) -> { + assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_ISSUER); + }) + .verify(); + } + + @Test + void validateTokenWhenAudienceIsNotValidShouldThrowException() throws Exception { + given(this.securityService.fetchTokenKeys()).willReturn(Mono.just(VALID_KEYS)); + given(this.securityService.getUaaUrl()).willReturn(Mono.just("http://localhost:8080/uaa")); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}"; + StepVerifier + .create(this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .consumeErrorWith((ex) -> { + assertThat(ex).isExactlyInstanceOf(CloudFoundryAuthorizationException.class); + assertThat(((CloudFoundryAuthorizationException) ex).getReason()).isEqualTo(Reason.INVALID_AUDIENCE); + }) + .verify(); + } + + private String getSignedToken(byte[] header, byte[] claims) throws Exception { + PrivateKey privateKey = getPrivateKey(); + Signature signature = Signature.getInstance("SHA256WithRSA"); + signature.initSign(privateKey); + byte[] content = dotConcat(Base64.getUrlEncoder().encode(header), Base64.getEncoder().encode(claims)); + signature.update(content); + byte[] crypto = signature.sign(); + byte[] token = dotConcat(Base64.getUrlEncoder().encode(header), Base64.getUrlEncoder().encode(claims), + Base64.getUrlEncoder().encode(crypto)); + return new String(token, StandardCharsets.UTF_8); + } + + private PrivateKey getPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException { + String signingKey = """ + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDSbn2Xa72IOcxu + tcd+qQ6ufZ1VDe98EmpwO4VQrTd37U9kZtWU0KqeSkgnyzIWmlbyWOdbB4/v4uJa + lGjPQjt9hvd3xOOFXzpj33sWXgMGvGAzopMk64T+7GegOFlDXguA5TZyReM7M51O + ycYwpAEsKXS+lxcG0UsxpJum/WjOLyHsMnJVnoScVBlRYZ2BMyEOuap69/H3lT/X + pzlYEM6SrAifsaWvL2f1K7HKBt/yDkDOlZy6xmAMsghnslNSV0FvypTZrQOXia8t + k6fjA+iN+P0LDZAgKxzn4/B/bV8/6HN/7VZJEdudi/y5qdE7SBnx6QZqCEz/YfqC + olujacgnAgMBAAECggEAc9X2tJ/OWWrXqinOg160gkELloJxTi8lAFsDbAGuAwpT + JcWl1KF5CmGBjsY/8ElNi2J9GJL1HOwcBhikCVNARD1DhF6RkB13mvquWwWtTMvt + eP8JWM19DIc+E+hw2rCuTGngqs7l4vTqpzBTNPtS2eiIJ1IsjsgvSEiAlk/wnW48 + 11cf6SQMQcT3HNTWrS+yLycEuWKb6Khh8RpD9D+i8w2+IspWz5lTP7BrKCUNsLOx + 6+5T52HcaZ9z3wMnDqfqIKWl3h8M+q+HFQ4EN5BPWYV4fF7EOx7+Qf2fKDFPoTjC + VTWzDRNAA1xPqwdF7IdPVOXCdaUJDOhHeXZGaTNSwQKBgQDxb9UiR/Jh1R3muL7I + neIt1gXa0O+SK7NWYl4DkArYo7V81ztxI8r+xKEeu5zRZZkpaJHxOnd3VfADascw + UfALvxGxN2z42lE6zdhrmxZ3ma+akQFsv7NyXcBT00sdW+xmOiCaAj0cgxNOXiV3 + sYOwUy3SqUIPO2obpb+KC5ALHwKBgQDfH+NSQ/jn89oVZ3lzUORa+Z+aL1TGsgzs + p7IG0MTEYiR9/AExYUwJab0M4PDXhumeoACMfkCFALNVhpch2nXZv7X5445yRgfD + ONY4WknecuA0rfCLTruNWnQ3RR+BXmd9jD/5igd9hEIawz3V+jCHvAtzI8/CZIBt + AArBs5kp+QKBgQCdxwN1n6baIDemK10iJWtFoPO6h4fH8h8EeMwPb/ZmlLVpnA4Q + Zd+mlkDkoJ5eiRKKaPfWuOqRZeuvj/wTq7g/NOIO+bWQ+rrSvuqLh5IrHpgPXmub + 8bsHJhUlspMH4KagN6ROgOAG3fGj6Qp7KdpxRCpR3KJ66czxvGNrhxre6QKBgB+s + MCGiYnfSprd5G8VhyziazKwfYeJerfT+DQhopDXYVKPJnQW8cQW5C8wDNkzx6sHI + pqtK1K/MnKhcVaHJmAcT7qoNQlA4Xqu4qrgPIQNBvU/dDRNJVthG6c5aspEzrG8m + 9IHgtRV9K8EOy/1O6YqrB9kNUVWf3JccdWpvqyNJAoGAORzJiQCOk4egbdcozDTo + 4Tg4qk/03qpTy5k64DxkX1nJHu8V/hsKwq9Af7Fj/iHy2Av54BLPlBaGPwMi2bzB + gYjmUomvx/fqOTQks9Rc4PIMB43p6Rdj0sh+52SKPDR2eHbwsmpuQUXnAs20BPPI + J/OOn5zOs8yf26os0q3+JUM= + -----END PRIVATE KEY-----"""; + String privateKey = signingKey.replace("-----BEGIN PRIVATE KEY-----\n", ""); + privateKey = privateKey.replace("-----END PRIVATE KEY-----", ""); + privateKey = privateKey.replace("\n", ""); + byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(privateKey); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePrivate(keySpec); + } + + private byte[] dotConcat(byte[]... bytes) throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + for (int i = 0; i < bytes.length; i++) { + if (i > 0) { + StreamUtils.copy(DOT, result); + } + StreamUtils.copy(bytes[i], result); + } + return result.toByteArray(); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryActuatorAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryActuatorAutoConfigurationTests.java index b98b9f17203b..709390a0b1c2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryActuatorAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import java.util.Arrays; import java.util.Collection; @@ -25,10 +25,8 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; import org.springframework.boot.actuate.endpoint.ApiVersion; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; @@ -40,14 +38,17 @@ import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestTemplateAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; @@ -290,7 +291,7 @@ void healthEndpointInvokerShouldBeCloudFoundryWebExtension() { .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", "vcap.application.cf_api:https://my-cloud-controller.com") .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, - HealthEndpointAutoConfiguration.class)) + HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class)) .run((context) -> { Collection endpoints = context .getBean("cloudFoundryWebEndpointServletHandlerMapping", diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryHealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryHealthEndpointWebExtensionTests.java new file mode 100644 index 000000000000..088d5b26a71a --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryHealthEndpointWebExtensionTests.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.ApiVersion; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.health.contributor.CompositeHealth; +import org.springframework.boot.health.contributor.ContributedHealth; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestTemplateAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CloudFoundryHealthEndpointWebExtension}. + * + * @author Madhura Bhave + */ +class CloudFoundryHealthEndpointWebExtensionTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withPropertyValues("VCAP_APPLICATION={}") + .withConfiguration(AutoConfigurations.of(SecurityAutoConfiguration.class, WebMvcAutoConfiguration.class, + JacksonAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, + RestTemplateAutoConfiguration.class, ManagementContextAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class, + WebEndpointAutoConfiguration.class, HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + CloudFoundryActuatorAutoConfiguration.class)) + .withUserConfiguration(TestHealthIndicator.class); + + @Test + void healthComponentsAlwaysPresent() { + this.contextRunner.run((context) -> { + CloudFoundryHealthEndpointWebExtension extension = context + .getBean(CloudFoundryHealthEndpointWebExtension.class); + ContributedHealth body = extension.health(ApiVersion.V3).getBody(); + ContributedHealth health = ((CompositeHealth) body).getComponents().entrySet().iterator().next().getValue(); + assertThat(((Health) health).getDetails()).containsEntry("spring", "boot"); + }); + } + + private static final class TestHealthIndicator implements HealthIndicator { + + @Override + public Health health() { + return Health.up().withDetail("spring", "boot").build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryInfoEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryInfoEndpointWebExtensionTests.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryInfoEndpointWebExtensionTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryInfoEndpointWebExtensionTests.java index 1048cb86fae3..1d5bd6f43d80 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryInfoEndpointWebExtensionTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryInfoEndpointWebExtensionTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import java.util.Map; @@ -26,18 +26,18 @@ import org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestTemplateAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java index 9ea193654c07..f70dee0b5eec 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import java.time.Duration; import java.util.ArrayList; @@ -29,9 +29,6 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; @@ -43,9 +40,12 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -73,7 +73,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests { private final TokenValidator tokenValidator = mock(TokenValidator.class); - private final CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class); + private final SecurityService securityService = mock(SecurityService.class); @Test void operationWithSecurityInterceptorForbidden() { @@ -204,7 +204,7 @@ private void load(Class configuration, Consumer clientConsumer new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withUserConfiguration(configuration, CloudFoundryMvcConfiguration.class) .withBean(TokenValidator.class, () -> this.tokenValidator) - .withBean(CloudFoundrySecurityService.class, () -> this.securityService) + .withBean(SecurityService.class, () -> this.securityService) .run((context) -> consumer.accept(context, WebTestClient.bindToServer() .baseUrl("http://localhost:" + getPort( (AnnotationConfigServletWebServerApplicationContext) context.getSourceApplicationContext())) @@ -227,9 +227,8 @@ private String mockAccessToken() { static class CloudFoundryMvcConfiguration { @Bean - CloudFoundrySecurityInterceptor interceptor(TokenValidator tokenValidator, - CloudFoundrySecurityService securityService) { - return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id"); + SecurityInterceptor interceptor(TokenValidator tokenValidator, SecurityService securityService) { + return new SecurityInterceptor(tokenValidator, securityService, "app-id"); } @Bean @@ -241,7 +240,7 @@ EndpointMediaTypes EndpointMediaTypes() { @Bean CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping( WebEndpointDiscoverer webEndpointDiscoverer, EndpointMediaTypes endpointMediaTypes, - CloudFoundrySecurityInterceptor interceptor) { + SecurityInterceptor interceptor) { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com")); corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST")); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java similarity index 77% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java index 6326dd460e8e..15d677f4d982 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryLinksHandler; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryWebEndpointServletHandlerMappingRuntimeHints; import org.springframework.boot.actuate.endpoint.web.Link; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryLinksHandler; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryWebEndpointServletHandlerMappingRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityInterceptorTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityInterceptorTests.java new file mode 100644 index 000000000000..b8ccacb10fc3 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityInterceptorTests.java @@ -0,0 +1,139 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; + +import java.util.Base64; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.SecurityResponse; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockHttpServletRequest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.assertArg; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +/** + * Tests for {@link SecurityInterceptor}. + * + * @author Madhura Bhave + */ +@ExtendWith(MockitoExtension.class) +class SecurityInterceptorTests { + + @Mock + private TokenValidator tokenValidator; + + @Mock + private SecurityService securityService; + + private SecurityInterceptor interceptor; + + private MockHttpServletRequest request; + + @BeforeEach + void setup() { + this.interceptor = new SecurityInterceptor(this.tokenValidator, this.securityService, "my-app-id"); + this.request = new MockHttpServletRequest(); + } + + @Test + void preHandleWhenRequestIsPreFlightShouldReturnTrue() { + this.request.setMethod("OPTIONS"); + this.request.addHeader(HttpHeaders.ORIGIN, "https://example.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); + } + + @Test + void preHandleWhenTokenIsMissingShouldReturnFalse() { + SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); + assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus()); + } + + @Test + void preHandleWhenTokenIsNotBearerShouldReturnFalse() { + this.request.addHeader("Authorization", mockAccessToken()); + SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); + assertThat(response.getStatus()).isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus()); + } + + @Test + void preHandleWhenApplicationIdIsNullShouldReturnFalse() { + this.interceptor = new SecurityInterceptor(this.tokenValidator, this.securityService, null); + this.request.addHeader("Authorization", "bearer " + mockAccessToken()); + SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); + assertThat(response.getStatus()).isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus()); + } + + @Test + void preHandleWhenCloudFoundrySecurityServiceIsNullShouldReturnFalse() { + this.interceptor = new SecurityInterceptor(this.tokenValidator, null, "my-app-id"); + this.request.addHeader("Authorization", "bearer " + mockAccessToken()); + SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); + assertThat(response.getStatus()).isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus()); + } + + @Test + void preHandleWhenAccessIsNotAllowedShouldReturnFalse() { + String accessToken = mockAccessToken(); + this.request.addHeader("Authorization", "bearer " + accessToken); + given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(AccessLevel.RESTRICTED); + SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); + assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus()); + } + + @Test + void preHandleSuccessfulWithFullAccess() { + String accessToken = mockAccessToken(); + this.request.addHeader("Authorization", "Bearer " + accessToken); + given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(AccessLevel.FULL); + SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("test")); + then(this.tokenValidator).should().validate(assertArg((token) -> assertThat(token).hasToString(accessToken))); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); + assertThat(this.request.getAttribute("cloudFoundryAccessLevel")).isEqualTo(AccessLevel.FULL); + } + + @Test + void preHandleSuccessfulWithRestrictedAccess() { + String accessToken = mockAccessToken(); + this.request.addHeader("Authorization", "Bearer " + accessToken); + given(this.securityService.getAccessLevel(accessToken, "my-app-id")).willReturn(AccessLevel.RESTRICTED); + SecurityResponse response = this.interceptor.preHandle(this.request, EndpointId.of("info")); + then(this.tokenValidator).should().validate(assertArg((token) -> assertThat(token).hasToString(accessToken))); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK); + assertThat(this.request.getAttribute("cloudFoundryAccessLevel")).isEqualTo(AccessLevel.RESTRICTED); + } + + private String mockAccessToken() { + return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu" + + "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ." + + Base64.getEncoder().encodeToString("signature".getBytes()); + } + +} diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityServiceTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityServiceTests.java new file mode 100644 index 000000000000..18e97c36876c --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SecurityServiceTests.java @@ -0,0 +1,207 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; + +import java.util.Map; +import java.util.function.Consumer; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.AccessLevel; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.test.MockServerRestTemplateCustomizer; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.header; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withServerError; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withUnauthorizedRequest; + +/** + * Tests for {@link SecurityService}. + * + * @author Madhura Bhave + */ +class SecurityServiceTests { + + private static final String CLOUD_CONTROLLER = "https://my-cloud-controller.com"; + + private static final String CLOUD_CONTROLLER_PERMISSIONS = CLOUD_CONTROLLER + "/v2/apps/my-app-id/permissions"; + + private static final String UAA_URL = "https://my-uaa.com"; + + private SecurityService securityService; + + private MockRestServiceServer server; + + @BeforeEach + void setup() { + MockServerRestTemplateCustomizer mockServerCustomizer = new MockServerRestTemplateCustomizer(); + RestTemplateBuilder builder = new RestTemplateBuilder(mockServerCustomizer); + this.securityService = new SecurityService(builder, CLOUD_CONTROLLER, false); + this.server = mockServerCustomizer.getServer(); + } + + @Test + void skipSslValidationWhenTrue() { + RestTemplateBuilder builder = new RestTemplateBuilder(); + this.securityService = new SecurityService(builder, CLOUD_CONTROLLER, true); + RestTemplate restTemplate = (RestTemplate) ReflectionTestUtils.getField(this.securityService, "restTemplate"); + assertThat(restTemplate.getRequestFactory()).isInstanceOf(SkipSslVerificationHttpRequestFactory.class); + } + + @Test + void doNotSkipSslValidationWhenFalse() { + RestTemplateBuilder builder = new RestTemplateBuilder(); + this.securityService = new SecurityService(builder, CLOUD_CONTROLLER, false); + RestTemplate restTemplate = (RestTemplate) ReflectionTestUtils.getField(this.securityService, "restTemplate"); + assertThat(restTemplate.getRequestFactory()).isNotInstanceOf(SkipSslVerificationHttpRequestFactory.class); + } + + @Test + void getAccessLevelWhenSpaceDeveloperShouldReturnFull() { + String responseBody = "{\"read_sensitive_data\": true,\"read_basic_data\": true}"; + this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) + .andExpect(header("Authorization", "bearer my-access-token")) + .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); + AccessLevel accessLevel = this.securityService.getAccessLevel("my-access-token", "my-app-id"); + this.server.verify(); + assertThat(accessLevel).isEqualTo(AccessLevel.FULL); + } + + @Test + void getAccessLevelWhenNotSpaceDeveloperShouldReturnRestricted() { + String responseBody = "{\"read_sensitive_data\": false,\"read_basic_data\": true}"; + this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) + .andExpect(header("Authorization", "bearer my-access-token")) + .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); + AccessLevel accessLevel = this.securityService.getAccessLevel("my-access-token", "my-app-id"); + this.server.verify(); + assertThat(accessLevel).isEqualTo(AccessLevel.RESTRICTED); + } + + @Test + void getAccessLevelWhenTokenIsNotValidShouldThrowException() { + this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) + .andExpect(header("Authorization", "bearer my-access-token")) + .andRespond(withUnauthorizedRequest()); + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id")) + .satisfies(reasonRequirement(Reason.INVALID_TOKEN)); + } + + @Test + void getAccessLevelWhenForbiddenShouldThrowException() { + this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) + .andExpect(header("Authorization", "bearer my-access-token")) + .andRespond(withStatus(HttpStatus.FORBIDDEN)); + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id")) + .satisfies(reasonRequirement(Reason.ACCESS_DENIED)); + } + + @Test + void getAccessLevelWhenCloudControllerIsNotReachableThrowsException() { + this.server.expect(requestTo(CLOUD_CONTROLLER_PERMISSIONS)) + .andExpect(header("Authorization", "bearer my-access-token")) + .andRespond(withServerError()); + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy(() -> this.securityService.getAccessLevel("my-access-token", "my-app-id")) + .satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE)); + } + + @Test + void fetchTokenKeysWhenSuccessfulShouldReturnListOfKeysFromUAA() { + this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")) + .andRespond(withSuccess("{\"token_endpoint\":\"https://my-uaa.com\"}", MediaType.APPLICATION_JSON)); + String tokenKeyValue = """ + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO + rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7 + fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB + LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO + kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo + jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI + JwIDAQAB + -----END PUBLIC KEY-----"""; + String responseBody = "{\"keys\" : [ {\"kid\":\"test-key\",\"value\" : \"" + tokenKeyValue.replace("\n", "\\n") + + "\"} ]}"; + this.server.expect(requestTo(UAA_URL + "/token_keys")) + .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); + Map tokenKeys = this.securityService.fetchTokenKeys(); + this.server.verify(); + assertThat(tokenKeys).containsEntry("test-key", tokenKeyValue); + } + + @Test + void fetchTokenKeysWhenNoKeysReturnedFromUAA() { + this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")) + .andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON)); + String responseBody = "{\"keys\": []}"; + this.server.expect(requestTo(UAA_URL + "/token_keys")) + .andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON)); + Map tokenKeys = this.securityService.fetchTokenKeys(); + this.server.verify(); + assertThat(tokenKeys).isEmpty(); + } + + @Test + void fetchTokenKeysWhenUnsuccessfulShouldThrowException() { + this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")) + .andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON)); + this.server.expect(requestTo(UAA_URL + "/token_keys")).andRespond(withServerError()); + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy(() -> this.securityService.fetchTokenKeys()) + .satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE)); + } + + @Test + void getUaaUrlShouldCallCloudControllerInfoOnlyOnce() { + this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")) + .andRespond(withSuccess("{\"token_endpoint\":\"" + UAA_URL + "\"}", MediaType.APPLICATION_JSON)); + String uaaUrl = this.securityService.getUaaUrl(); + this.server.verify(); + assertThat(uaaUrl).isEqualTo(UAA_URL); + // Second call should not need to hit server + uaaUrl = this.securityService.getUaaUrl(); + assertThat(uaaUrl).isEqualTo(UAA_URL); + } + + @Test + void getUaaUrlWhenCloudControllerUrlIsNotReachableShouldThrowException() { + this.server.expect(requestTo(CLOUD_CONTROLLER + "/info")).andRespond(withServerError()); + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy(() -> this.securityService.getUaaUrl()) + .satisfies(reasonRequirement(Reason.SERVICE_UNAVAILABLE)); + } + + private Consumer reasonRequirement(Reason reason) { + return (ex) -> assertThat(ex.getReason()).isEqualTo(reason); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/SkipSslVerificationHttpRequestFactoryTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SkipSslVerificationHttpRequestFactoryTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/SkipSslVerificationHttpRequestFactoryTests.java rename to spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SkipSslVerificationHttpRequestFactoryTests.java index 482f09b89dc4..d7e7e828738e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/SkipSslVerificationHttpRequestFactoryTests.java +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/SkipSslVerificationHttpRequestFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; import javax.net.ssl.SSLHandshakeException; @@ -23,7 +23,7 @@ import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; import org.springframework.boot.testsupport.web.servlet.ExampleServlet; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.servlet.ServletRegistrationBean; diff --git a/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/TokenValidatorTests.java b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/TokenValidatorTests.java new file mode 100644 index 000000000000..a38d8c703028 --- /dev/null +++ b/spring-boot-project/spring-boot-cloudfoundry/src/test/java/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/TokenValidatorTests.java @@ -0,0 +1,264 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.servlet; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.Signature; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; +import java.util.Collections; +import java.util.Map; +import java.util.function.Consumer; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.cloudfoundry.actuate.autoconfigure.endpoint.Token; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.util.StreamUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.never; + +/** + * Tests for {@link TokenValidator}. + * + * @author Madhura Bhave + */ +@ExtendWith(MockitoExtension.class) +class TokenValidatorTests { + + private static final byte[] DOT = ".".getBytes(); + + @Mock + private SecurityService securityService; + + private TokenValidator tokenValidator; + + private static final String VALID_KEY = """ + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO + rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7 + fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB + LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO + kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo + jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI + JwIDAQAB + -----END PUBLIC KEY-----"""; + + private static final String INVALID_KEY = """ + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzYuc22QSst/dS7geYYK + 5l5kLxU0tayNdixkEQ17ix+CUcUbKIsnyftZxaCYT46rQtXgCaYRdJcbB3hmyrOa + vkhTpX79xJZnQmfuamMbZBqitvscxW9zRR9tBUL6vdi/0rpoUwPMEh8+Bw7CgYR0 + FK0DhWYBNDfe9HKcyZEv3max8Cdq18htxjEsdYO0iwzhtKRXomBWTdhD5ykd/fAC + VTr4+KEY+IeLvubHVmLUhbE5NgWXxrRpGasDqzKhCTmsa2Ysf712rl57SlH0Wz/M + r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s + YwIDAQAB + -----END PUBLIC KEY-----"""; + + private static final Map INVALID_KEYS = Collections.singletonMap("invalid-key", INVALID_KEY); + + private static final Map VALID_KEYS = Collections.singletonMap("valid-key", VALID_KEY); + + @BeforeEach + void setup() { + this.tokenValidator = new TokenValidator(this.securityService); + } + + @Test + void validateTokenWhenKidValidationFailsTwiceShouldThrowException() { + ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", INVALID_KEYS); + given(this.securityService.fetchTokenKeys()).willReturn(INVALID_KEYS); + String header = "{\"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{\"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy( + () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .satisfies(reasonRequirement(Reason.INVALID_KEY_ID)); + } + + @Test + void validateTokenWhenKidValidationSucceedsInTheSecondAttempt() throws Exception { + ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", INVALID_KEYS); + given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); + given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))); + then(this.securityService).should().fetchTokenKeys(); + } + + @Test + void validateTokenShouldFetchTokenKeysIfNull() throws Exception { + given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); + given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))); + then(this.securityService).should().fetchTokenKeys(); + } + + @Test + void validateTokenWhenValidShouldNotFetchTokenKeys() throws Exception { + ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", VALID_KEYS); + given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes()))); + then(this.securityService).should(never()).fetchTokenKeys(); + } + + @Test + void validateTokenWhenSignatureInvalidShouldThrowException() { + ReflectionTestUtils.setField(this.tokenValidator, "tokenKeys", + Collections.singletonMap("valid-key", INVALID_KEY)); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\",\"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy( + () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .satisfies(reasonRequirement(Reason.INVALID_SIGNATURE)); + } + + @Test + void validateTokenWhenTokenAlgorithmIsNotRS256ShouldThrowException() { + String header = "{ \"alg\": \"HS256\", \"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"actuator.read\"]}"; + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy( + () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .satisfies(reasonRequirement(Reason.UNSUPPORTED_TOKEN_SIGNING_ALGORITHM)); + } + + @Test + void validateTokenWhenExpiredShouldThrowException() { + given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); + given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; + String claims = "{ \"jti\": \"0236399c350c47f3ae77e67a75e75e7d\", \"exp\": 1477509977, \"scope\": [\"actuator.read\"]}"; + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy( + () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .satisfies(reasonRequirement(Reason.TOKEN_EXPIRED)); + } + + @Test + void validateTokenWhenIssuerIsNotValidShouldThrowException() { + given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); + given(this.securityService.getUaaUrl()).willReturn("https://other-uaa.com"); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\", \"scope\": [\"actuator.read\"]}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\"}"; + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy( + () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .satisfies(reasonRequirement(Reason.INVALID_ISSUER)); + } + + @Test + void validateTokenWhenAudienceIsNotValidShouldThrowException() { + given(this.securityService.fetchTokenKeys()).willReturn(VALID_KEYS); + given(this.securityService.getUaaUrl()).willReturn("http://localhost:8080/uaa"); + String header = "{ \"alg\": \"RS256\", \"kid\": \"valid-key\", \"typ\": \"JWT\"}"; + String claims = "{ \"exp\": 2147483647, \"iss\": \"http://localhost:8080/uaa/oauth/token\", \"scope\": [\"foo.bar\"]}"; + assertThatExceptionOfType(CloudFoundryAuthorizationException.class) + .isThrownBy( + () -> this.tokenValidator.validate(new Token(getSignedToken(header.getBytes(), claims.getBytes())))) + .satisfies(reasonRequirement(Reason.INVALID_AUDIENCE)); + } + + private String getSignedToken(byte[] header, byte[] claims) throws Exception { + PrivateKey privateKey = getPrivateKey(); + Signature signature = Signature.getInstance("SHA256WithRSA"); + signature.initSign(privateKey); + byte[] content = dotConcat(Base64.getUrlEncoder().encode(header), Base64.getEncoder().encode(claims)); + signature.update(content); + byte[] crypto = signature.sign(); + byte[] token = dotConcat(Base64.getUrlEncoder().encode(header), Base64.getUrlEncoder().encode(claims), + Base64.getUrlEncoder().encode(crypto)); + return new String(token, StandardCharsets.UTF_8); + } + + private PrivateKey getPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException { + String signingKey = """ + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDSbn2Xa72IOcxu + tcd+qQ6ufZ1VDe98EmpwO4VQrTd37U9kZtWU0KqeSkgnyzIWmlbyWOdbB4/v4uJa + lGjPQjt9hvd3xOOFXzpj33sWXgMGvGAzopMk64T+7GegOFlDXguA5TZyReM7M51O + ycYwpAEsKXS+lxcG0UsxpJum/WjOLyHsMnJVnoScVBlRYZ2BMyEOuap69/H3lT/X + pzlYEM6SrAifsaWvL2f1K7HKBt/yDkDOlZy6xmAMsghnslNSV0FvypTZrQOXia8t + k6fjA+iN+P0LDZAgKxzn4/B/bV8/6HN/7VZJEdudi/y5qdE7SBnx6QZqCEz/YfqC + olujacgnAgMBAAECggEAc9X2tJ/OWWrXqinOg160gkELloJxTi8lAFsDbAGuAwpT + JcWl1KF5CmGBjsY/8ElNi2J9GJL1HOwcBhikCVNARD1DhF6RkB13mvquWwWtTMvt + eP8JWM19DIc+E+hw2rCuTGngqs7l4vTqpzBTNPtS2eiIJ1IsjsgvSEiAlk/wnW48 + 11cf6SQMQcT3HNTWrS+yLycEuWKb6Khh8RpD9D+i8w2+IspWz5lTP7BrKCUNsLOx + 6+5T52HcaZ9z3wMnDqfqIKWl3h8M+q+HFQ4EN5BPWYV4fF7EOx7+Qf2fKDFPoTjC + VTWzDRNAA1xPqwdF7IdPVOXCdaUJDOhHeXZGaTNSwQKBgQDxb9UiR/Jh1R3muL7I + neIt1gXa0O+SK7NWYl4DkArYo7V81ztxI8r+xKEeu5zRZZkpaJHxOnd3VfADascw + UfALvxGxN2z42lE6zdhrmxZ3ma+akQFsv7NyXcBT00sdW+xmOiCaAj0cgxNOXiV3 + sYOwUy3SqUIPO2obpb+KC5ALHwKBgQDfH+NSQ/jn89oVZ3lzUORa+Z+aL1TGsgzs + p7IG0MTEYiR9/AExYUwJab0M4PDXhumeoACMfkCFALNVhpch2nXZv7X5445yRgfD + ONY4WknecuA0rfCLTruNWnQ3RR+BXmd9jD/5igd9hEIawz3V+jCHvAtzI8/CZIBt + AArBs5kp+QKBgQCdxwN1n6baIDemK10iJWtFoPO6h4fH8h8EeMwPb/ZmlLVpnA4Q + Zd+mlkDkoJ5eiRKKaPfWuOqRZeuvj/wTq7g/NOIO+bWQ+rrSvuqLh5IrHpgPXmub + 8bsHJhUlspMH4KagN6ROgOAG3fGj6Qp7KdpxRCpR3KJ66czxvGNrhxre6QKBgB+s + MCGiYnfSprd5G8VhyziazKwfYeJerfT+DQhopDXYVKPJnQW8cQW5C8wDNkzx6sHI + pqtK1K/MnKhcVaHJmAcT7qoNQlA4Xqu4qrgPIQNBvU/dDRNJVthG6c5aspEzrG8m + 9IHgtRV9K8EOy/1O6YqrB9kNUVWf3JccdWpvqyNJAoGAORzJiQCOk4egbdcozDTo + 4Tg4qk/03qpTy5k64DxkX1nJHu8V/hsKwq9Af7Fj/iHy2Av54BLPlBaGPwMi2bzB + gYjmUomvx/fqOTQks9Rc4PIMB43p6Rdj0sh+52SKPDR2eHbwsmpuQUXnAs20BPPI + J/OOn5zOs8yf26os0q3+JUM= + -----END PRIVATE KEY-----"""; + String privateKey = signingKey.replace("-----BEGIN PRIVATE KEY-----\n", ""); + privateKey = privateKey.replace("-----END PRIVATE KEY-----", ""); + privateKey = privateKey.replace("\n", ""); + byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(privateKey); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePrivate(keySpec); + } + + private byte[] dotConcat(byte[]... bytes) throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + for (int i = 0; i < bytes.length; i++) { + if (i > 0) { + StreamUtils.copy(DOT, result); + } + StreamUtils.copy(bytes[i], result); + } + return result.toByteArray(); + } + + private Consumer reasonRequirement(Reason reason) { + return (ex) -> assertThat(ex.getReason()).isEqualTo(reason); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/test.jks b/spring-boot-project/spring-boot-cloudfoundry/src/test/resources/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/test.jks similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/test.jks rename to spring-boot-project/spring-boot-cloudfoundry/src/test/resources/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/reactive/test.jks diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/test.jks b/spring-boot-project/spring-boot-cloudfoundry/src/test/resources/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/test.jks similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/test.jks rename to spring-boot-project/spring-boot-cloudfoundry/src/test/resources/org/springframework/boot/cloudfoundry/actuate/autoconfigure/endpoint/servlet/test.jks diff --git a/spring-boot-project/spring-boot-couchbase/build.gradle b/spring-boot-project/spring-boot-couchbase/build.gradle new file mode 100644 index 000000000000..adc43a90fbf5 --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/build.gradle @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Couchbase" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("com.couchbase.client:java-client") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional(project(":spring-boot-project:spring-boot-jackson")) + optional("org.testcontainers:couchbase") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation("org.junit.jupiter:junit-jupiter") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-couchbase/src/dockerTest/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfigurationIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-couchbase/src/dockerTest/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfigurationIntegrationTests.java index 28792c008529..2f870dc92faf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-couchbase/src/dockerTest/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/couchbase/CouchbaseContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-couchbase/src/dockerTest/java/org/springframework/boot/couchbase/testcontainers/CouchbaseContainerConnectionDetailsFactoryTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/couchbase/CouchbaseContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-couchbase/src/dockerTest/java/org/springframework/boot/couchbase/testcontainers/CouchbaseContainerConnectionDetailsFactoryTests.java index 059fc2ef553d..25cd97f25e4b 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/couchbase/CouchbaseContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-couchbase/src/dockerTest/java/org/springframework/boot/couchbase/testcontainers/CouchbaseContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.couchbase; +package org.springframework.boot.couchbase.testcontainers; import com.couchbase.client.java.Cluster; import org.junit.jupiter.api.Test; @@ -26,8 +26,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseConnectionDetails; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-couchbase/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-couchbase/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-couchbase/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-couchbase/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/ClusterEnvironmentBuilderCustomizer.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/ClusterEnvironmentBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/ClusterEnvironmentBuilderCustomizer.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/ClusterEnvironmentBuilderCustomizer.java index 1f4be3d23407..d0f70c36ce9d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/ClusterEnvironmentBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/ClusterEnvironmentBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure; import com.couchbase.client.java.env.ClusterEnvironment; import com.couchbase.client.java.env.ClusterEnvironment.Builder; @@ -25,7 +25,7 @@ * retaining default auto-configuration. * * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface ClusterEnvironmentBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfiguration.java index 54e348c79c1d..9e81e889694a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfiguration.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure; import java.io.IOException; import java.io.InputStream; @@ -43,13 +43,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration.CouchbaseCondition; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Authentication.Jks; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Authentication.Pem; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Ssl; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Timeouts; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration.CouchbaseCondition; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseProperties.Authentication.Jks; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseProperties.Authentication.Pem; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseProperties.Ssl; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseProperties.Timeouts; import org.springframework.boot.io.ApplicationResourceLoader; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; @@ -74,9 +73,9 @@ * @author Andy Wilkinson * @author Phillip Webb * @author Scott Frederick - * @since 1.4.0 + * @since 4.0.0 */ -@AutoConfiguration(after = JacksonAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration") @ConditionalOnClass(Cluster.class) @Conditional(CouchbaseCondition.class) @EnableConfigurationProperties(CouchbaseProperties.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseConnectionDetails.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseConnectionDetails.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseConnectionDetails.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseConnectionDetails.java index 7632d84f2678..e714b74ae122 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseConnectionDetails.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; import org.springframework.boot.ssl.SslBundle; @@ -25,7 +25,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface CouchbaseConnectionDetails extends ConnectionDetails { @@ -50,7 +50,6 @@ public interface CouchbaseConnectionDetails extends ConnectionDetails { /** * SSL bundle to use. * @return the SSL bundle to use - * @since 3.5.0 */ default SslBundle getSslBundle() { return null; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseProperties.java index de4c3acb2cfb..6ee05313b6e0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseProperties.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure; import java.time.Duration; @@ -30,7 +30,7 @@ * @author Brian Clozel * @author Michael Nitschinger * @author Scott Frederick - * @since 1.4.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.couchbase") public class CouchbaseProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseHealthContributorAutoConfiguration.java similarity index 77% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseHealthContributorAutoConfiguration.java index 27fe49392ce9..8db89256eb94 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseHealthContributorAutoConfiguration.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure.health; import com.couchbase.client.java.Cluster; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.couchbase.CouchbaseHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; +import org.springframework.boot.couchbase.health.CouchbaseHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; import org.springframework.context.annotation.Bean; /** @@ -38,11 +38,11 @@ * @author Eddú Meléndez * @author Stephane Nicoll * @author Andy Wilkinson Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( after = { CouchbaseAutoConfiguration.class, CouchbaseReactiveHealthContributorAutoConfiguration.class }) -@ConditionalOnClass(Cluster.class) +@ConditionalOnClass({ Cluster.class, CouchbaseHealthIndicator.class, ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(Cluster.class) @ConditionalOnEnabledHealthIndicator("couchbase") public class CouchbaseHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseReactiveHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseReactiveHealthContributorAutoConfiguration.java similarity index 76% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseReactiveHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseReactiveHealthContributorAutoConfiguration.java index c953ae8c2d78..a56a87ec5117 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseReactiveHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseReactiveHealthContributorAutoConfiguration.java @@ -14,22 +14,22 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure.health; import com.couchbase.client.java.Cluster; import reactor.core.publisher.Flux; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.couchbase.CouchbaseReactiveHealthIndicator; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; +import org.springframework.boot.couchbase.health.CouchbaseReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; import org.springframework.context.annotation.Bean; /** @@ -38,10 +38,11 @@ * * @author Mikalai Lushchytski * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = CouchbaseAutoConfiguration.class) -@ConditionalOnClass({ Cluster.class, Flux.class }) +@ConditionalOnClass({ Cluster.class, Flux.class, CouchbaseReactiveHealthIndicator.class, + ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(Cluster.class) @ConditionalOnEnabledHealthIndicator("couchbase") public class CouchbaseReactiveHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..870b34b55509 --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Couchbase health. + */ +package org.springframework.boot.couchbase.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/package-info.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/package-info.java new file mode 100644 index 000000000000..b8e3a6586aea --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Couchbase. + */ +package org.springframework.boot.couchbase.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseHealth.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseHealth.java similarity index 92% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseHealth.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseHealth.java index f5f98e7170c9..c8cc6d6bc17f 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseHealth.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseHealth.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.couchbase; +package org.springframework.boot.couchbase.health; import java.util.Collection; import java.util.HashMap; @@ -24,7 +24,7 @@ import com.couchbase.client.core.diagnostics.DiagnosticsResult; import com.couchbase.client.core.diagnostics.EndpointDiagnostics; -import org.springframework.boot.actuate.health.Health.Builder; +import org.springframework.boot.health.contributor.Health; /** * Details of Couchbase's health. @@ -39,7 +39,7 @@ class CouchbaseHealth { this.diagnostics = diagnostics; } - void applyTo(Builder builder) { + void applyTo(Health.Builder builder) { builder = isCouchbaseUp(this.diagnostics) ? builder.up() : builder.down(); builder.withDetail("sdk", this.diagnostics.sdk()); builder.withDetail("endpoints", diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseHealthIndicator.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseHealthIndicator.java similarity index 84% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseHealthIndicator.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseHealthIndicator.java index d51df93a8e42..21d524d04377 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseHealthIndicator.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseHealthIndicator.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.couchbase; +package org.springframework.boot.couchbase.health; import com.couchbase.client.core.diagnostics.DiagnosticsResult; import com.couchbase.client.java.Cluster; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.util.Assert; /** @@ -29,7 +29,7 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public class CouchbaseHealthIndicator extends AbstractHealthIndicator { @@ -38,7 +38,6 @@ public class CouchbaseHealthIndicator extends AbstractHealthIndicator { /** * Create an indicator with the specified {@link Cluster}. * @param cluster the Couchbase Cluster - * @since 2.0.6 */ public CouchbaseHealthIndicator(Cluster cluster) { super("Couchbase health check failed"); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseReactiveHealthIndicator.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseReactiveHealthIndicator.java similarity index 83% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseReactiveHealthIndicator.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseReactiveHealthIndicator.java index f14dd98cd558..31b103543ca9 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/CouchbaseReactiveHealthIndicator.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.couchbase; +package org.springframework.boot.couchbase.health; import com.couchbase.client.java.Cluster; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; /** * A {@link ReactiveHealthIndicator} for Couchbase. * * @author Mikalai Lushchytski * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ public class CouchbaseReactiveHealthIndicator extends AbstractReactiveHealthIndicator { diff --git a/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/package-info.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/package-info.java new file mode 100644 index 000000000000..04ad2ba4da0e --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for Couchbase. + */ +package org.springframework.boot.couchbase.health; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/couchbase/CouchbaseContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/testcontainers/CouchbaseContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/couchbase/CouchbaseContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/testcontainers/CouchbaseContainerConnectionDetailsFactory.java index 862ddc82bc02..3860e2a5d0e6 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/couchbase/CouchbaseContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/testcontainers/CouchbaseContainerConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.couchbase; +package org.springframework.boot.couchbase.testcontainers; import org.testcontainers.couchbase.CouchbaseContainer; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseConnectionDetails; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseConnectionDetails; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; diff --git a/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/testcontainers/package-info.java b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/testcontainers/package-info.java new file mode 100644 index 000000000000..048c7181e25e --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/main/java/org/springframework/boot/couchbase/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Couchbase service connections. + */ +package org.springframework.boot.couchbase.testcontainers; diff --git a/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..545d927c69d1 --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,151 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.health.couchbase.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Couchbase health check.", + "defaultValue": true + }, + { + "name": "management.health.couchbase.timeout", + "type": "java.time.Duration", + "description": "Timeout for getting the Bucket information from the server.", + "defaultValue": "1000ms", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.couchbase.bootstrap-hosts", + "type": "java.util.List", + "description": "Couchbase nodes (host or IP address) to bootstrap from.", + "deprecation": { + "replacement": "spring.couchbase.connection-string", + "level": "error" + } + }, + { + "name": "spring.couchbase.bucket.name", + "type": "java.lang.String", + "description": "Name of the bucket to connect to.", + "deprecation": { + "reason": "A bucket is no longer auto-configured.", + "level": "error" + } + }, + { + "name": "spring.couchbase.bucket.password", + "type": "java.lang.String", + "description": "Password of the bucket.", + "deprecation": { + "reason": "A bucket is no longer auto-configured.", + "level": "error" + } + }, + { + "name": "spring.couchbase.env.bootstrap.http-direct-port", + "type": "java.lang.Integer", + "description": "Port for the HTTP bootstrap.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.couchbase.env.bootstrap.http-ssl-port", + "type": "java.lang.Integer", + "description": "Port for the HTTPS bootstrap.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.couchbase.env.endpoints.key-value", + "type": "java.lang.Integer", + "description": "Number of sockets per node against the key/value service.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.couchbase.env.endpoints.query", + "type": "java.lang.Integer", + "description": "Number of sockets per node against the query (N1QL) service.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.couchbase.env.endpoints.queryservice.max-endpoints", + "type": "java.lang.Integer", + "description": "Maximum number of sockets per node.", + "deprecation": { + "replacement": "spring.couchbase.env.io.max-endpoints", + "level": "error" + } + }, + { + "name": "spring.couchbase.env.endpoints.queryservice.min-endpoints", + "type": "java.lang.Integer", + "description": "Minimum number of sockets per node.", + "deprecation": { + "replacement": "spring.couchbase.env.io.min-endpoints", + "level": "error" + } + }, + { + "name": "spring.couchbase.env.endpoints.view", + "type": "java.lang.Integer", + "description": "Number of sockets per node against the view service.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.couchbase.env.endpoints.viewservice.max-endpoints", + "type": "java.lang.Integer", + "description": "Maximum number of sockets per node.", + "deprecation": { + "replacement": "spring.couchbase.env.io.max-endpoints", + "level": "error" + } + }, + { + "name": "spring.couchbase.env.endpoints.viewservice.min-endpoints", + "type": "java.lang.Integer", + "description": "Minimum number of sockets per node.", + "deprecation": { + "replacement": "spring.couchbase.env.io.min-endpoints", + "level": "error" + } + }, + { + "name": "spring.couchbase.env.ssl.key-store", + "type": "java.lang.String", + "description": "Path to the JVM key store that holds the certificates.", + "deprecation": { + "replacement": "spring.couchbase.env.ssl.bundle", + "level": "error", + "since": "3.1.0" + } + }, + { + "name": "spring.couchbase.env.ssl.key-store-password", + "type": "java.lang.String", + "description": "Password used to access the key store.", + "deprecation": { + "replacement": "spring.couchbase.env.ssl.bundle", + "level": "error", + "since": "3.1.0" + } + }, + { + "name": "spring.couchbase.env.timeouts.socket-connect", + "type": "java.time.Duration", + "description": "Socket connect connections timeout.", + "deprecation": { + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..4eb3f0a8009d --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.couchbase.testcontainers.CouchbaseContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..c8727227ebe2 --- /dev/null +++ b/spring-boot-project/spring-boot-couchbase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration +org.springframework.boot.couchbase.autoconfigure.health.CouchbaseHealthContributorAutoConfiguration +org.springframework.boot.couchbase.autoconfigure.health.CouchbaseReactiveHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java rename to spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfigurationTests.java index 953c7e514781..d99f2f423c1d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure; import java.time.Duration; import java.util.HashSet; @@ -37,9 +37,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration.PropertiesCouchbaseConnectionDetails; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration.PropertiesCouchbaseConnectionDetails; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.ssl.NoSuchSslBundleException; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbasePropertiesTests.java b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbasePropertiesTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbasePropertiesTests.java rename to spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbasePropertiesTests.java index 73213fd5681b..f303d7cc0f69 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbasePropertiesTests.java +++ b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbasePropertiesTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure; import com.couchbase.client.core.env.IoConfig; import com.couchbase.client.core.env.TimeoutConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Io; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties.Timeouts; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseProperties.Io; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseProperties.Timeouts; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseTestConfiguration.java b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseTestConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseTestConfiguration.java rename to spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseTestConfiguration.java index 7f588ae56f33..aee3d8fb9522 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseTestConfiguration.java +++ b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/CouchbaseTestConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure; import com.couchbase.client.core.env.Authenticator; import com.couchbase.client.java.Cluster; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseHealthContributorAutoConfigurationTests.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseHealthContributorAutoConfigurationTests.java index 82e7adfc7cf1..02e94ac08858 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseHealthContributorAutoConfigurationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure.health; import com.couchbase.client.java.Cluster; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.couchbase.CouchbaseHealthIndicator; -import org.springframework.boot.actuate.couchbase.CouchbaseReactiveHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.couchbase.health.CouchbaseHealthIndicator; +import org.springframework.boot.couchbase.health.CouchbaseReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseReactiveHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseReactiveHealthContributorAutoConfigurationTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseReactiveHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseReactiveHealthContributorAutoConfigurationTests.java index 81ce9ab9878e..a6bb1bc0ebf2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseReactiveHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/autoconfigure/health/CouchbaseReactiveHealthContributorAutoConfigurationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.couchbase; +package org.springframework.boot.couchbase.autoconfigure.health; import com.couchbase.client.java.Cluster; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.couchbase.CouchbaseHealthIndicator; -import org.springframework.boot.actuate.couchbase.CouchbaseReactiveHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.couchbase.health.CouchbaseHealthIndicator; +import org.springframework.boot.couchbase.health.CouchbaseReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/couchbase/CouchbaseHealthIndicatorTests.java b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/health/CouchbaseHealthIndicatorTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/couchbase/CouchbaseHealthIndicatorTests.java rename to spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/health/CouchbaseHealthIndicatorTests.java index e7ef05269fa7..299a9f07c5c0 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/couchbase/CouchbaseHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/health/CouchbaseHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.couchbase; +package org.springframework.boot.couchbase.health; import java.util.Arrays; import java.util.Collections; @@ -30,8 +30,8 @@ import com.couchbase.client.java.Cluster; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/couchbase/CouchbaseReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/health/CouchbaseReactiveHealthIndicatorTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/couchbase/CouchbaseReactiveHealthIndicatorTests.java rename to spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/health/CouchbaseReactiveHealthIndicatorTests.java index c54e1c10fb25..2e6732c14a87 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/couchbase/CouchbaseReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-couchbase/src/test/java/org/springframework/boot/couchbase/health/CouchbaseReactiveHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.couchbase; +package org.springframework.boot.couchbase.health; import java.time.Duration; import java.util.Arrays; @@ -33,8 +33,8 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/couchbase/key.crt b/spring-boot-project/spring-boot-couchbase/src/test/resources/org/springframework/boot/couchbase/autoconfigure/key.crt similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/couchbase/key.crt rename to spring-boot-project/spring-boot-couchbase/src/test/resources/org/springframework/boot/couchbase/autoconfigure/key.crt diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/couchbase/key.pem b/spring-boot-project/spring-boot-couchbase/src/test/resources/org/springframework/boot/couchbase/autoconfigure/key.pem similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/couchbase/key.pem rename to spring-boot-project/spring-boot-couchbase/src/test/resources/org/springframework/boot/couchbase/autoconfigure/key.pem diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/couchbase/keystore.jks b/spring-boot-project/spring-boot-couchbase/src/test/resources/org/springframework/boot/couchbase/autoconfigure/keystore.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/couchbase/keystore.jks rename to spring-boot-project/spring-boot-couchbase/src/test/resources/org/springframework/boot/couchbase/autoconfigure/keystore.jks diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/couchbase/test.jks b/spring-boot-project/spring-boot-couchbase/src/test/resources/org/springframework/boot/couchbase/autoconfigure/test.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/couchbase/test.jks rename to spring-boot-project/spring-boot-couchbase/src/test/resources/org/springframework/boot/couchbase/autoconfigure/test.jks diff --git a/spring-boot-project/spring-boot-data-cassandra/build.gradle b/spring-boot-project/spring-boot-data-cassandra/build.gradle new file mode 100644 index 000000000000..beae2aa14c8b --- /dev/null +++ b/spring-boot-project/spring-boot-data-cassandra/build.gradle @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data Cassandra" + +dependencies { + api(project(":spring-boot-project:spring-boot-cassandra")) + api(project(":spring-boot-project:spring-boot-data-commons")) + api("org.springframework.data:spring-data-cassandra") { + exclude group: "org.slf4j", module: "jcl-over-slf4j" + } + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-reactor")) + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation("org.junit.jupiter:junit-jupiter") + dockerTestImplementation("org.testcontainers:cassandra") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-data-cassandra/src/dockerTest/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfigurationIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-data-cassandra/src/dockerTest/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfigurationIntegrationTests.java index 4a355bb911b1..209ce9f3e008 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/dockerTest/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.CqlSessionBuilder; @@ -26,8 +26,8 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.data.cassandra.city.City; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.data.cassandra.domain.city.City; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfiguration.java index 545e714f8562..3b515d107b20 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import java.util.Collections; import java.util.List; @@ -25,11 +25,11 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.domain.EntityScanPackages; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; @@ -58,7 +58,7 @@ * @author Mark Paluch * @author Madhura Bhave * @author Christoph Strobl - * @since 1.3.0 + * @since 4.0.0 */ @AutoConfiguration(after = CassandraAutoConfiguration.class) @ConditionalOnClass({ CqlSession.class, CassandraAdminOperations.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveDataAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveDataAutoConfiguration.java index 0817b471613f..2588dad516ab 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.CqlSession; import reactor.core.publisher.Flux; @@ -41,7 +41,7 @@ * * @author Eddú Meléndez * @author Mark Paluch - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = CassandraDataAutoConfiguration.class) @ConditionalOnClass({ CqlSession.class, ReactiveCassandraTemplate.class, Flux.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesAutoConfiguration.java index e119cbc137d5..46342622f343 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -34,7 +34,7 @@ * * @author Eddú Meléndez * @author Mark Paluch - * @since 2.0.0 + * @since 4.0.0 * @see EnableReactiveCassandraRepositories */ @AutoConfiguration(after = CassandraReactiveDataAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesRegistrar.java index 4a0024393d90..8d1c2838654f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesAutoConfiguration.java index 0cedf55f4ebc..ca35f5e6c8f8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.CqlSession; @@ -34,7 +34,7 @@ * Repositories. * * @author Eddú Meléndez - * @since 1.3.0 + * @since 4.0.0 * @see EnableCassandraRepositories */ @AutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesRegistrar.java index 8fa77792b1bb..e1c432c0f76c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/package-info.java new file mode 100644 index 000000000000..1ae0cce98586 --- /dev/null +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/java/org/springframework/boot/data/cassandra/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data Cassandra. + */ +package org.springframework.boot.data.cassandra.autoconfigure; diff --git a/spring-boot-project/spring-boot-data-cassandra/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-cassandra/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..27367bba9c85 --- /dev/null +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,263 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.data.cassandra.compression", + "defaultValue": "none", + "deprecation": { + "replacement": "spring.cassandra.compression", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.config", + "type": "org.springframework.core.io.Resource", + "deprecation": { + "replacement": "spring.cassandra.config", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.connection.connect-timeout", + "defaultValue": "5s", + "deprecation": { + "replacement": "spring.cassandra.connection.connect-timeout", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.connection.init-query-timeout", + "defaultValue": "5s", + "deprecation": { + "replacement": "spring.cassandra.connection.init-query-timeout", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.contact-points", + "defaultValue": [ + "127.0.0.1:9042" + ], + "deprecation": { + "replacement": "spring.cassandra.contact-points", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.controlconnection.timeout", + "defaultValue": "5s", + "deprecation": { + "replacement": "spring.cassandra.controlconnection.timeout", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.jmx-enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable JMX reporting. Default to false as Cassandra JMX reporting is not compatible with Dropwizard Metrics.", + "deprecation": { + "reason": "Cassandra no longer provides JMX metrics.", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.keyspace-name", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.cassandra.keyspace-name", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.load-balancing-policy", + "type": "java.lang.Class", + "description": "Class name of the load balancing policy. The class must have a default constructor.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.cassandra.local-datacenter", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.cassandra.local-datacenter", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.password", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.cassandra.password", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.pool.heartbeat-interval", + "defaultValue": "30s", + "deprecation": { + "replacement": "spring.cassandra.pool.heartbeat-interval", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.pool.idle-timeout", + "defaultValue": "5s", + "deprecation": { + "replacement": "spring.cassandra.pool.idle-timeout", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.pool.max-queue-size", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.cassandra.request.throttler.max-queue-size", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.pool.pool-timeout", + "type": "java.time.Duration", + "description": "Pool timeout when trying to acquire a connection from a host's pool.", + "deprecation": { + "reason": "No longer available.", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.port", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.cassandra.port", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.reconnection-policy", + "type": "java.lang.Class", + "description": "Class name of the reconnection policy. The class must have a default constructor.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.cassandra.repositories.type", + "type": "org.springframework.boot.autoconfigure.data.RepositoryType", + "description": "Type of Cassandra repositories to enable.", + "defaultValue": "auto" + }, + { + "name": "spring.data.cassandra.request.consistency", + "type": "com.datastax.oss.driver.api.core.DefaultConsistencyLevel", + "deprecation": { + "replacement": "spring.cassandra.request.consistency", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.request.page-size", + "defaultValue": 5000, + "deprecation": { + "replacement": "spring.cassandra.request.page-size", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.request.serial-consistency", + "type": "com.datastax.oss.driver.api.core.DefaultConsistencyLevel", + "deprecation": { + "replacement": "spring.cassandra.request.serial-consistency", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.request.throttler.drain-interval", + "type": "java.time.Duration", + "deprecation": { + "replacement": "spring.cassandra.request.throttler.drain-interval", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.request.throttler.max-concurrent-requests", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.cassandra.request.throttler.max-concurrent-requests", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.request.throttler.max-queue-size", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.cassandra.request.throttler.max-queue-size", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.request.throttler.max-requests-per-second", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.cassandra.request.throttler.max-requests-per-second", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.request.throttler.type", + "defaultValue": "none", + "deprecation": { + "replacement": "spring.cassandra.request.throttler.type", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.request.timeout", + "defaultValue": "2s", + "deprecation": { + "replacement": "spring.cassandra.request.timeout", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.retry-policy", + "type": "java.lang.Class", + "description": "Class name of the retry policy. The class must have a default constructor.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.cassandra.schema-action", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.cassandra.schema-action", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.session-name", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.cassandra.session-name", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.ssl", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.cassandra.ssl.enabled", + "level": "error" + } + }, + { + "name": "spring.data.cassandra.username", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.cassandra.username", + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-data-cassandra/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-cassandra/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..e2bb647a5553 --- /dev/null +++ b/spring-boot-project/spring-boot-data-cassandra/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.data.cassandra.autoconfigure.CassandraDataAutoConfiguration +org.springframework.boot.data.cassandra.autoconfigure.CassandraReactiveDataAutoConfiguration +org.springframework.boot.data.cassandra.autoconfigure.CassandraReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.cassandra.autoconfigure.CassandraRepositoriesAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfigurationTests.java index 2e313019200e..a84e4a01128b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraDataAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import java.util.Collections; @@ -22,9 +22,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.data.cassandra.city.City; import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.data.cassandra.domain.city.City; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -126,7 +126,7 @@ void clusterDoesNotExist() { } @Configuration(proxyBeanMethods = false) - @EntityScan("org.springframework.boot.autoconfigure.data.cassandra.city") + @EntityScan("org.springframework.boot.data.cassandra.domain.city") static class EntityScanConfig { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraMockConfiguration.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraMockConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraMockConfiguration.java rename to spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraMockConfiguration.java index 91c8634f2ad4..527006581df5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraMockConfiguration.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraMockConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.context.DriverContext; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveDataAutoConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveDataAutoConfigurationTests.java index f70e5b0f661c..588fa03570f9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveDataAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.data.cassandra.city.City; import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.data.cassandra.domain.city.City; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.data.cassandra.core.ReactiveCassandraTemplate; @@ -86,7 +86,7 @@ void userTypeResolverShouldBeSet() { } @Configuration(proxyBeanMethods = false) - @EntityScan("org.springframework.boot.autoconfigure.data.cassandra.city") + @EntityScan("org.springframework.boot.data.cassandra.domain.city") static class EntityScanConfig { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesAutoConfigurationTests.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesAutoConfigurationTests.java index 031382ffb707..2bb2a0bb25a2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraReactiveRepositoriesAutoConfigurationTests.java @@ -14,19 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.CqlSessionBuilder; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.alt.cassandra.ReactiveCityCassandraRepository; -import org.springframework.boot.autoconfigure.data.cassandra.city.City; -import org.springframework.boot.autoconfigure.data.cassandra.city.ReactiveCityRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.data.cassandra.domain.city.City; +import org.springframework.boot.data.cassandra.domain.city.ReactiveCityRepository; +import org.springframework.boot.data.cassandra.domain.empty.EmptyDataPackage; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; @@ -73,7 +72,7 @@ void testNoRepositoryConfiguration() { @Test void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { this.contextRunner.withUserConfiguration(CustomizedConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(ReactiveCityCassandraRepository.class); + assertThat(context).hasSingleBean(ReactiveCityRepository.class); assertThat(getManagedTypes(context).toList()).hasSize(1).containsOnly(City.class); }); } @@ -112,8 +111,8 @@ static class DefaultConfiguration { } @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(CassandraReactiveRepositoriesAutoConfigurationTests.class) - @EnableReactiveCassandraRepositories(basePackageClasses = ReactiveCityCassandraRepository.class) + @TestAutoConfigurationPackage(City.class) + @EnableReactiveCassandraRepositories(basePackageClasses = ReactiveCityRepository.class) @Import(CassandraMockConfiguration.class) static class CustomizedConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesAutoConfigurationTests.java similarity index 86% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesAutoConfigurationTests.java index 603e16878579..29f094c499b0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/autoconfigure/CassandraRepositoriesAutoConfigurationTests.java @@ -14,19 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.cassandra; +package org.springframework.boot.data.cassandra.autoconfigure; import com.datastax.oss.driver.api.core.CqlSessionBuilder; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.alt.cassandra.CityCassandraRepository; -import org.springframework.boot.autoconfigure.data.cassandra.city.City; -import org.springframework.boot.autoconfigure.data.cassandra.city.CityRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.data.cassandra.domain.city.City; +import org.springframework.boot.data.cassandra.domain.city.CityRepository; +import org.springframework.boot.data.cassandra.domain.empty.EmptyDataPackage; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; @@ -71,7 +70,7 @@ void testNoRepositoryConfiguration() { @Test void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { this.contextRunner.withUserConfiguration(CustomizedConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(CityCassandraRepository.class); + assertThat(context).hasSingleBean(CityRepository.class); assertThat(getManagedTypes(context).toList()).hasSize(1).containsOnly(City.class); }); } @@ -110,8 +109,8 @@ static class DefaultConfiguration { } @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(CassandraRepositoriesAutoConfigurationTests.class) - @EnableCassandraRepositories(basePackageClasses = CityCassandraRepository.class) + @TestAutoConfigurationPackage(City.class) + @EnableCassandraRepositories(basePackageClasses = CityRepository.class) @Import(CassandraMockConfiguration.class) static class CustomizedConfiguration { diff --git a/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/City.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/City.java new file mode 100644 index 000000000000..69ccf7d3851e --- /dev/null +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/City.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.cassandra.domain.city; + +import org.springframework.data.cassandra.core.mapping.CassandraType; +import org.springframework.data.cassandra.core.mapping.CassandraType.Name; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.PrimaryKey; +import org.springframework.data.cassandra.core.mapping.Table; + +@Table +public class City { + + @PrimaryKey + @CassandraType(type = Name.BIGINT) + private Long id; + + @Column + private String name; + + @Column + private String state; + + @Column + private String country; + + @Column + private String map; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCountry() { + return this.country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getMap() { + return this.map; + } + + public void setMap(String map) { + this.map = map; + } + +} diff --git a/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/CityRepository.java new file mode 100644 index 000000000000..76847b75e83c --- /dev/null +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/CityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.cassandra.domain.city; + +import org.springframework.data.repository.Repository; + +public interface CityRepository extends Repository { + +} diff --git a/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/ReactiveCityRepository.java new file mode 100644 index 000000000000..59a880b345fc --- /dev/null +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/city/ReactiveCityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.cassandra.domain.city; + +import org.springframework.data.repository.reactive.ReactiveCrudRepository; + +public interface ReactiveCityRepository extends ReactiveCrudRepository { + +} diff --git a/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/empty/EmptyDataPackage.java b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/empty/EmptyDataPackage.java new file mode 100644 index 000000000000..12e1bcb58e63 --- /dev/null +++ b/spring-boot-project/spring-boot-data-cassandra/src/test/java/org/springframework/boot/data/cassandra/domain/empty/EmptyDataPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.cassandra.domain.empty; + +public class EmptyDataPackage { + +} diff --git a/spring-boot-project/spring-boot-data-commons/build.gradle b/spring-boot-project/spring-boot-data-commons/build.gradle new file mode 100644 index 000000000000..43a71e89d168 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/build.gradle @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data Commons" + +dependencies { + api(project(":spring-boot-project:spring-boot-webmvc")) + api("org.springframework.data:spring-data-commons") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-metrics")) + + testImplementation(project(":spring-boot-project:spring-boot-jdbc")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("org.springframework.data:spring-data-jdbc") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") + testRuntimeOnly("jakarta.servlet:jakarta.servlet-api") +} diff --git a/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/DataMetricsProperties.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/DataMetricsProperties.java new file mode 100644 index 000000000000..8ec07e3e9006 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/DataMetricsProperties.java @@ -0,0 +1,106 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.autoconfigure.metrics; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * {@link ConfigurationProperties @ConfigurationProperties} for configuring + * Micrometer-based Spring Data metrics. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@ConfigurationProperties("management.metrics.data") +public class DataMetricsProperties { + + private final Repository repository = new Repository(); + + public Repository getRepository() { + return this.repository; + } + + public static class Repository { + + /** + * Name of the metric for sent requests. + */ + private String metricName = "spring.data.repository.invocations"; + + /** + * Auto-timed request settings. + */ + private final Autotime autotime = new Autotime(); + + public String getMetricName() { + return this.metricName; + } + + public void setMetricName(String metricName) { + this.metricName = metricName; + } + + public Autotime getAutotime() { + return this.autotime; + } + + public static class Autotime { + + /** + * Whether to enable auto-timing. + */ + private boolean enabled = true; + + /** + * Whether to publish percentile histograms. + */ + private boolean percentilesHistogram; + + /** + * Percentiles for which additional time series should be published. + */ + private double[] percentiles; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isPercentilesHistogram() { + return this.percentilesHistogram; + } + + public void setPercentilesHistogram(boolean percentilesHistogram) { + this.percentilesHistogram = percentilesHistogram; + } + + public double[] getPercentiles() { + return this.percentiles; + } + + public void setPercentiles(double[] percentiles) { + this.percentiles = percentiles; + } + + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/MetricsRepositoryMethodInvocationListenerBeanPostProcessor.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/MetricsRepositoryMethodInvocationListenerBeanPostProcessor.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/MetricsRepositoryMethodInvocationListenerBeanPostProcessor.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/MetricsRepositoryMethodInvocationListenerBeanPostProcessor.java index 13b5a864b75f..8c97ab22ff43 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/MetricsRepositoryMethodInvocationListenerBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/MetricsRepositoryMethodInvocationListenerBeanPostProcessor.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.data; +package org.springframework.boot.data.autoconfigure.metrics; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.actuate.metrics.data.MetricsRepositoryMethodInvocationListener; +import org.springframework.boot.data.metrics.MetricsRepositoryMethodInvocationListener; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactoryCustomizer; import org.springframework.data.repository.core.support.RepositoryFactorySupport; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesAutoTimer.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/PropertiesAutoTimer.java similarity index 79% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesAutoTimer.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/PropertiesAutoTimer.java index 47e869116c72..35deb5c23714 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesAutoTimer.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/PropertiesAutoTimer.java @@ -14,28 +14,29 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.data.autoconfigure.metrics; import io.micrometer.core.instrument.Timer.Builder; -import org.springframework.boot.actuate.metrics.AutoTimer; +import org.springframework.boot.data.autoconfigure.metrics.DataMetricsProperties.Repository.Autotime; +import org.springframework.boot.data.metrics.AutoTimer; /** - * {@link AutoTimer} whose behavior is configured by {@link AutoTimeProperties}. + * {@link AutoTimer} whose behavior is configured by {@link Autotime} properties. * * @author Andy Wilkinson - * @since 3.0.0 + * @since 4.0.0 */ public class PropertiesAutoTimer implements AutoTimer { - private final AutoTimeProperties properties; + private final Autotime properties; /** * Create a new {@link PropertiesAutoTimer} configured using the given * {@code properties}. * @param properties the properties to configure auto-timing */ - public PropertiesAutoTimer(AutoTimeProperties properties) { + public PropertiesAutoTimer(Autotime properties) { this.properties = properties; } diff --git a/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/SpringDataRepositoryMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/SpringDataRepositoryMetricsAutoConfiguration.java new file mode 100644 index 000000000000..1e81be890a76 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/SpringDataRepositoryMetricsAutoConfiguration.java @@ -0,0 +1,78 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.autoconfigure.metrics; + +import io.micrometer.core.instrument.MeterRegistry; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.data.autoconfigure.metrics.DataMetricsProperties.Repository; +import org.springframework.boot.data.metrics.DefaultRepositoryTagsProvider; +import org.springframework.boot.data.metrics.MetricsRepositoryMethodInvocationListener; +import org.springframework.boot.data.metrics.RepositoryTagsProvider; +import org.springframework.context.annotation.Bean; +import org.springframework.util.function.SingletonSupplier; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data Repository metrics. + * + * @author Phillip Webb + * @since 4.0.0 + */ +@AutoConfiguration( + afterName = { "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration", + "org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration", + "org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration" }) +@ConditionalOnClass(org.springframework.data.repository.Repository.class) +@ConditionalOnBean(MeterRegistry.class) +@EnableConfigurationProperties(DataMetricsProperties.class) +public class SpringDataRepositoryMetricsAutoConfiguration { + + private final DataMetricsProperties properties; + + public SpringDataRepositoryMetricsAutoConfiguration(DataMetricsProperties properties) { + this.properties = properties; + } + + @Bean + @ConditionalOnMissingBean(RepositoryTagsProvider.class) + public DefaultRepositoryTagsProvider repositoryTagsProvider() { + return new DefaultRepositoryTagsProvider(); + } + + @Bean + @ConditionalOnMissingBean + public MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocationListener( + ObjectProvider registry, RepositoryTagsProvider tagsProvider) { + Repository properties = this.properties.getRepository(); + return new MetricsRepositoryMethodInvocationListener(registry::getObject, tagsProvider, + properties.getMetricName(), new PropertiesAutoTimer(properties.getAutotime())); + } + + @Bean + public static MetricsRepositoryMethodInvocationListenerBeanPostProcessor metricsRepositoryMethodInvocationListenerBeanPostProcessor( + ObjectProvider metricsRepositoryMethodInvocationListener) { + return new MetricsRepositoryMethodInvocationListenerBeanPostProcessor( + SingletonSupplier.of(metricsRepositoryMethodInvocationListener::getObject)); + } + +} diff --git a/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..3796c20413c8 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data repository metrics. + */ +package org.springframework.boot.data.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfiguration.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/SpringDataWebAutoConfiguration.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfiguration.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/SpringDataWebAutoConfiguration.java index 81d275f50c7a..eecfbeb4ea89 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/SpringDataWebAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.web; +package org.springframework.boot.data.autoconfigure.web; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -22,9 +22,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.Pageable; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.data.autoconfigure.web.SpringDataWebProperties.Pageable; import org.springframework.context.annotation.Bean; import org.springframework.data.domain.PageRequest; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; @@ -44,9 +43,9 @@ * @author Andy Wilkinson * @author Vedran Pavic * @author Yanming Zhou - * @since 1.2.0 + * @since 4.0.0 */ -@AutoConfiguration(after = RepositoryRestMvcAutoConfiguration.class) +@AutoConfiguration @EnableSpringDataWebSupport @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ PageableHandlerMethodArgumentResolver.class, WebMvcConfigurer.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebProperties.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/SpringDataWebProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebProperties.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/SpringDataWebProperties.java index 146220c65101..6e7fa0e42622 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebProperties.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/SpringDataWebProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.web; +package org.springframework.boot.data.autoconfigure.web; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.data.web.config.EnableSpringDataWebSupport.PageSerializationMode; @@ -24,7 +24,7 @@ * * @author Vedran Pavic * @author Yanming Zhou - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.data.web") public class SpringDataWebProperties { diff --git a/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/package-info.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/package-info.java new file mode 100644 index 000000000000..34d846198ef1 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data web. + */ +package org.springframework.boot.data.autoconfigure.web; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/AutoTimer.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/AutoTimer.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/AutoTimer.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/AutoTimer.java index ac1ced1c3d93..ad0dd480e814 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/AutoTimer.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/AutoTimer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics; +package org.springframework.boot.data.metrics; import java.util.Set; import java.util.function.Consumer; @@ -33,7 +33,7 @@ * @author Tadaya Tsuyukubo * @author Stephane Nicoll * @author Phillip Webb - * @since 2.2.0 + * @since 4.0.0 */ @FunctionalInterface public interface AutoTimer { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/DefaultRepositoryTagsProvider.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/DefaultRepositoryTagsProvider.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/DefaultRepositoryTagsProvider.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/DefaultRepositoryTagsProvider.java index 6c1df3631e62..169f88fe4e05 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/DefaultRepositoryTagsProvider.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/DefaultRepositoryTagsProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.data; +package org.springframework.boot.data.metrics; import java.lang.reflect.Method; import java.util.function.Function; @@ -30,7 +30,7 @@ * Default {@link RepositoryTagsProvider} implementation. * * @author Phillip Webb - * @since 2.5.0 + * @since 4.0.0 */ public class DefaultRepositoryTagsProvider implements RepositoryTagsProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/MetricsRepositoryMethodInvocationListener.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/MetricsRepositoryMethodInvocationListener.java similarity index 92% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/MetricsRepositoryMethodInvocationListener.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/MetricsRepositoryMethodInvocationListener.java index 70305c3c150e..5b863b67af01 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/MetricsRepositoryMethodInvocationListener.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/MetricsRepositoryMethodInvocationListener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.data; +package org.springframework.boot.data.metrics; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -24,8 +24,6 @@ import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import org.springframework.boot.actuate.metrics.AutoTimer; -import org.springframework.boot.actuate.metrics.annotation.TimedAnnotations; import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener; import org.springframework.util.function.SingletonSupplier; @@ -34,7 +32,7 @@ * execution time and results. * * @author Phillip Webb - * @since 2.5.0 + * @since 4.0.0 */ public class MetricsRepositoryMethodInvocationListener implements RepositoryMethodInvocationListener { @@ -52,7 +50,7 @@ public class MetricsRepositoryMethodInvocationListener implements RepositoryMeth * @param tagsProvider provider for metrics tags * @param metricName name of the metric to record * @param autoTimer the auto-timers to apply or {@code null} to disable auto-timing - * @since 2.5.4 + * @since 4.0.0 */ public MetricsRepositoryMethodInvocationListener(Supplier registrySupplier, RepositoryTagsProvider tagsProvider, String metricName, AutoTimer autoTimer) { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/RepositoryTagsProvider.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/RepositoryTagsProvider.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/RepositoryTagsProvider.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/RepositoryTagsProvider.java index 9a169fd331c5..cc2552c78473 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/data/RepositoryTagsProvider.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/RepositoryTagsProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.data; +package org.springframework.boot.data.metrics; import io.micrometer.core.instrument.Tag; @@ -25,7 +25,7 @@ * invocations}. * * @author Phillip Webb - * @since 2.5.0 + * @since 4.0.0 */ @FunctionalInterface public interface RepositoryTagsProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/annotation/TimedAnnotations.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/TimedAnnotations.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/annotation/TimedAnnotations.java rename to spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/TimedAnnotations.java index 292a41994a78..24dc6e9d0c5b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/annotation/TimedAnnotations.java +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/TimedAnnotations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.annotation; +package org.springframework.boot.data.metrics; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; @@ -32,7 +32,7 @@ * Utility used to obtain {@link Timed @Timed} annotations from bean methods. * * @author Phillip Webb - * @since 2.5.0 + * @since 4.0.0 */ public final class TimedAnnotations { diff --git a/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/package-info.java b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/package-info.java new file mode 100644 index 000000000000..e2369bbe0ed8 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring Data repository metrics. + */ +package org.springframework.boot.data.metrics; diff --git a/spring-boot-project/spring-boot-data-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-data-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..a2d71bcb9b90 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.data.autoconfigure.metrics.SpringDataRepositoryMetricsAutoConfiguration +org.springframework.boot.data.autoconfigure.web.SpringDataWebAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests.java rename to spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests.java index 9454a4d2adc5..abc15448720e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests.java +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.data; +package org.springframework.boot.data.autoconfigure.metrics; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.actuate.metrics.data.MetricsRepositoryMethodInvocationListener; +import org.springframework.boot.data.metrics.MetricsRepositoryMethodInvocationListener; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactoryCustomizer; import org.springframework.data.repository.core.support.RepositoryFactorySupport; diff --git a/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/RepositoryMetricsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/RepositoryMetricsAutoConfigurationIntegrationTests.java new file mode 100644 index 000000000000..6bfd713a9956 --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/RepositoryMetricsAutoConfigurationIntegrationTests.java @@ -0,0 +1,98 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.autoconfigure.metrics; + +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.data.domain.city.City; +import org.springframework.boot.data.domain.city.CityRepository; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration; +import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link SpringDataRepositoryMetricsAutoConfiguration}. + * + * @author Phillip Webb + */ +@WithResource(name = "schema.sql", content = """ + CREATE TABLE CITY ( + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR(30), + country VARCHAR(30) + ); + """) +class RepositoryMetricsAutoConfigurationIntegrationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class) + .withConfiguration(AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class, + SpringDataRepositoryMetricsAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, + DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, + DataSourceInitializationAutoConfiguration.class)) + .withUserConfiguration(TestConfig.class); + + @Test + void repositoryMethodCallRecordsMetrics() { + this.contextRunner.run((context) -> { + context.getBean(CityRepository.class).count(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry.get("spring.data.repository.invocations") + .tag("repository", "CityRepository") + .timer() + .count()).isOne(); + }); + } + + @Test + void doesNotPreventMeterBindersFromDependingUponSpringDataRepositories() { + this.contextRunner.withUserConfiguration(SpringDataRepositoryMeterBinderConfiguration.class) + .run((context) -> assertThat(context).hasNotFailed()); + } + + @Configuration(proxyBeanMethods = false) + @EnableJdbcRepositories(basePackageClasses = City.class) + static class TestConfig extends AbstractJdbcConfiguration { + + } + + @Configuration(proxyBeanMethods = false) + static class SpringDataRepositoryMeterBinderConfiguration { + + @Bean + MeterBinder meterBinder(CityRepository repository) { + return (registry) -> Gauge.builder("city.count", repository::count); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/RepositoryMetricsAutoConfigurationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/RepositoryMetricsAutoConfigurationTests.java index f423b367b8e0..b1cc4eb9a435 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/RepositoryMetricsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.data; +package org.springframework.boot.data.autoconfigure.metrics; import java.util.Collection; import java.util.Collections; @@ -27,15 +27,16 @@ import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.distribution.HistogramSnapshot; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectFactory; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.metrics.AutoTimer; -import org.springframework.boot.actuate.metrics.data.DefaultRepositoryTagsProvider; -import org.springframework.boot.actuate.metrics.data.MetricsRepositoryMethodInvocationListener; -import org.springframework.boot.actuate.metrics.data.RepositoryTagsProvider; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.data.metrics.AutoTimer; +import org.springframework.boot.data.metrics.DefaultRepositoryTagsProvider; +import org.springframework.boot.data.metrics.MetricsRepositoryMethodInvocationListener; +import org.springframework.boot.data.metrics.RepositoryTagsProvider; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -51,19 +52,22 @@ import static org.mockito.Mockito.mock; /** - * Tests for {@link RepositoryMetricsAutoConfiguration}. + * Tests for {@link SpringDataRepositoryMetricsAutoConfiguration}. * * @author Phillip Webb */ class RepositoryMetricsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(RepositoryMetricsAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class) + .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, + SpringDataRepositoryMetricsAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=false"); @Test void backsOffWhenMeterRegistryIsMissing() { new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RepositoryMetricsAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(SpringDataRepositoryMetricsAutoConfiguration.class)) .run((context) -> assertThat(context).doesNotHaveBean(RepositoryTagsProvider.class)); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/web/SpringDataWebAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/web/SpringDataWebAutoConfigurationTests.java index c8b46e05e1f3..f0dd47a10eb5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/web/SpringDataWebAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/autoconfigure/metrics/web/SpringDataWebAutoConfigurationTests.java @@ -14,11 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.web; +package org.springframework.boot.data.autoconfigure.metrics.web; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.data.autoconfigure.web.SpringDataWebAutoConfiguration; +import org.springframework.boot.data.autoconfigure.web.SpringDataWebProperties; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.data.domain.PageRequest; diff --git a/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/domain/city/City.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/domain/city/City.java new file mode 100644 index 000000000000..9e248ee4c57c --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/domain/city/City.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.domain.city; + +import org.springframework.data.annotation.Id; + +public class City { + + @Id + private Long id; + + private String name; + + private String country; + + public City(String name, String country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getCountry() { + return this.country; + } + + @Override + public String toString() { + return getName() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/domain/city/CityRepository.java new file mode 100644 index 000000000000..f4d6fcf8024a --- /dev/null +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/domain/city/CityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.domain.city; + +import org.springframework.data.repository.CrudRepository; + +public interface CityRepository extends CrudRepository { + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/data/DefaultRepositoryTagsProviderTests.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/DefaultRepositoryTagsProviderTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/data/DefaultRepositoryTagsProviderTests.java rename to spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/DefaultRepositoryTagsProviderTests.java index c9c863156163..ef760887c132 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/data/DefaultRepositoryTagsProviderTests.java +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/DefaultRepositoryTagsProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.data; +package org.springframework.boot.data.metrics; import java.io.IOException; import java.lang.reflect.Method; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/data/MetricsRepositoryMethodInvocationListenerTests.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/MetricsRepositoryMethodInvocationListenerTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/data/MetricsRepositoryMethodInvocationListenerTests.java rename to spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/MetricsRepositoryMethodInvocationListenerTests.java index 9de32d843cec..bef84137f838 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/data/MetricsRepositoryMethodInvocationListenerTests.java +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/MetricsRepositoryMethodInvocationListenerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.data; +package org.springframework.boot.data.metrics; import java.lang.reflect.Method; @@ -25,7 +25,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.metrics.AutoTimer; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocation; import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocationResult; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/annotation/TimedAnnotationsTests.java b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/TimedAnnotationsTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/annotation/TimedAnnotationsTests.java rename to spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/TimedAnnotationsTests.java index 924625065a15..ad0252affe1b 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/annotation/TimedAnnotationsTests.java +++ b/spring-boot-project/spring-boot-data-commons/src/test/java/org/springframework/boot/data/metrics/TimedAnnotationsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.annotation; +package org.springframework.boot.data.metrics; import java.lang.reflect.Method; import java.util.Set; diff --git a/spring-boot-project/spring-boot-data-couchbase/build.gradle b/spring-boot-project/spring-boot-data-couchbase/build.gradle new file mode 100644 index 000000000000..85bb8cb42d96 --- /dev/null +++ b/spring-boot-project/spring-boot-data-couchbase/build.gradle @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data Couchbase" + +dependencies { + api(project(":spring-boot-project:spring-boot-couchbase")) + api(project(":spring-boot-project:spring-boot-data-commons")) + api("org.springframework.data:spring-data-couchbase") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-reactor")) + optional(project(":spring-boot-project:spring-boot-validation")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseClientFactoryConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseClientFactoryConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseClientFactoryConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseClientFactoryConfiguration.java index 321df5e536bf..14d7910a6494 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseClientFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseClientFactoryConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import com.couchbase.client.java.Cluster; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseClientFactoryDependentConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseClientFactoryDependentConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseClientFactoryDependentConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseClientFactoryDependentConfiguration.java index a32a079c6d46..b589343fef99 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseClientFactoryDependentConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseClientFactoryDependentConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataAutoConfiguration.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataAutoConfiguration.java index 57c654093dff..0fac77b9a44e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import com.couchbase.client.java.Bucket; import jakarta.validation.Validator; @@ -23,9 +23,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -37,9 +36,10 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.4.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { CouchbaseAutoConfiguration.class, ValidationAutoConfiguration.class }) +@AutoConfiguration(after = CouchbaseAutoConfiguration.class, + afterName = "org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration") @ConditionalOnClass({ Bucket.class, CouchbaseRepository.class }) @EnableConfigurationProperties(CouchbaseDataProperties.class) @Import({ CouchbaseDataConfiguration.class, CouchbaseClientFactoryConfiguration.class, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataConfiguration.java index 5e57358e02cc..f805e319ca9c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataProperties.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataProperties.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataProperties.java index 5df99281c989..902268edbbb9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataProperties.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -22,7 +22,7 @@ * Configuration properties for Spring Data Couchbase. * * @author Stephane Nicoll - * @since 1.4.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.data.couchbase") public class CouchbaseDataProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataAutoConfiguration.java index 0ab5fa6d1c43..d63ae0ec5719 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import com.couchbase.client.java.Cluster; import reactor.core.publisher.Flux; @@ -30,7 +30,7 @@ * support. * * @author Alex Derkach - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = CouchbaseDataAutoConfiguration.class) @ConditionalOnClass({ Cluster.class, ReactiveCouchbaseRepository.class, Flux.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataConfiguration.java index 764893cddd52..ee71d09b25be 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesAutoConfiguration.java index d930dd0cd07e..02298fc5e13c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import com.couchbase.client.java.Cluster; import reactor.core.publisher.Flux; @@ -36,7 +36,7 @@ * Repositories. * * @author Alex Derkach - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = CouchbaseReactiveDataAutoConfiguration.class) @ConditionalOnClass({ Cluster.class, ReactiveCouchbaseRepository.class, Flux.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesRegistrar.java index 196de0eb32c5..691030e547ed 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesAutoConfiguration.java index deff69d72fe3..a1bf876e032d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import com.couchbase.client.java.Bucket; @@ -36,7 +36,7 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.4.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ Bucket.class, CouchbaseRepository.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesRegistrar.java index c2aaca7cb89c..60f9c69566f5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/package-info.java new file mode 100644 index 000000000000..6ef3ebeb77a8 --- /dev/null +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/java/org/springframework/boot/data/couchbase/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data Couchbase. + */ +package org.springframework.boot.data.couchbase.autoconfigure; diff --git a/spring-boot-project/spring-boot-data-couchbase/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-couchbase/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..a84e0a3a9c6c --- /dev/null +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,18 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.data.couchbase.consistency", + "type": "org.springframework.data.couchbase.core.query.Consistency", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.couchbase.repositories.type", + "type": "org.springframework.boot.autoconfigure.data.RepositoryType", + "description": "Type of Couchbase repositories to enable.", + "defaultValue": "auto" + } + ] +} diff --git a/spring-boot-project/spring-boot-data-couchbase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-couchbase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..8528d4935265 --- /dev/null +++ b/spring-boot-project/spring-boot-data-couchbase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.data.couchbase.autoconfigure.CouchbaseDataAutoConfiguration +org.springframework.boot.data.couchbase.autoconfigure.CouchbaseReactiveDataAutoConfiguration +org.springframework.boot.data.couchbase.autoconfigure.CouchbaseReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.couchbase.autoconfigure.CouchbaseRepositoriesAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataAutoConfigurationTests.java index 34b06af738fb..5d1446108388 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataAutoConfigurationTests.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import java.util.Collections; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties; -import org.springframework.boot.autoconfigure.data.couchbase.city.City; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseProperties; +import org.springframework.boot.data.couchbase.domain.city.City; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -110,7 +110,7 @@ CouchbaseCustomConversions myCustomConversions() { } @Configuration(proxyBeanMethods = false) - @EntityScan("org.springframework.boot.autoconfigure.data.couchbase.city") + @EntityScan(basePackageClasses = City.class) @Import(CouchbaseMockConfiguration.class) static class EntityScanConfig { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataPropertiesTests.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataPropertiesTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataPropertiesTests.java rename to spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataPropertiesTests.java index 8a44ddbe1dc1..8b3459670534 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseDataPropertiesTests.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseDataPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseMockConfiguration.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseMockConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseMockConfiguration.java rename to spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseMockConfiguration.java index c1a8519b6985..d50f01d6d48c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseMockConfiguration.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseMockConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveAndImperativeRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveAndImperativeRepositoriesAutoConfigurationTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveAndImperativeRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveAndImperativeRepositoriesAutoConfigurationTests.java index 8e2438ed030e..e3afca1a81ef 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveAndImperativeRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveAndImperativeRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import java.util.ArrayList; import java.util.List; @@ -22,9 +22,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; -import org.springframework.boot.autoconfigure.data.couchbase.city.CityRepository; -import org.springframework.boot.autoconfigure.data.couchbase.city.ReactiveCityRepository; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; +import org.springframework.boot.data.couchbase.domain.city.CityRepository; +import org.springframework.boot.data.couchbase.domain.city.ReactiveCityRepository; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataAutoConfigurationTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataAutoConfigurationTests.java index 52297aeafb8e..0fe0c39ef37f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveDataAutoConfigurationTests.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import java.util.Collections; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties; -import org.springframework.boot.autoconfigure.data.couchbase.city.City; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseProperties; +import org.springframework.boot.data.couchbase.domain.city.City; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -94,7 +94,7 @@ CouchbaseCustomConversions myCustomConversions() { } @Configuration(proxyBeanMethods = false) - @EntityScan("org.springframework.boot.autoconfigure.data.couchbase.city") + @EntityScan(basePackageClasses = City.class) @Import(CouchbaseMockConfiguration.class) static class EntityScanConfig { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesAutoConfigurationTests.java similarity index 84% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesAutoConfigurationTests.java index d866c829cf30..0115376064f4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseReactiveRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseReactiveRepositoriesAutoConfigurationTests.java @@ -14,18 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; -import org.springframework.boot.autoconfigure.data.alt.couchbase.CityCouchbaseRepository; -import org.springframework.boot.autoconfigure.data.alt.couchbase.ReactiveCityCouchbaseRepository; -import org.springframework.boot.autoconfigure.data.couchbase.city.City; -import org.springframework.boot.autoconfigure.data.couchbase.city.ReactiveCityRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; +import org.springframework.boot.data.couchbase.domain.city.City; +import org.springframework.boot.data.couchbase.domain.city.CityRepository; +import org.springframework.boot.data.couchbase.domain.city.ReactiveCityRepository; +import org.springframework.boot.data.couchbase.domain.empty.EmptyDataPackage; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -80,7 +79,7 @@ void noRepositoryAvailable() { @Test void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { this.contextRunner.withUserConfiguration(CustomizedConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(ReactiveCityCouchbaseRepository.class)); + .run((context) -> assertThat(context).doesNotHaveBean(ReactiveCityRepository.class)); } @Configuration(proxyBeanMethods = false) @@ -99,7 +98,7 @@ static class NoRepositoryConfiguration { @Configuration(proxyBeanMethods = false) @TestAutoConfigurationPackage(CouchbaseReactiveRepositoriesAutoConfigurationTests.class) - @EnableCouchbaseRepositories(basePackageClasses = CityCouchbaseRepository.class) + @EnableCouchbaseRepositories(basePackageClasses = CityRepository.class) @Import(CouchbaseMockConfiguration.class) static class CustomizedConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesAutoConfigurationTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesAutoConfigurationTests.java index f58290457ec2..a1ac6d0af5b9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/couchbase/CouchbaseRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/autoconfigure/CouchbaseRepositoriesAutoConfigurationTests.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.couchbase; +package org.springframework.boot.data.couchbase.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration; -import org.springframework.boot.autoconfigure.data.couchbase.city.City; -import org.springframework.boot.autoconfigure.data.couchbase.city.CityRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; +import org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration; +import org.springframework.boot.data.couchbase.domain.city.City; +import org.springframework.boot.data.couchbase.domain.city.CityRepository; +import org.springframework.boot.data.couchbase.domain.empty.EmptyDataPackage; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/City.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/City.java new file mode 100644 index 000000000000..cf1f05e7f236 --- /dev/null +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/City.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.couchbase.domain.city; + +import org.springframework.data.annotation.Id; +import org.springframework.data.couchbase.core.mapping.Document; +import org.springframework.data.couchbase.core.mapping.Field; + +@Document +public class City { + + @Id + private String id; + + @Field + private String name; + +} diff --git a/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/CityRepository.java new file mode 100644 index 000000000000..a8126dca217f --- /dev/null +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/CityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.couchbase.domain.city; + +import org.springframework.data.repository.Repository; + +public interface CityRepository extends Repository { + +} diff --git a/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/ReactiveCityRepository.java new file mode 100644 index 000000000000..f5b1694efba3 --- /dev/null +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/city/ReactiveCityRepository.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.couchbase.domain.city; + +import reactor.core.publisher.Mono; + +import org.springframework.data.repository.Repository; + +public interface ReactiveCityRepository extends Repository { + + Mono save(City city); + + Mono findById(Long id); + +} diff --git a/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/empty/EmptyDataPackage.java b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/empty/EmptyDataPackage.java new file mode 100644 index 000000000000..1ec262fc6f74 --- /dev/null +++ b/spring-boot-project/spring-boot-data-couchbase/src/test/java/org/springframework/boot/data/couchbase/domain/empty/EmptyDataPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.couchbase.domain.empty; + +public class EmptyDataPackage { + +} diff --git a/spring-boot-project/spring-boot-data-elasticsearch/build.gradle b/spring-boot-project/spring-boot-data-elasticsearch/build.gradle new file mode 100644 index 000000000000..2d662f9a2361 --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/build.gradle @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data Elasticsearch" + +dependencies { + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-elasticsearch")) + api("org.springframework.data:spring-data-elasticsearch") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-reactor")) + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + dockerTestImplementation("ch.qos.logback:logback-classic") + dockerTestImplementation("org.junit.jupiter:junit-jupiter") + dockerTestImplementation("org.testcontainers:elasticsearch") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("com.squareup.okhttp3:mockwebserver") + testImplementation("org.springframework:spring-web") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesAutoConfigurationTests.java new file mode 100644 index 000000000000..b01671ab0778 --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesAutoConfigurationTests.java @@ -0,0 +1,126 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.elasticsearch.autoconfigure; + +import org.junit.jupiter.api.Test; +import org.testcontainers.elasticsearch.ElasticsearchContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; +import org.springframework.boot.data.elasticsearch.domain.city.City; +import org.springframework.boot.data.elasticsearch.domain.city.ReactiveCityRepository; +import org.springframework.boot.data.elasticsearch.domain.empty.EmptyDataPackage; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchReactiveClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchTemplate; +import org.springframework.data.elasticsearch.config.EnableElasticsearchAuditing; +import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ElasticsearchReactiveRepositoriesAutoConfiguration}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Brian Clozel + * @author Scott Frederick + */ +@Testcontainers(disabledWithoutDocker = true) +class ElasticsearchReactiveRepositoriesAutoConfigurationTests { + + @Container + static final ElasticsearchContainer elasticsearch = TestImage.container(ElasticsearchContainer.class); + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ElasticsearchClientAutoConfiguration.class, + ElasticsearchRestClientAutoConfiguration.class, + ElasticsearchReactiveRepositoriesAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, + ElasticsearchReactiveClientAutoConfiguration.class)) + .withPropertyValues( + "spring.elasticsearch.uris=" + elasticsearch.getHost() + ":" + elasticsearch.getFirstMappedPort(), + "spring.elasticsearch.socket-timeout=30s"); + + @Test + void backsOffWithoutReactor() { + this.contextRunner.withUserConfiguration(TestConfiguration.class) + .withClassLoader(new FilteredClassLoader(Mono.class)) + .run((context) -> assertThat(context) + .doesNotHaveBean(ElasticsearchReactiveRepositoriesAutoConfiguration.class)); + } + + @Test + void testDefaultRepositoryConfiguration() { + this.contextRunner.withUserConfiguration(TestConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ReactiveCityRepository.class) + .hasSingleBean(ReactiveElasticsearchTemplate.class)); + } + + @Test + void testNoRepositoryConfiguration() { + this.contextRunner.withUserConfiguration(EmptyConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchTemplate.class)); + } + + @Test + void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { + this.contextRunner.withUserConfiguration(CustomizedConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ReactiveCityRepository.class)); + } + + @Test + void testAuditingConfiguration() { + this.contextRunner.withUserConfiguration(AuditingConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchTemplate.class)); + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + static class TestConfiguration { + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(EmptyDataPackage.class) + static class EmptyConfiguration { + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + @EnableReactiveElasticsearchRepositories(basePackageClasses = ReactiveCityRepository.class) + static class CustomizedConfiguration { + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + @EnableReactiveElasticsearchRepositories + @EnableElasticsearchAuditing + static class AuditingConfiguration { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesAutoConfigurationTests.java similarity index 80% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesAutoConfigurationTests.java index 1fb4543a5992..2e9e12d3b7d3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.autoconfigure; import org.junit.jupiter.api.Test; import org.testcontainers.elasticsearch.ElasticsearchContainer; @@ -23,12 +23,11 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.alt.elasticsearch.CityElasticsearchDbRepository; -import org.springframework.boot.autoconfigure.data.elasticsearch.city.City; -import org.springframework.boot.autoconfigure.data.elasticsearch.city.CityRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.data.elasticsearch.domain.city.City; +import org.springframework.boot.data.elasticsearch.domain.city.CityRepository; +import org.springframework.boot.data.elasticsearch.domain.empty.EmptyDataPackage; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; @@ -74,7 +73,7 @@ void testNoRepositoryConfiguration() { @Test void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { this.contextRunner.withUserConfiguration(CustomizedConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(CityElasticsearchDbRepository.class)); + .run((context) -> assertThat(context).hasSingleBean(CityRepository.class)); } @Test @@ -96,14 +95,14 @@ static class EmptyConfiguration { } @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(ElasticsearchRepositoriesAutoConfigurationTests.class) - @EnableElasticsearchRepositories(basePackageClasses = CityElasticsearchDbRepository.class) + @TestAutoConfigurationPackage(City.class) + @EnableElasticsearchRepositories(basePackageClasses = CityRepository.class) static class CustomizedConfiguration { } @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(ElasticsearchRepositoriesAutoConfigurationTests.class) + @TestAutoConfigurationPackage(City.class) @EnableElasticsearchRepositories @EnableElasticsearchAuditing static class AuditingConfiguration { diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/domain/empty/EmptyDataPackage.java b/spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/domain/empty/EmptyDataPackage.java new file mode 100644 index 000000000000..a034dc949c06 --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/dockerTest/java/org/springframework/boot/data/elasticsearch/domain/empty/EmptyDataPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.elasticsearch.domain.empty; + +public class EmptyDataPackage { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataAutoConfiguration.java index ddf727c069e8..3ab3c4a63b79 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataAutoConfiguration.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.autoconfigure; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchReactiveClientAutoConfiguration; import org.springframework.context.annotation.Import; import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -33,12 +33,12 @@ * @author Brian Clozel * @author Artur Konczak * @author Mohsin Husen - * @since 1.1.0 + * @since 4.0.0 * @see EnableElasticsearchRepositories * @see EnableReactiveElasticsearchRepositories */ @AutoConfiguration( - after = { ElasticsearchClientAutoConfiguration.class, ReactiveElasticsearchClientAutoConfiguration.class }) + after = { ElasticsearchClientAutoConfiguration.class, ElasticsearchReactiveClientAutoConfiguration.class }) @ConditionalOnClass({ ElasticsearchTemplate.class }) @Import({ ElasticsearchDataConfiguration.BaseConfiguration.class, ElasticsearchDataConfiguration.JavaClientConfiguration.class, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataConfiguration.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataConfiguration.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataConfiguration.java index f7029ce82b41..57d789af979b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataConfiguration.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.autoconfigure; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesAutoConfiguration.java new file mode 100644 index 000000000000..81f463bcf0f3 --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesAutoConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.elasticsearch.autoconfigure; + +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; +import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; +import org.springframework.data.elasticsearch.repository.support.ReactiveElasticsearchRepositoryFactoryBean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Elasticsearch + * Reactive Repositories. + * + * @author Brian Clozel + * @since 4.0.0 + * @see EnableReactiveElasticsearchRepositories + */ +@AutoConfiguration +@ConditionalOnClass({ ReactiveElasticsearchClient.class, ReactiveElasticsearchRepository.class, Mono.class }) +@ConditionalOnBooleanProperty(name = "spring.data.elasticsearch.repositories.enabled", matchIfMissing = true) +@ConditionalOnMissingBean(ReactiveElasticsearchRepositoryFactoryBean.class) +@Import(ElasticsearchReactiveRepositoriesRegistrar.class) +public class ElasticsearchReactiveRepositoriesAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesRegistrar.java new file mode 100644 index 000000000000..d70821f32384 --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchReactiveRepositoriesRegistrar.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.elasticsearch.autoconfigure; + +import java.lang.annotation.Annotation; + +import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; +import org.springframework.data.elasticsearch.repository.config.ReactiveElasticsearchRepositoryConfigurationExtension; +import org.springframework.data.repository.config.RepositoryConfigurationExtension; + +/** + * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Elasticsearch + * Reactive Repositories. + * + * @author Brian Clozel + */ +class ElasticsearchReactiveRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport { + + @Override + protected Class getAnnotation() { + return EnableReactiveElasticsearchRepositories.class; + } + + @Override + protected Class getConfiguration() { + return EnableElasticsearchRepositoriesConfiguration.class; + } + + @Override + protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() { + return new ReactiveElasticsearchRepositoryConfigurationExtension(); + } + + @EnableReactiveElasticsearchRepositories + private static final class EnableElasticsearchRepositoriesConfiguration { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesAutoConfiguration.java index 6f983d20e808..c9da938d38ab 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.autoconfigure; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -32,7 +32,7 @@ * * @author Artur Konczak * @author Mohsin Husen - * @since 1.1.0 + * @since 4.0.0 * @see EnableElasticsearchRepositories */ @AutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesRegistrar.java index 7bbaa80bf1ab..3c91b474014b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/ElasticsearchReactiveHealthContributorAutoConfiguration.java similarity index 75% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/ElasticsearchReactiveHealthContributorAutoConfiguration.java index 98e8c979b16e..eb9362b6fa1a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/ElasticsearchReactiveHealthContributorAutoConfiguration.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.autoconfigure.health; import reactor.core.publisher.Flux; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.data.elasticsearch.ElasticsearchReactiveHealthIndicator; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration; +import org.springframework.boot.data.elasticsearch.health.ElasticsearchReactiveHealthIndicator; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchReactiveClientAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; import org.springframework.context.annotation.Bean; import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; @@ -38,10 +38,11 @@ * {@link ReactiveElasticsearchClient}. * * @author Aleksander Lech - * @since 2.3.2 + * @since 4.0.0 */ -@AutoConfiguration(after = ReactiveElasticsearchClientAutoConfiguration.class) -@ConditionalOnClass({ ReactiveElasticsearchClient.class, Flux.class }) +@AutoConfiguration(after = ElasticsearchReactiveClientAutoConfiguration.class) +@ConditionalOnClass({ ReactiveElasticsearchClient.class, Flux.class, ElasticsearchReactiveHealthIndicator.class, + ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(ReactiveElasticsearchClient.class) @ConditionalOnEnabledHealthIndicator("elasticsearch") public class ElasticsearchReactiveHealthContributorAutoConfiguration extends diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..ca55959d0173 --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data Elasticsearch health. + */ +package org.springframework.boot.data.elasticsearch.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/package-info.java new file mode 100644 index 000000000000..3e8a1e29ab6e --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data Elasticsearch. + */ +package org.springframework.boot.data.elasticsearch.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/elasticsearch/ElasticsearchReactiveHealthIndicator.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/health/ElasticsearchReactiveHealthIndicator.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/elasticsearch/ElasticsearchReactiveHealthIndicator.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/health/ElasticsearchReactiveHealthIndicator.java index f4ab933a0177..d5a2c41695ea 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/elasticsearch/ElasticsearchReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/health/ElasticsearchReactiveHealthIndicator.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.actuate.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.health; import co.elastic.clients.elasticsearch._types.HealthStatus; import co.elastic.clients.elasticsearch.cluster.HealthResponse; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; /** @@ -33,7 +33,7 @@ * @author Brian Clozel * @author Aleksander Lech * @author Scott Frederick - * @since 2.3.2 + * @since 4.0.0 */ public class ElasticsearchReactiveHealthIndicator extends AbstractReactiveHealthIndicator { diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/health/package-info.java b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/health/package-info.java new file mode 100644 index 000000000000..baeb5f437b8c --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/java/org/springframework/boot/data/elasticsearch/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Elasticsearch health integration using Spring Data Elasticsearch. + */ +package org.springframework.boot.data.elasticsearch.health; diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-elasticsearch/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..d170e6cb003d --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,35 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.data.elasticsearch.cluster-name", + "type": "java.lang.String", + "description": "Elasticsearch cluster name.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.elasticsearch.cluster-nodes", + "type": "java.lang.String", + "description": "Comma-separated list of cluster node addresses.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.elasticsearch.properties", + "type": "java.util.Map", + "description": "Additional properties used to configure the client.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.elasticsearch.repositories.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Elasticsearch repositories.", + "defaultValue": true + } + ] +} diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..fe06cff203db --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchDataAutoConfiguration +org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchRepositoriesAutoConfiguration +org.springframework.boot.data.elasticsearch.autoconfigure.health.ElasticsearchReactiveHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataAutoConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataAutoConfigurationTests.java index 43eafb1ca6af..e07aaf29bdf1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/autoconfigure/ElasticsearchDataAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.autoconfigure; import java.math.BigDecimal; import java.util.Collections; @@ -24,10 +24,10 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.elasticsearch.city.City; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration; +import org.springframework.boot.data.elasticsearch.domain.city.City; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchReactiveClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -57,7 +57,7 @@ class ElasticsearchDataAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class, ElasticsearchClientAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, - ReactiveElasticsearchClientAutoConfiguration.class)); + ElasticsearchReactiveClientAutoConfiguration.class)); @Test void defaultRestBeansRegistered() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java similarity index 75% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java index 38b946003279..3b972f055fb7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/autoconfigure/health/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.data.elasticsearch; +package org.springframework.boot.data.elasticsearch.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticsearchRestHealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.data.elasticsearch.ElasticsearchReactiveHealthIndicator; -import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration; +import org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchDataAutoConfiguration; +import org.springframework.boot.data.elasticsearch.health.ElasticsearchReactiveHealthIndicator; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchReactiveClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.health.ElasticsearchRestHealthContributorAutoConfiguration; +import org.springframework.boot.elasticsearch.health.ElasticsearchRestClientHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -39,7 +39,7 @@ class ElasticsearchReactiveHealthContributorAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(ElasticsearchDataAutoConfiguration.class, - ReactiveElasticsearchClientAutoConfiguration.class, ElasticsearchRestClientAutoConfiguration.class, + ElasticsearchReactiveClientAutoConfiguration.class, ElasticsearchRestClientAutoConfiguration.class, ElasticsearchReactiveHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class)); diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/City.java b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/City.java new file mode 100644 index 000000000000..cbce6806c292 --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/City.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.elasticsearch.domain.city; + +import java.io.Serializable; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Setting; + +@Document(indexName = "city") +@Setting(shards = 1, replicas = 0, refreshInterval = "-1") +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + private Long id; + + private String name; + + private String state; + + private String country; + + private String map; + + protected City() { + } + + public City(String name, String country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/CityRepository.java new file mode 100644 index 000000000000..e84d746c527d --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/CityRepository.java @@ -0,0 +1,31 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.elasticsearch.domain.city; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.Repository; + +public interface CityRepository extends Repository { + + Page findAll(Pageable pageable); + + Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); + + City findByNameAndCountryAllIgnoringCase(String name, String country); + +} diff --git a/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/ReactiveCityRepository.java new file mode 100644 index 000000000000..17b6db207acd --- /dev/null +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/domain/city/ReactiveCityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.elasticsearch.domain.city; + +import org.springframework.data.repository.reactive.ReactiveCrudRepository; + +public interface ReactiveCityRepository extends ReactiveCrudRepository { + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/health/ElasticsearchReactiveHealthIndicatorTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java rename to spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/health/ElasticsearchReactiveHealthIndicatorTests.java index b833836195f5..4c736a1b1d5a 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-data-elasticsearch/src/test/java/org/springframework/boot/data/elasticsearch/health/ElasticsearchReactiveHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.elasticsearch; +package org.springframework.boot.data.elasticsearch.health; import java.time.Duration; import java.util.Map; @@ -30,9 +30,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.data.elasticsearch.ElasticsearchReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; diff --git a/spring-boot-project/spring-boot-data-jdbc/build.gradle b/spring-boot-project/spring-boot-data-jdbc/build.gradle new file mode 100644 index 000000000000..b6bdb7711e24 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jdbc/build.gradle @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data JDBC" + +dependencies { + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-jdbc")) + api("org.springframework.data:spring-data-jdbc") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcDataProperties.java b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcDataProperties.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcDataProperties.java rename to spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcDataProperties.java index ad7898180c65..929b34a3c7c3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcDataProperties.java +++ b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcDataProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jdbc; +package org.springframework.boot.data.jdbc.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -22,7 +22,7 @@ * Configuration properties for Spring Data JDBC. * * @author Jens Schauder - * @since 3.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.data.jdbc") public class JdbcDataProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcDatabaseDialect.java b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcDatabaseDialect.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcDatabaseDialect.java rename to spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcDatabaseDialect.java index 5ae6ab5755a9..bd68be0481f2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcDatabaseDialect.java +++ b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcDatabaseDialect.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jdbc; +package org.springframework.boot.data.jdbc.autoconfigure; import org.springframework.data.jdbc.core.dialect.JdbcDb2Dialect; import org.springframework.data.jdbc.core.dialect.JdbcH2Dialect; @@ -29,7 +29,7 @@ * List of database dialects that can be configured in Boot for use with Spring Data JDBC. * * @author Jens Schauder - * @since 3.3.0 + * @since 4.0.0 */ public enum JdbcDatabaseDialect { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesAutoConfiguration.java index c758d9452105..b94afaacf086 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jdbc; +package org.springframework.boot.data.jdbc.autoconfigure; import java.util.Optional; import java.util.Set; @@ -26,9 +26,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.domain.EntityScanner; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -61,7 +61,7 @@ * @author Stephane Nicoll * @author Mark Paluch * @author Jens Schauder - * @since 2.1.0 + * @since 4.0.0 * @see EnableJdbcRepositories */ @AutoConfiguration(after = { JdbcTemplateAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesRegistrar.java index 747adbc44042..03811a1b7a31 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jdbc; +package org.springframework.boot.data.jdbc.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/package-info.java new file mode 100644 index 000000000000..7b1d59261625 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jdbc/src/main/java/org/springframework/boot/data/jdbc/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data JDBC. + */ +package org.springframework.boot.data.jdbc.autoconfigure; diff --git a/spring-boot-project/spring-boot-data-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..5fcc8f848069 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,11 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.data.jdbc.repositories.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable JDBC repositories.", + "defaultValue": true + } + ] +} diff --git a/spring-boot-project/spring-boot-data-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..8594a630c365 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.data.jdbc.autoconfigure.JdbcRepositoriesAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesAutoConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesAutoConfigurationTests.java index 8179c68d00e4..6f6a1c25b088 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/autoconfigure/JdbcRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jdbc; +package org.springframework.boot.data.jdbc.autoconfigure; import java.util.function.Function; @@ -25,13 +25,13 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.data.jdbc.city.City; -import org.springframework.boot.autoconfigure.data.jdbc.city.CityRepository; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; +import org.springframework.boot.data.jdbc.domain.city.City; +import org.springframework.boot.data.jdbc.domain.city.CityRepository; +import org.springframework.boot.data.jdbc.domain.empty.EmptyDataPackage; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.context.annotation.Bean; @@ -218,8 +218,8 @@ private void allowsUserToDefineCustomBean(Class configuration, Class beanT private Function database() { return (runner) -> runner - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class, SqlInitializationAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + DataSourceInitializationAutoConfiguration.class)) .withPropertyValues("spring.sql.init.schema-locations=classpath:schema.sql", "spring.sql.init.data-locations=classpath:data.sql", "spring.datasource.generate-unique-name:true"); } diff --git a/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/city/City.java b/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/city/City.java new file mode 100644 index 000000000000..07a33df81916 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/city/City.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.jdbc.domain.city; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Table; + +@Table("CITY") +public class City { + + @Id + private Long id; + + private String name; + + private String state; + + private String country; + + private String map; + + protected City() { + } + + public City(String name, String country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/city/CityRepository.java new file mode 100644 index 000000000000..c1d1432c436d --- /dev/null +++ b/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/city/CityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.jdbc.domain.city; + +import org.springframework.data.repository.CrudRepository; + +public interface CityRepository extends CrudRepository { + +} diff --git a/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/empty/EmptyDataPackage.java b/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/empty/EmptyDataPackage.java new file mode 100644 index 000000000000..16e3c900bd3e --- /dev/null +++ b/spring-boot-project/spring-boot-data-jdbc/src/test/java/org/springframework/boot/data/jdbc/domain/empty/EmptyDataPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.jdbc.domain.empty; + +public class EmptyDataPackage { + +} diff --git a/spring-boot-project/spring-boot-data-jpa/build.gradle b/spring-boot-project/spring-boot-data-jpa/build.gradle new file mode 100644 index 000000000000..bb1e41941f6a --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/build.gradle @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data JPA" + +dependencies { + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-hibernate")) + api("org.springframework.data:spring-data-jpa") + api("org.springframework:spring-aspects") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("org.springframework.data:spring-data-envers") { + exclude group: "javax.activation", module: "javax.activation-api" + exclude group: "javax.persistence", module: "javax.persistence-api" + exclude group: "javax.xml.bind", module: "jaxb-api" + exclude group: "org.jboss.spec.javax.transaction", module: "jboss-transaction-api_1.2_spec" + } + + testImplementation(project(":spring-boot-project:spring-boot-jdbc")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") + testRuntimeOnly("jakarta.servlet:jakarta.servlet-api") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/EnversRevisionRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/EnversRevisionRepositoriesRegistrar.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/EnversRevisionRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/EnversRevisionRepositoriesRegistrar.java index 4a13ab2a88cd..de76eb51736d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/EnversRevisionRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/EnversRevisionRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jpa; +package org.springframework.boot.data.jpa.autoconfigure; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.data.envers.repository.support.EnversRevisionRepositoryFactoryBean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesAutoConfiguration.java index c034b7cb27d8..6a11da334bf4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jpa; +package org.springframework.boot.data.jpa.autoconfigure; import java.util.Map; @@ -28,10 +28,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration.JpaRepositoriesImportSelector; -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; +import org.springframework.boot.data.jpa.autoconfigure.JpaRepositoriesAutoConfiguration.JpaRepositoriesImportSelector; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Import; @@ -68,7 +68,7 @@ * @author Josh Long * @author Scott Frederick * @author Stefano Cordio - * @since 1.0.0 + * @since 4.0.0 * @see EnableJpaRepositories */ @AutoConfiguration(after = { HibernateJpaAutoConfiguration.class, TaskExecutionAutoConfiguration.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesRegistrar.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesRegistrar.java index fddd30a5adff..472881949182 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jpa; +package org.springframework.boot.data.jpa.autoconfigure; import java.lang.annotation.Annotation; import java.util.Locale; diff --git a/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/package-info.java new file mode 100644 index 000000000000..f61412014140 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/src/main/java/org/springframework/boot/data/jpa/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data JPA. + */ +package org.springframework.boot.data.jpa.autoconfigure; diff --git a/spring-boot-project/spring-boot-data-jpa/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-jpa/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..3741f3d04dd6 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,17 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.data.jpa.repositories.bootstrap-mode", + "type": "org.springframework.data.repository.config.BootstrapMode", + "description": "Bootstrap mode for JPA repositories.", + "defaultValue": "default" + }, + { + "name": "spring.data.jpa.repositories.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable JPA repositories.", + "defaultValue": true + } + ] +} diff --git a/spring-boot-project/spring-boot-data-jpa/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-jpa/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..ae0f029c1748 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.data.jpa.autoconfigure.JpaRepositoriesAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/AbstractJpaRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/AbstractJpaRepositoriesAutoConfigurationTests.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/AbstractJpaRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/AbstractJpaRepositoriesAutoConfigurationTests.java index 4a10316d1847..68a01b5bdc9c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/AbstractJpaRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/AbstractJpaRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jpa; +package org.springframework.boot.data.jpa.autoconfigure; import jakarta.persistence.EntityManagerFactory; import org.junit.jupiter.api.Test; @@ -22,21 +22,16 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.alt.elasticsearch.CityElasticsearchDbRepository; -import org.springframework.boot.autoconfigure.data.alt.jpa.CityJpaRepository; -import org.springframework.boot.autoconfigure.data.alt.mongo.CityMongoDbRepository; -import org.springframework.boot.autoconfigure.data.jpa.city.City; -import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository; -import org.springframework.boot.autoconfigure.data.jpa.country.Country; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration; +import org.springframework.boot.data.jpa.autoconfigure.domain.city.City; +import org.springframework.boot.data.jpa.autoconfigure.domain.city.CityRepository; +import org.springframework.boot.data.jpa.autoconfigure.domain.country.Country; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Import; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @@ -74,7 +69,7 @@ void testDefaultRepositoryConfiguration() { @Test void testOverrideRepositoryConfiguration() { this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(CityJpaRepository.class); + assertThat(context).hasSingleBean(CityRepository.class); assertThat(context).hasSingleBean(PlatformTransactionManager.class); assertThat(context).hasSingleBean(EntityManagerFactory.class); }); @@ -163,10 +158,7 @@ static class TestConfiguration { } @Configuration(proxyBeanMethods = false) - @EnableJpaRepositories( - basePackageClasses = org.springframework.boot.autoconfigure.data.alt.jpa.CityJpaRepository.class, - excludeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE, value = CityMongoDbRepository.class), - @Filter(type = FilterType.ASSIGNABLE_TYPE, value = CityElasticsearchDbRepository.class) }) + @EnableJpaRepositories(basePackageClasses = CityRepository.class) @TestAutoConfigurationPackage(City.class) static class CustomConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/EnversRevisionRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/EnversRevisionRepositoriesAutoConfigurationTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/EnversRevisionRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/EnversRevisionRepositoriesAutoConfigurationTests.java index b43241a91624..28323aeb2a87 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/EnversRevisionRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/EnversRevisionRepositoriesAutoConfigurationTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jpa; +package org.springframework.boot.data.jpa.autoconfigure; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.data.jpa.country.CountryRepository; +import org.springframework.boot.data.jpa.autoconfigure.domain.country.CountryRepository; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesAutoConfigurationTests.java index 71a744150d8c..db4b1bcf77f9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.jpa; +package org.springframework.boot.data.jpa.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesSpringDataWebAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesSpringDataWebAutoConfigurationTests.java new file mode 100644 index 000000000000..44b1e19aee48 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/JpaRepositoriesSpringDataWebAutoConfigurationTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.jpa.autoconfigure; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; +import org.springframework.boot.data.autoconfigure.web.SpringDataWebAutoConfiguration; +import org.springframework.boot.data.jpa.autoconfigure.domain.city.City; +import org.springframework.boot.data.jpa.autoconfigure.domain.city.CityRepository; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.geo.Distance; +import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.data.web.SortHandlerMethodArgumentResolver; +import org.springframework.format.support.FormattingConversionService; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringDataWebAutoConfiguration} and + * {@link JpaRepositoriesAutoConfiguration}. + * + * @author Dave Syer + * @author Stephane Nicoll + */ +class JpaRepositoriesSpringDataWebAutoConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, + JpaRepositoriesAutoConfiguration.class, SpringDataWebAutoConfiguration.class)) + .withPropertyValues("spring.datasource.generate-unique-name=true"); + + @Test + void springDataWebIsConfiguredWithJpaRepositories() { + this.contextRunner.withUserConfiguration(TestConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(CityRepository.class); + assertThat(context).hasSingleBean(PageableHandlerMethodArgumentResolver.class); + assertThat(context).hasSingleBean(SortHandlerMethodArgumentResolver.class); + assertThat(context.getBean(FormattingConversionService.class).canConvert(String.class, Distance.class)) + .isTrue(); + }); + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + @EnableWebMvc + static class TestConfiguration { + + } + +} diff --git a/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/city/City.java b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/city/City.java new file mode 100644 index 000000000000..8fb40e76eb56 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/city/City.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.jpa.autoconfigure.domain.city; + +import java.io.Serializable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + @Column(nullable = false) + private String country; + + @Column(nullable = false) + private String map; + + protected City() { + } + + public City(String name, String country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/city/CityRepository.java new file mode 100644 index 000000000000..5b0cdfe90477 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/city/CityRepository.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.jpa.autoconfigure.domain.city; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CityRepository extends JpaRepository { + + @Override + Page findAll(Pageable pageable); + + Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); + + City findByNameAndCountryAllIgnoringCase(String name, String country); + +} diff --git a/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/country/Country.java b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/country/Country.java new file mode 100644 index 000000000000..8b2417451308 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/country/Country.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.jpa.autoconfigure.domain.country; + +import java.io.Serializable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import org.hibernate.envers.Audited; + +@Entity +public class Country implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Audited + @Column + private String name; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/country/CountryRepository.java b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/country/CountryRepository.java new file mode 100644 index 000000000000..04a3467cffa0 --- /dev/null +++ b/spring-boot-project/spring-boot-data-jpa/src/test/java/org/springframework/boot/data/jpa/autoconfigure/domain/country/CountryRepository.java @@ -0,0 +1,24 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.jpa.autoconfigure.domain.country; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.history.RevisionRepository; + +public interface CountryRepository extends JpaRepository, RevisionRepository { + +} diff --git a/spring-boot-project/spring-boot-data-ldap/build.gradle b/spring-boot-project/spring-boot-data-ldap/build.gradle new file mode 100644 index 000000000000..22013578ddb0 --- /dev/null +++ b/spring-boot-project/spring-boot-data-ldap/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data LDAP" + +dependencies { + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-ldap")) + api("org.springframework.data:spring-data-ldap") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesAutoConfiguration.java index b690e0345016..1e65e323c797 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.ldap; +package org.springframework.boot.data.ldap.autoconfigure; import javax.naming.ldap.LdapContext; @@ -31,7 +31,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's LDAP Repositories. * * @author Eddú Meléndez - * @since 1.5.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ LdapContext.class, LdapRepository.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesRegistrar.java index 3123812b551a..9ddb56c3911c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.ldap; +package org.springframework.boot.data.ldap.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/package-info.java new file mode 100644 index 000000000000..8875bacbbdeb --- /dev/null +++ b/spring-boot-project/spring-boot-data-ldap/src/main/java/org/springframework/boot/data/ldap/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data LDAP. + */ +package org.springframework.boot.data.ldap.autoconfigure; diff --git a/spring-boot-project/spring-boot-data-ldap/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-ldap/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..b87beeb2b9fe --- /dev/null +++ b/spring-boot-project/spring-boot-data-ldap/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,11 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.data.ldap.repositories.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable LDAP repositories.", + "defaultValue": true + } + ] +} diff --git a/spring-boot-project/spring-boot-data-ldap/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-ldap/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..acc2148297c0 --- /dev/null +++ b/spring-boot-project/spring-boot-data-ldap/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.data.ldap.autoconfigure.LdapRepositoriesAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesAutoConfigurationTests.java similarity index 82% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesAutoConfigurationTests.java index c20d4ce3daf9..7294aff556f2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/LdapRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/LdapRepositoriesAutoConfigurationTests.java @@ -14,18 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.ldap; +package org.springframework.boot.data.ldap.autoconfigure; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.alt.ldap.PersonLdapRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.data.ldap.person.Person; -import org.springframework.boot.autoconfigure.data.ldap.person.PersonRepository; -import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.data.ldap.autoconfigure.domain.empty.EmptyDataPackage; +import org.springframework.boot.data.ldap.autoconfigure.domain.person.Person; +import org.springframework.boot.data.ldap.autoconfigure.domain.person.PersonRepository; +import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; @@ -64,7 +63,7 @@ void testNoRepositoryConfiguration() { @Test void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { load(CustomizedConfiguration.class); - assertThat(this.context.getBean(PersonLdapRepository.class)).isNotNull(); + assertThat(this.context.getBean(PersonRepository.class)).isNotNull(); } private void load(Class... configurationClasses) { @@ -90,7 +89,7 @@ static class EmptyConfiguration { @Configuration(proxyBeanMethods = false) @TestAutoConfigurationPackage(LdapRepositoriesAutoConfigurationTests.class) - @EnableLdapRepositories(basePackageClasses = PersonLdapRepository.class) + @EnableLdapRepositories(basePackageClasses = PersonRepository.class) static class CustomizedConfiguration { } diff --git a/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/empty/EmptyDataPackage.java b/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/empty/EmptyDataPackage.java new file mode 100644 index 000000000000..919c02b5be81 --- /dev/null +++ b/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/empty/EmptyDataPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.ldap.autoconfigure.domain.empty; + +public class EmptyDataPackage { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/person/Person.java b/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/person/Person.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/person/Person.java rename to spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/person/Person.java index dcfa762e2a5f..43155f364c81 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/person/Person.java +++ b/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/person/Person.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.ldap.person; +package org.springframework.boot.data.ldap.autoconfigure.domain.person; import javax.naming.Name; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/person/PersonRepository.java b/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/person/PersonRepository.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/person/PersonRepository.java rename to spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/person/PersonRepository.java index 9396f8aee021..927a9e2ac34a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/ldap/person/PersonRepository.java +++ b/spring-boot-project/spring-boot-data-ldap/src/test/java/org/springframework/boot/data/ldap/autoconfigure/domain/person/PersonRepository.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.ldap.person; +package org.springframework.boot.data.ldap.autoconfigure.domain.person; import javax.naming.Name; diff --git a/spring-boot-project/spring-boot-data-mongodb/build.gradle b/spring-boot-project/spring-boot-data-mongodb/build.gradle new file mode 100644 index 000000000000..d9d94cdc10c4 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/build.gradle @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data MongoDB" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-mongodb")) + api("org.springframework.data:spring-data-mongodb") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-reactor")) + optional("org.mongodb:mongodb-driver-reactivestreams") + optional("org.mongodb:mongodb-driver-sync") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation("ch.qos.logback:logback-classic") + dockerTestImplementation("org.junit.jupiter:junit-jupiter") + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:mongodb") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("io.projectreactor:reactor-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/mongo/MongoHealthIndicatorIntegrationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/dockerTest/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicatorIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/mongo/MongoHealthIndicatorIntegrationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/dockerTest/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicatorIntegrationTests.java index 34168704731e..82603c0bbfdf 100644 --- a/spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/mongo/MongoHealthIndicatorIntegrationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/dockerTest/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicatorIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.mongo; +package org.springframework.boot.data.mongodb.health; import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; @@ -28,9 +28,8 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.springframework.boot.actuate.data.mongo.MongoHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.data.mongodb.core.MongoTemplate; diff --git a/spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorIntegrationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/dockerTest/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicatorIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorIntegrationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/dockerTest/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicatorIntegrationTests.java index f566f87ee001..c047e607dee0 100644 --- a/spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorIntegrationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/dockerTest/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicatorIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.mongo; +package org.springframework.boot.data.mongodb.health; import java.time.Duration; @@ -30,9 +30,8 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.springframework.boot.actuate.data.mongo.MongoReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataAutoConfiguration.java similarity index 86% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataAutoConfiguration.java index 82a9ccff313a..9b38c059adc9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import com.mongodb.client.MongoClient; @@ -23,11 +23,11 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; -import org.springframework.boot.autoconfigure.mongo.MongoProperties; -import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; +import org.springframework.boot.mongodb.autoconfigure.MongoProperties; +import org.springframework.boot.mongodb.autoconfigure.PropertiesMongoConnectionDetails; import org.springframework.boot.ssl.SslBundles; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -50,7 +50,7 @@ * @author Eddú Meléndez * @author Stephane Nicoll * @author Christoph Strobl - * @since 1.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = MongoAutoConfiguration.class) @ConditionalOnClass({ MongoClient.class, MongoTemplate.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataConfiguration.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataConfiguration.java index 1bdbaf366621..f80c02d14284 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataConfiguration.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import java.util.Collections; @@ -22,8 +22,8 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.domain.EntityScanner; -import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.mongodb.autoconfigure.MongoProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDatabaseFactoryConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDatabaseFactoryConfiguration.java index 25ef29b895a0..59a57d27e8fb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDatabaseFactoryConfiguration.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import com.mongodb.client.MongoClient; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; -import org.springframework.boot.autoconfigure.mongo.MongoProperties; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; +import org.springframework.boot.mongodb.autoconfigure.MongoProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.MongoDatabaseFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDatabaseFactoryDependentConfiguration.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDatabaseFactoryDependentConfiguration.java index 70a42f0cbec8..0b9106f0790c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDatabaseFactoryDependentConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import com.mongodb.ClientSessionOptions; import com.mongodb.client.ClientSession; @@ -22,10 +22,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs; -import org.springframework.boot.autoconfigure.mongo.MongoProperties; -import org.springframework.boot.autoconfigure.mongo.MongoProperties.Gridfs; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails.GridFs; +import org.springframework.boot.mongodb.autoconfigure.MongoProperties; +import org.springframework.boot.mongodb.autoconfigure.MongoProperties.Gridfs; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.dao.DataAccessException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveDataAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveDataAutoConfiguration.java index f9dc2e1aa443..88f1eafbe97b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import java.util.Optional; @@ -31,11 +31,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs; -import org.springframework.boot.autoconfigure.mongo.MongoProperties; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails.GridFs; +import org.springframework.boot.mongodb.autoconfigure.MongoProperties; +import org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.core.io.buffer.DataBufferFactory; @@ -65,7 +65,7 @@ * @author Andy Wilkinson * @author Phillip Webb * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = MongoReactiveAutoConfiguration.class) @ConditionalOnClass({ MongoClient.class, ReactiveMongoTemplate.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesAutoConfiguration.java index 486f35c30663..845d99e07ec1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import com.mongodb.reactivestreams.client.MongoClient; @@ -45,7 +45,7 @@ * annotation. * * @author Mark Paluch - * @since 2.0.0 + * @since 4.0.0 * @see EnableReactiveMongoRepositories */ @AutoConfiguration(after = MongoReactiveDataAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesRegistrar.java index 069270d22f60..6161f49e7caf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesAutoConfiguration.java index 47dc173f5a06..329f45037eba 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import com.mongodb.client.MongoClient; @@ -47,7 +47,7 @@ * @author Dave Syer * @author Oliver Gierke * @author Josh Long - * @since 1.0.0 + * @since 4.0.0 * @see EnableMongoRepositories */ @AutoConfiguration(after = MongoDataAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesRegistrar.java index f8a915794de5..cd0db619c7e8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoHealthContributorAutoConfiguration.java new file mode 100644 index 000000000000..de4fb38408b5 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoHealthContributorAutoConfiguration.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.mongodb.autoconfigure.health; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration; +import org.springframework.boot.data.mongodb.health.MongoHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.data.mongodb.core.MongoTemplate; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for {@link MongoHealthIndicator}. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration(after = { MongoReactiveHealthContributorAutoConfiguration.class, MongoDataAutoConfiguration.class, + MongoAutoConfiguration.class }) +@ConditionalOnClass({ MongoTemplate.class, MongoHealthIndicator.class, ConditionalOnEnabledHealthIndicator.class }) +@ConditionalOnBean(MongoTemplate.class) +@ConditionalOnEnabledHealthIndicator("mongo") +public class MongoHealthContributorAutoConfiguration + extends CompositeHealthContributorConfiguration { + + public MongoHealthContributorAutoConfiguration() { + super(MongoHealthIndicator::new); + } + + @Bean + @ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" }) + public HealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) { + return createContributor(beanFactory, MongoTemplate.class); + } + +} diff --git a/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoReactiveHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoReactiveHealthContributorAutoConfiguration.java new file mode 100644 index 000000000000..576caaa4fd08 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoReactiveHealthContributorAutoConfiguration.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.mongodb.autoconfigure.health; + +import reactor.core.publisher.Flux; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveDataAutoConfiguration; +import org.springframework.boot.data.mongodb.health.MongoReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.context.annotation.Bean; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link MongoReactiveHealthIndicator}. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration(after = MongoReactiveDataAutoConfiguration.class) +@ConditionalOnClass({ ReactiveMongoTemplate.class, Flux.class, MongoReactiveHealthIndicator.class, + ConditionalOnEnabledHealthIndicator.class }) +@ConditionalOnBean(ReactiveMongoTemplate.class) +@ConditionalOnEnabledHealthIndicator("mongo") +public class MongoReactiveHealthContributorAutoConfiguration + extends CompositeReactiveHealthContributorConfiguration { + + public MongoReactiveHealthContributorAutoConfiguration() { + super(MongoReactiveHealthIndicator::new); + } + + @Bean + @ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" }) + public ReactiveHealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) { + return createContributor(beanFactory, ReactiveMongoTemplate.class); + } + +} diff --git a/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..2268c26f4db8 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data MongoDB health. + */ +package org.springframework.boot.data.mongodb.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/package-info.java new file mode 100644 index 000000000000..a0122086369d --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data MongoDB. + */ +package org.springframework.boot.data.mongodb.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/MongoHealthIndicator.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicator.java similarity index 84% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/MongoHealthIndicator.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicator.java index f2daad8e0742..005df6362de6 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/MongoHealthIndicator.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicator.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.data.mongo; +package org.springframework.boot.data.mongodb.health; import org.bson.Document; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.util.Assert; @@ -29,7 +29,7 @@ * Mongo data stores. * * @author Christian Dupuis - * @since 2.0.0 + * @since 4.0.0 */ public class MongoHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/MongoReactiveHealthIndicator.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicator.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/MongoReactiveHealthIndicator.java rename to spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicator.java index 5dc8e2e617f2..418678528468 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/MongoReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicator.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.data.mongo; +package org.springframework.boot.data.mongodb.health; import org.bson.Document; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.util.Assert; @@ -29,7 +29,7 @@ * A {@link ReactiveHealthIndicator} for Mongo. * * @author Yulin Qin - * @since 2.0.0 + * @since 4.0.0 */ public class MongoReactiveHealthIndicator extends AbstractReactiveHealthIndicator { diff --git a/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/package-info.java b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/package-info.java new file mode 100644 index 000000000000..b3404379a9d6 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * MongoDB health integration using Spring Data MongoDB. + */ +package org.springframework.boot.data.mongodb.health; diff --git a/spring-boot-project/spring-boot-data-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..c6be55b70f79 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,39 @@ +{ + "properties": [ + { + "name": "management.health.mongo.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable MongoDB health check.", + "defaultValue": true + } + ], + "hints": [ + { + "name": "spring.data.mongodb.field-naming-strategy", + "providers": [ + { + "name": "class-reference", + "parameters": { + "target": "org.springframework.data.mapping.model.FieldNamingStrategy" + } + } + ] + }, + { + "name": "spring.data.mongodb.protocol", + "values": [ + { + "value": "mongodb" + }, + { + "value": "mongodb+srv" + } + ], + "providers": [ + { + "name": "any" + } + ] + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-data-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..21134753f001 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,6 @@ +org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveDataAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.MongoRepositoriesAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.health.MongoHealthContributorAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.health.MongoReactiveHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/mongo/CityMongoDbRepository.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/alt/CityMongoDbRepository.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/mongo/CityMongoDbRepository.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/alt/CityMongoDbRepository.java index c502742538ef..5e5b8d64700a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/mongo/CityMongoDbRepository.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/alt/CityMongoDbRepository.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.alt.mongo; +package org.springframework.boot.data.mongodb.alt; -import org.springframework.boot.autoconfigure.data.mongo.city.City; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.City; import org.springframework.data.repository.Repository; public interface CityMongoDbRepository extends Repository { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/mongo/ReactiveCityMongoDbRepository.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/alt/ReactiveCityMongoDbRepository.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/mongo/ReactiveCityMongoDbRepository.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/alt/ReactiveCityMongoDbRepository.java index 0b501f356bbe..6ac8595821d9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/alt/mongo/ReactiveCityMongoDbRepository.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/alt/ReactiveCityMongoDbRepository.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.alt.mongo; +package org.springframework.boot.data.mongodb.alt; -import org.springframework.boot.autoconfigure.data.mongo.city.City; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.City; import org.springframework.data.repository.reactive.ReactiveCrudRepository; public interface ReactiveCityMongoDbRepository extends ReactiveCrudRepository { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataAutoConfigurationTests.java index 18bf8b6221bc..5656bc6452f0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoDataAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import java.time.LocalDateTime; import java.util.Arrays; @@ -32,12 +32,12 @@ import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.city.City; -import org.springframework.boot.autoconfigure.data.mongo.country.Country; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; -import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.City; +import org.springframework.boot.data.mongodb.autoconfigure.domain.country.Country; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; +import org.springframework.boot.mongodb.autoconfigure.PropertiesMongoConnectionDetails; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -345,7 +345,7 @@ MongoCustomConversions customConversions() { } @Configuration(proxyBeanMethods = false) - @EntityScan("org.springframework.boot.autoconfigure.data.mongo") + @EntityScan("org.springframework.boot.data.mongodb.autoconfigure") static class EntityScanConfig { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveAndBlockingRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveAndBlockingRepositoriesAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveAndBlockingRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveAndBlockingRepositoriesAutoConfigurationTests.java index 28c1d5f35540..154aa292958e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveAndBlockingRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveAndBlockingRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import java.util.ArrayList; import java.util.List; @@ -23,10 +23,10 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.mongo.city.CityRepository; -import org.springframework.boot.autoconfigure.data.mongo.city.ReactiveCityRepository; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.CityRepository; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.ReactiveCityRepository; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveDataAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveDataAutoConfigurationTests.java index be5c43a399a0..2ffbe4f03ef0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveDataAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import java.time.Duration; @@ -26,8 +26,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; +import org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesAutoConfigurationTests.java index 766571ac3fec..3a189c08b445 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoReactiveRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import com.mongodb.reactivestreams.client.MongoClient; import org.junit.jupiter.api.Test; @@ -22,13 +22,13 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.alt.mongo.CityMongoDbRepository; -import org.springframework.boot.autoconfigure.data.alt.mongo.ReactiveCityMongoDbRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.data.mongo.city.City; -import org.springframework.boot.autoconfigure.data.mongo.city.ReactiveCityRepository; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.boot.data.mongodb.alt.CityMongoDbRepository; +import org.springframework.boot.data.mongodb.alt.ReactiveCityMongoDbRepository; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.City; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.ReactiveCityRepository; +import org.springframework.boot.data.mongodb.autoconfigure.empty.EmptyDataPackage; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.ManagedTypes; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesAutoConfigurationTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesAutoConfigurationTests.java index 10ed01ac51e6..61a351023a42 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/MongoRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure; import com.mongodb.client.MongoClient; import org.junit.jupiter.api.Test; @@ -22,11 +22,11 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.alt.mongo.CityMongoDbRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.data.mongo.city.City; -import org.springframework.boot.autoconfigure.data.mongo.city.CityRepository; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.data.mongodb.alt.CityMongoDbRepository; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.City; +import org.springframework.boot.data.mongodb.autoconfigure.domain.city.CityRepository; +import org.springframework.boot.data.mongodb.autoconfigure.empty.EmptyDataPackage; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.ManagedTypes; diff --git a/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/City.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/City.java new file mode 100644 index 000000000000..c515be7dcd3a --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/City.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.mongodb.autoconfigure.domain.city; + +import java.io.Serializable; + +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + private String name; + + private String state; + + private String country; + + private String map; + + protected City() { + } + + public City(String name, String country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/CityRepository.java new file mode 100644 index 000000000000..b8c6caff1acf --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/CityRepository.java @@ -0,0 +1,31 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.mongodb.autoconfigure.domain.city; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.Repository; + +public interface CityRepository extends Repository { + + Page findAll(Pageable pageable); + + Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); + + City findByNameAndCountryAllIgnoringCase(String name, String country); + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/PersistentEntity.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/PersistentEntity.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/PersistentEntity.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/PersistentEntity.java index 1d91b45bd695..5f111ee1e5f3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/city/PersistentEntity.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/PersistentEntity.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.mongo.city; +package org.springframework.boot.data.mongodb.autoconfigure.domain.city; import java.io.Serializable; diff --git a/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/ReactiveCityRepository.java new file mode 100644 index 000000000000..bd067930933c --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/city/ReactiveCityRepository.java @@ -0,0 +1,27 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.mongodb.autoconfigure.domain.city; + +import reactor.core.publisher.Flux; + +import org.springframework.data.repository.Repository; + +public interface ReactiveCityRepository extends Repository { + + Flux findAll(); + +} diff --git a/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/country/Country.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/country/Country.java new file mode 100644 index 000000000000..a4f90f9a3ef2 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/country/Country.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.mongodb.autoconfigure.domain.country; + +import java.io.Serializable; + +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class Country implements Serializable { + + private static final long serialVersionUID = 1L; + + private String name; + + protected Country() { + } + + public Country(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + return getName(); + } + +} diff --git a/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/country/CountryRepository.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/country/CountryRepository.java new file mode 100644 index 000000000000..7afeffc86700 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/domain/country/CountryRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.mongodb.autoconfigure.domain.country; + +import org.springframework.data.repository.Repository; + +public interface CountryRepository extends Repository { + +} diff --git a/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/empty/EmptyDataPackage.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/empty/EmptyDataPackage.java new file mode 100644 index 000000000000..809981a11145 --- /dev/null +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/empty/EmptyDataPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.mongodb.autoconfigure.empty; + +public class EmptyDataPackage { + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoHealthContributorAutoConfigurationTests.java similarity index 80% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoHealthContributorAutoConfigurationTests.java index a8595ea7f1b5..bdaa586ccc94 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoHealthContributorAutoConfigurationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.data.mongo.MongoHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration; +import org.springframework.boot.data.mongodb.health.MongoHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoReactiveHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoReactiveHealthContributorAutoConfigurationTests.java similarity index 77% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoReactiveHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoReactiveHealthContributorAutoConfigurationTests.java index 4868261c152e..e5624565d859 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoReactiveHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoReactiveHealthContributorAutoConfigurationTests.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.data.mongo; +package org.springframework.boot.data.mongodb.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.data.mongo.MongoHealthIndicator; -import org.springframework.boot.actuate.data.mongo.MongoReactiveHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration; +import org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveDataAutoConfiguration; +import org.springframework.boot.data.mongodb.health.MongoHealthIndicator; +import org.springframework.boot.data.mongodb.health.MongoReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoHealthIndicatorTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicatorTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoHealthIndicatorTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicatorTests.java index 6aa606869bec..45dd1be26a5d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicatorTests.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.mongo; +package org.springframework.boot.data.mongodb.health; import com.mongodb.MongoException; import org.bson.Document; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.data.mongo.MongoHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.data.mongodb.core.MongoTemplate; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicatorTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTests.java rename to spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicatorTests.java index 36518edb8fc3..5c956f6ff4ed 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-data-mongodb/src/test/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.mongo; +package org.springframework.boot.data.mongodb.health; import java.time.Duration; @@ -24,9 +24,8 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import org.springframework.boot.actuate.data.mongo.MongoReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-data-neo4j/build.gradle b/spring-boot-project/spring-boot-data-neo4j/build.gradle new file mode 100644 index 000000000000..3f6f1bacf563 --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/build.gradle @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data Neo4j" + +dependencies { + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-neo4j")) + api(project(":spring-boot-project:spring-boot-tx")) + api("org.springframework.data:spring-data-neo4j") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-reactor")) + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation("ch.qos.logback:logback-classic") + dockerTestImplementation("org.junit.jupiter:junit-jupiter") + dockerTestImplementation("org.testcontainers:neo4j") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("io.projectreactor:reactor-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-data-neo4j/src/dockerTest/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfigurationIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-data-neo4j/src/dockerTest/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfigurationIntegrationTests.java index f01f3479a1a2..df397e6270f9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/dockerTest/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.junit.jupiter.api.Test; import org.testcontainers.containers.Neo4jContainer; @@ -23,8 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; +import org.springframework.boot.data.neo4j.domain.country.CountryRepository; +import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataAutoConfiguration.java index 9d7dd44109ca..801b5d92be42 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import java.util.Set; @@ -27,11 +27,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.domain.EntityScanner; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizers; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.data.neo4j.aot.Neo4jManagedTypes; @@ -57,7 +57,7 @@ * @author Stephane Nicoll * @author Kazuki Shimizu * @author Michael J. Simons - * @since 1.4.0 + * @since 4.0.0 */ @AutoConfiguration(before = TransactionAutoConfiguration.class, after = { Neo4jAutoConfiguration.class, TransactionManagerCustomizationAutoConfiguration.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataProperties.java b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataProperties.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataProperties.java rename to spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataProperties.java index b3809eb485b9..d30301a451e3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataProperties.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -22,7 +22,7 @@ * Configuration properties for Spring Data Neo4j. * * @author Michael J. Simons - * @since 2.4.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.data.neo4j") public class Neo4jDataProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveDataAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveDataAutoConfiguration.java index fab0b44703bf..891b5d6eec4b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.neo4j.driver.Driver; import reactor.core.publisher.Flux; @@ -40,7 +40,7 @@ * * @author Michael J. Simons * @author Stephane Nicoll - * @since 2.4.0 + * @since 4.0.0 */ @AutoConfiguration(after = Neo4jDataAutoConfiguration.class) @ConditionalOnClass({ Driver.class, ReactiveNeo4jTemplate.class, ReactiveTransactionManager.class, Flux.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesAutoConfiguration.java index 55bc8fb5920f..8505c540fdde 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.neo4j.driver.Driver; import reactor.core.publisher.Flux; @@ -36,7 +36,7 @@ * * @author Michael J. Simons * @author Stephane Nicoll - * @since 2.4.0 + * @since 4.0.0 */ @AutoConfiguration(after = Neo4jReactiveDataAutoConfiguration.class) @ConditionalOnClass({ Driver.class, ReactiveNeo4jRepository.class, Flux.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesRegistrar.java index e91fe3879b0c..c630f269d80c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfiguration.java index a9744f3358a9..f12322e46275 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.neo4j.driver.Driver; @@ -46,7 +46,7 @@ * @author Oliver Gierke * @author Josh Long * @author Michael J. Simons - * @since 1.4.0 + * @since 4.0.0 * @see EnableNeo4jRepositories */ @AutoConfiguration(after = Neo4jDataAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesRegistrar.java index 9515b07cc328..24b78112c250 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/package-info.java new file mode 100644 index 000000000000..ba3a304a193c --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/java/org/springframework/boot/data/neo4j/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data Neo4j. + */ +package org.springframework.boot.data.neo4j.autoconfigure; diff --git a/spring-boot-project/spring-boot-data-neo4j/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-neo4j/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..fcaa6e4afa8a --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,83 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.data.neo4j.auto-index", + "description": "Auto index mode.", + "defaultValue": "none", + "deprecation": { + "reason": "Automatic index creation is no longer supported.", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.embedded.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable embedded mode if the embedded driver is available.", + "deprecation": { + "reason": "Embedded mode is no longer supported, please use Testcontainers instead.", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.open-in-view", + "type": "java.lang.Boolean", + "description": "Register OpenSessionInViewInterceptor that binds a Neo4j Session to the thread for the entire processing of the request.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.data.neo4j.password", + "type": "java.lang.String", + "description": "Login password of the server.", + "deprecation": { + "replacement": "spring.neo4j.authentication.password", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.repositories.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Neo4j repositories.", + "defaultValue": true, + "deprecation": { + "replacement": "spring.data.neo4j.repositories.type", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.repositories.type", + "type": "org.springframework.boot.autoconfigure.data.RepositoryType", + "description": "Type of Neo4j repositories to enable.", + "defaultValue": "auto" + }, + { + "name": "spring.data.neo4j.uri", + "type": "java.lang.String", + "description": "URI used by the driver. Auto-detected by default.", + "deprecation": { + "replacement": "spring.neo4j.uri", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.use-native-types", + "type": "java.lang.Boolean", + "description": "Whether to use Neo4j native types wherever possible.", + "deprecation": { + "reason": "Native type support is now built-in.", + "level": "error" + } + }, + { + "name": "spring.data.neo4j.username", + "type": "java.lang.String", + "description": "Login user of the server.", + "deprecation": { + "replacement": "spring.neo4j.authentication.username", + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-data-neo4j/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-neo4j/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..95f5116fe738 --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.data.neo4j.autoconfigure.Neo4jDataAutoConfiguration +org.springframework.boot.data.neo4j.autoconfigure.Neo4jReactiveDataAutoConfiguration +org.springframework.boot.data.neo4j.autoconfigure.Neo4jReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.neo4j.autoconfigure.Neo4jRepositoriesAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MockedDriverConfiguration.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/MockedDriverConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MockedDriverConfiguration.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/MockedDriverConfiguration.java index 7c905139baeb..6e14b1b68a38 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/MockedDriverConfiguration.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/MockedDriverConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.mockito.ArgumentMatchers; import org.neo4j.driver.Driver; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataAutoConfigurationTests.java index 9be0603c1a85..8798b87e4248 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jDataAutoConfigurationTests.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.junit.jupiter.api.Test; import org.neo4j.driver.Driver; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.neo4j.scan.TestNode; -import org.springframework.boot.autoconfigure.data.neo4j.scan.TestNonAnnotated; -import org.springframework.boot.autoconfigure.data.neo4j.scan.TestPersistent; -import org.springframework.boot.autoconfigure.data.neo4j.scan.TestRelationshipProperties; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; +import org.springframework.boot.data.neo4j.domain.scan.TestNode; +import org.springframework.boot.data.neo4j.domain.scan.TestNonAnnotated; +import org.springframework.boot.data.neo4j.domain.scan.TestPersistent; +import org.springframework.boot.data.neo4j.domain.scan.TestRelationshipProperties; +import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveDataAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveDataAutoConfigurationTests.java index de246aba440e..4ef2c827bbfb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveDataAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.junit.jupiter.api.Test; import org.neo4j.driver.Driver; @@ -23,11 +23,11 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.neo4j.scan.TestNode; -import org.springframework.boot.autoconfigure.data.neo4j.scan.TestNonAnnotated; -import org.springframework.boot.autoconfigure.data.neo4j.scan.TestPersistent; -import org.springframework.boot.autoconfigure.data.neo4j.scan.TestRelationshipProperties; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; +import org.springframework.boot.data.neo4j.domain.scan.TestNode; +import org.springframework.boot.data.neo4j.domain.scan.TestNonAnnotated; +import org.springframework.boot.data.neo4j.domain.scan.TestPersistent; +import org.springframework.boot.data.neo4j.domain.scan.TestRelationshipProperties; +import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesAutoConfigurationTests.java similarity index 86% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesAutoConfigurationTests.java index a2a7d48dc031..a5b70764bc52 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jReactiveRepositoriesAutoConfigurationTests.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.data.neo4j.city.City; -import org.springframework.boot.autoconfigure.data.neo4j.city.CityRepository; -import org.springframework.boot.autoconfigure.data.neo4j.city.ReactiveCityRepository; -import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository; -import org.springframework.boot.autoconfigure.data.neo4j.country.ReactiveCountryRepository; +import org.springframework.boot.data.neo4j.domain.city.City; +import org.springframework.boot.data.neo4j.domain.city.CityRepository; +import org.springframework.boot.data.neo4j.domain.city.ReactiveCityRepository; +import org.springframework.boot.data.neo4j.domain.country.CountryRepository; +import org.springframework.boot.data.neo4j.domain.country.ReactiveCountryRepository; +import org.springframework.boot.data.neo4j.domain.empty.EmptyPackage; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate; @@ -93,7 +93,7 @@ static class TestConfiguration { } @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(EmptyDataPackage.class) + @TestAutoConfigurationPackage(EmptyPackage.class) static class EmptyConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfigurationTests.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfigurationTests.java index 67a54329a8c5..7510e30c7d60 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/autoconfigure/Neo4jRepositoriesAutoConfigurationTests.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j; +package org.springframework.boot.data.neo4j.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.data.neo4j.city.City; -import org.springframework.boot.autoconfigure.data.neo4j.city.CityRepository; -import org.springframework.boot.autoconfigure.data.neo4j.city.ReactiveCityRepository; -import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository; -import org.springframework.boot.autoconfigure.data.neo4j.country.ReactiveCountryRepository; +import org.springframework.boot.data.neo4j.domain.city.City; +import org.springframework.boot.data.neo4j.domain.city.CityRepository; +import org.springframework.boot.data.neo4j.domain.city.ReactiveCityRepository; +import org.springframework.boot.data.neo4j.domain.country.CountryRepository; +import org.springframework.boot.data.neo4j.domain.country.ReactiveCountryRepository; +import org.springframework.boot.data.neo4j.domain.empty.EmptyPackage; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -113,7 +113,7 @@ static class TestConfiguration { } @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(EmptyDataPackage.class) + @TestAutoConfigurationPackage(EmptyPackage.class) static class EmptyConfiguration { } diff --git a/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/City.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/City.java new file mode 100644 index 000000000000..bffeeaffe7fa --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/City.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.neo4j.domain.city; + +import java.io.Serializable; + +import org.springframework.boot.data.neo4j.domain.country.Country; +import org.springframework.data.neo4j.core.schema.GeneratedValue; +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; + +@Node +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + private final String name; + + private String state; + + private final Country country; + + private String map; + + public City(String name, Country country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public Country getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/CityRepository.java new file mode 100644 index 000000000000..d28999e87a36 --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/CityRepository.java @@ -0,0 +1,28 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.neo4j.domain.city; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.neo4j.repository.Neo4jRepository; + +public interface CityRepository extends Neo4jRepository { + + @Override + Page findAll(Pageable pageable); + +} diff --git a/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/ReactiveCityRepository.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/ReactiveCityRepository.java new file mode 100644 index 000000000000..5d9ba5195c96 --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/city/ReactiveCityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.neo4j.domain.city; + +import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; + +public interface ReactiveCityRepository extends ReactiveNeo4jRepository { + +} diff --git a/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/Country.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/Country.java new file mode 100644 index 000000000000..bda9f463fca6 --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/Country.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.neo4j.domain.country; + +import java.io.Serializable; + +import org.springframework.data.neo4j.core.schema.GeneratedValue; +import org.springframework.data.neo4j.core.schema.Id; +import org.springframework.data.neo4j.core.schema.Node; + +@Node +public class Country implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + private final String name; + + public Country(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + return getName(); + } + +} diff --git a/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/CountryRepository.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/CountryRepository.java new file mode 100644 index 000000000000..7f402f62c3e5 --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/CountryRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.neo4j.domain.country; + +import org.springframework.data.neo4j.repository.Neo4jRepository; + +public interface CountryRepository extends Neo4jRepository { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/ReactiveCountryRepository.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/ReactiveCountryRepository.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/ReactiveCountryRepository.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/ReactiveCountryRepository.java index 89b37de4a7a1..cbba18951926 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/country/ReactiveCountryRepository.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/country/ReactiveCountryRepository.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j.country; +package org.springframework.boot.data.neo4j.domain.country; import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository; diff --git a/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/empty/EmptyPackage.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/empty/EmptyPackage.java new file mode 100644 index 000000000000..34e3fbe07695 --- /dev/null +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/empty/EmptyPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.neo4j.domain.empty; + +public class EmptyPackage { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestNode.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestNode.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestNode.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestNode.java index 341e945748fd..860ac7e1d941 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestNode.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestNode.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j.scan; +package org.springframework.boot.data.neo4j.domain.scan; import org.springframework.data.neo4j.core.schema.GeneratedValue; import org.springframework.data.neo4j.core.schema.Id; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestNonAnnotated.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestNonAnnotated.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestNonAnnotated.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestNonAnnotated.java index 90bb2cda624e..dd517239afee 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestNonAnnotated.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestNonAnnotated.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j.scan; +package org.springframework.boot.data.neo4j.domain.scan; import org.springframework.data.neo4j.core.schema.GeneratedValue; import org.springframework.data.neo4j.core.schema.Id; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestPersistent.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestPersistent.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestPersistent.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestPersistent.java index bf0fd0205296..597f531a09a5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestPersistent.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestPersistent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j.scan; +package org.springframework.boot.data.neo4j.domain.scan; import org.springframework.data.annotation.Persistent; import org.springframework.data.neo4j.core.schema.GeneratedValue; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestRelationshipProperties.java b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestRelationshipProperties.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestRelationshipProperties.java rename to spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestRelationshipProperties.java index 12136ca9e861..073ef314fefb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/scan/TestRelationshipProperties.java +++ b/spring-boot-project/spring-boot-data-neo4j/src/test/java/org/springframework/boot/data/neo4j/domain/scan/TestRelationshipProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.neo4j.scan; +package org.springframework.boot.data.neo4j.domain.scan; import org.springframework.data.neo4j.core.schema.GeneratedValue; import org.springframework.data.neo4j.core.schema.Id; diff --git a/spring-boot-project/spring-boot-data-r2dbc/build.gradle b/spring-boot-project/spring-boot-data-r2dbc/build.gradle new file mode 100644 index 000000000000..05ed67064630 --- /dev/null +++ b/spring-boot-project/spring-boot-data-r2dbc/build.gradle @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data R2DBC" + +dependencies { + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-r2dbc")) + api("io.r2dbc:r2dbc-spi") + api("io.r2dbc:r2dbc-pool") + api("org.springframework.data:spring-data-r2dbc") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("io.projectreactor:reactor-test") + testImplementation("io.r2dbc:r2dbc-h2") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataAutoConfiguration.java b/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcDataAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataAutoConfiguration.java rename to spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcDataAutoConfiguration.java index 7570bfc3b3d2..3ae3cc957b6d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcDataAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.r2dbc; +package org.springframework.boot.data.r2dbc.autoconfigure; import java.util.ArrayList; import java.util.Collections; @@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.domain.EntityScanner; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.data.convert.CustomConversions; @@ -49,7 +49,7 @@ * * @author Mark Paluch * @author Oliver Drotbohm - * @since 2.3.0 + * @since 4.0.0 */ @AutoConfiguration(after = R2dbcAutoConfiguration.class) @ConditionalOnClass({ DatabaseClient.class, R2dbcEntityTemplate.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfiguration.java index ae801e0eb9b8..36622ad238c7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.r2dbc; +package org.springframework.boot.data.r2dbc.autoconfigure; import io.r2dbc.spi.ConnectionFactory; @@ -34,7 +34,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for Spring Data R2DBC Repositories. * * @author Mark Paluch - * @since 2.3.0 + * @since 4.0.0 * @see EnableR2dbcRepositories */ @AutoConfiguration(after = R2dbcDataAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfigureRegistrar.java b/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfigureRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfigureRegistrar.java rename to spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfigureRegistrar.java index c9cb8f403c4a..808f43a64694 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfigureRegistrar.java +++ b/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfigureRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.r2dbc; +package org.springframework.boot.data.r2dbc.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/package-info.java new file mode 100644 index 000000000000..e81aad4ebf35 --- /dev/null +++ b/spring-boot-project/spring-boot-data-r2dbc/src/main/java/org/springframework/boot/data/r2dbc/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-Configuration for Spring Data R2DBC. + */ +package org.springframework.boot.data.r2dbc.autoconfigure; diff --git a/spring-boot-project/spring-boot-data-r2dbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-r2dbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..6be98a6834a7 --- /dev/null +++ b/spring-boot-project/spring-boot-data-r2dbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,11 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.data.r2dbc.repositories.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable R2DBC repositories.", + "defaultValue": true + } + ] +} diff --git a/spring-boot-project/spring-boot-data-r2dbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-r2dbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..1c20cd5e98fb --- /dev/null +++ b/spring-boot-project/spring-boot-data-r2dbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.data.r2dbc.autoconfigure.R2dbcDataAutoConfiguration +org.springframework.boot.data.r2dbc.autoconfigure.R2dbcRepositoriesAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcDataAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcDataAutoConfigurationTests.java index 0a78a861eb44..7ba4aeeec12f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcDataAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.r2dbc; +package org.springframework.boot.data.r2dbc.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.r2dbc.city.City; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; +import org.springframework.boot.data.r2dbc.domain.city.City; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.data.domain.ManagedTypes; import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfigurationTests.java index a0a41e1802b6..5c03e20fbe28 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/autoconfigure/R2dbcRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.r2dbc; +package org.springframework.boot.data.r2dbc.autoconfigure; import java.time.Duration; @@ -25,10 +25,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.data.r2dbc.city.City; -import org.springframework.boot.autoconfigure.data.r2dbc.city.CityRepository; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; +import org.springframework.boot.data.r2dbc.domain.city.City; +import org.springframework.boot.data.r2dbc.domain.city.CityRepository; +import org.springframework.boot.data.r2dbc.domain.empty.EmptyDataPackage; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; diff --git a/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/city/City.java b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/city/City.java new file mode 100644 index 000000000000..770f5363dbad --- /dev/null +++ b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/city/City.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.r2dbc.domain.city; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Table; + +@Table("CITY") +public class City { + + @Id + private Long id; + + private String name; + + private String state; + + private String country; + + private String map; + + protected City() { + } + + public City(String name, String country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/city/CityRepository.java new file mode 100644 index 000000000000..21a0eca04bbe --- /dev/null +++ b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/city/CityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.r2dbc.domain.city; + +import org.springframework.data.repository.reactive.ReactiveCrudRepository; + +public interface CityRepository extends ReactiveCrudRepository { + +} diff --git a/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/empty/EmptyDataPackage.java b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/empty/EmptyDataPackage.java new file mode 100644 index 000000000000..7617d480cd02 --- /dev/null +++ b/spring-boot-project/spring-boot-data-r2dbc/src/test/java/org/springframework/boot/data/r2dbc/domain/empty/EmptyDataPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.r2dbc.domain.empty; + +public class EmptyDataPackage { + +} diff --git a/spring-boot-project/spring-boot-data-redis/build.gradle b/spring-boot-project/spring-boot-data-redis/build.gradle new file mode 100644 index 000000000000..500c7555399c --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/build.gradle @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data Redis" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-data-commons")) + api("io.lettuce:lettuce-core") + api("org.springframework.data:spring-data-redis") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + implementation(project(":spring-boot-project:spring-boot-netty")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("com.redis:testcontainers-redis") + optional("redis.clients:jedis") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-testcontainers"))) + dockerTestImplementation("ch.qos.logback:logback-classic") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("io.projectreactor:reactor-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesAutoConfigurationTests.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesAutoConfigurationTests.java index e731bb821377..76138481bd38 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import com.redis.testcontainers.RedisContainer; import org.junit.jupiter.api.AfterEach; @@ -25,10 +25,9 @@ import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.alt.redis.CityRedisRepository; -import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; -import org.springframework.boot.autoconfigure.data.redis.city.City; -import org.springframework.boot.autoconfigure.data.redis.city.CityRepository; +import org.springframework.boot.data.redis.domain.city.City; +import org.springframework.boot.data.redis.domain.city.CityRepository; +import org.springframework.boot.data.redis.domain.empty.EmptyPackage; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -83,7 +82,7 @@ void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { this.context.register(CustomizedConfiguration.class, RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); - assertThat(this.context.getBean(CityRedisRepository.class)).isNotNull(); + assertThat(this.context.getBean(CityRepository.class)).isNotNull(); } @Configuration(proxyBeanMethods = false) @@ -93,14 +92,14 @@ static class TestConfiguration { } @Configuration(proxyBeanMethods = false) - @TestAutoConfigurationPackage(EmptyDataPackage.class) + @TestAutoConfigurationPackage(EmptyPackage.class) static class EmptyConfiguration { } @Configuration(proxyBeanMethods = false) @TestAutoConfigurationPackage(RedisRepositoriesAutoConfigurationTests.class) - @EnableRedisRepositories(basePackageClasses = CityRedisRepository.class) + @EnableRedisRepositories(basePackageClasses = CityRepository.class) static class CustomizedConfiguration { } diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/redis/RedisDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/docker/compose/RedisDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/redis/RedisDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/docker/compose/RedisDockerComposeConnectionDetailsFactoryIntegrationTests.java index 0712765ea78d..92a413ad1563 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/redis/RedisDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/docker/compose/RedisDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.redis; +package org.springframework.boot.data.redis.docker.compose; import javax.net.ssl.SSLContext; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails.Standalone; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Standalone; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/CustomRedisContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/CustomRedisContainerConnectionDetailsFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/CustomRedisContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/CustomRedisContainerConnectionDetailsFactoryTests.java index b23911c5d05d..b56d46b73acd 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/CustomRedisContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/CustomRedisContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.redis; +package org.springframework.boot.data.redis.testcontainers; import java.util.Map; @@ -22,9 +22,9 @@ import com.redis.testcontainers.RedisStackContainer; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testcontainers.service.connection.TestContainerConnectionSource; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisContainerConnectionDetailsFactoryTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisContainerConnectionDetailsFactoryTests.java index 2e1f889ba26c..5c1ea8ca3f8b 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.redis; +package org.springframework.boot.data.redis.testcontainers; import com.redis.testcontainers.RedisContainer; import org.junit.jupiter.api.Test; @@ -23,8 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisStackContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisStackContainerConnectionDetailsFactoryTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisStackContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisStackContainerConnectionDetailsFactoryTests.java index d2efb1f7c4d7..583819788b1e 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisStackContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisStackContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.redis; +package org.springframework.boot.data.redis.testcontainers; import com.redis.testcontainers.RedisStackContainer; import org.junit.jupiter.api.Test; @@ -23,8 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisStackServerContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisStackServerContainerConnectionDetailsFactoryTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisStackServerContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisStackServerContainerConnectionDetailsFactoryTests.java index 218dc84e5782..1a089a62c345 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redis/RedisStackServerContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/dockerTest/java/org/springframework/boot/data/redis/testcontainers/RedisStackServerContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.redis; +package org.springframework.boot.data.redis.testcontainers; import org.junit.jupiter.api.Test; import org.testcontainers.junit.jupiter.Container; @@ -22,8 +22,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.RedisStackServerContainer; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/ca.crt b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/ca.crt similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/ca.crt rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/ca.crt diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/client.crt b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/client.crt similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/client.crt rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/client.crt diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/client.key b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/client.key similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/client.key rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/client.key diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/redis-bitnami-compose.yaml b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/redis-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/redis-bitnami-compose.yaml rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/redis-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/redis-compose.yaml b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/redis-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/redis-compose.yaml rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/redis-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/redis-ssl-compose.yaml b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/redis-ssl-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/redis-ssl-compose.yaml rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/redis-ssl-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/server.crt b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/server.crt similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/server.crt rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/server.crt diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/server.key b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/server.key similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/redis/server.key rename to spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/org/springframework/boot/data/redis/docker/compose/server.key diff --git a/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/ClientResourcesBuilderCustomizer.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/ClientResourcesBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/ClientResourcesBuilderCustomizer.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/ClientResourcesBuilderCustomizer.java index fd7fc0005e49..f71886183503 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/ClientResourcesBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/ClientResourcesBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import io.lettuce.core.resource.ClientResources; import io.lettuce.core.resource.ClientResources.Builder; @@ -25,7 +25,7 @@ * auto-configuration. * * @author Stephane Nicoll - * @since 2.6.0 + * @since 4.0.0 */ public interface ClientResourcesBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisClientConfigurationBuilderCustomizer.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/JedisClientConfigurationBuilderCustomizer.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisClientConfigurationBuilderCustomizer.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/JedisClientConfigurationBuilderCustomizer.java index 7d8e7001a057..f52ed5ceb25b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisClientConfigurationBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/JedisClientConfigurationBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; import org.springframework.data.redis.connection.jedis.JedisClientConfiguration.JedisClientConfigurationBuilder; @@ -26,7 +26,7 @@ * auto-configuration. * * @author Mark Paluch - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface JedisClientConfigurationBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/JedisConnectionConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/JedisConnectionConfiguration.java index 503a947ececd..75af6ccb4b77 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/JedisConnectionConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import javax.net.ssl.SSLParameters; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientConfigurationBuilderCustomizer.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceClientConfigurationBuilderCustomizer.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientConfigurationBuilderCustomizer.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceClientConfigurationBuilderCustomizer.java index 9823516fb79d..70037e9d412a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientConfigurationBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceClientConfigurationBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration.LettuceClientConfigurationBuilder; @@ -28,7 +28,7 @@ * configuration, use {@link LettuceClientOptionsBuilderCustomizer} instead. * * @author Mark Paluch - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface LettuceClientConfigurationBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientOptionsBuilderCustomizer.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceClientOptionsBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientOptionsBuilderCustomizer.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceClientOptionsBuilderCustomizer.java index ea9600f3cff4..7bac09b9b221 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientOptionsBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceClientOptionsBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import io.lettuce.core.ClientOptions; import io.lettuce.core.ClientOptions.Builder; @@ -28,7 +28,7 @@ * configuration, use {@link LettuceClientConfigurationBuilderCustomizer} instead. * * @author Soohyun Lim - * @since 3.4.0 + * @since 4.0.0 */ @FunctionalInterface public interface LettuceClientOptionsBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceConnectionConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceConnectionConfiguration.java index da72b63bfcbb..904265af84b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceConnectionConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.time.Duration; @@ -36,9 +36,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; -import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Lettuce.Cluster.Refresh; -import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Pool; import org.springframework.boot.autoconfigure.thread.Threading; +import org.springframework.boot.data.redis.autoconfigure.RedisProperties.Lettuce.Cluster.Refresh; +import org.springframework.boot.data.redis.autoconfigure.RedisProperties.Pool; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslOptions; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/LettuceMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceMetricsAutoConfiguration.java similarity index 76% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/LettuceMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceMetricsAutoConfiguration.java index 54503caf8842..e5a1f68ed51d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/LettuceMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceMetricsAutoConfiguration.java @@ -14,21 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.redis; +package org.springframework.boot.data.redis.autoconfigure; import io.lettuce.core.RedisClient; import io.lettuce.core.metrics.MicrometerCommandLatencyRecorder; import io.lettuce.core.metrics.MicrometerOptions; import io.micrometer.core.instrument.MeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.redis.ClientResourcesBuilderCustomizer; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -36,11 +32,11 @@ * * @author Antonin Arquey * @author Yanming Zhou - * @since 2.6.0 + * @since 4.0.0 */ @AutoConfiguration(before = RedisAutoConfiguration.class, - after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) -@ConditionalOnClass({ RedisClient.class, MicrometerCommandLatencyRecorder.class }) + afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") +@ConditionalOnClass({ RedisClient.class, MicrometerCommandLatencyRecorder.class, MeterRegistry.class }) @ConditionalOnBean(MeterRegistry.class) public class LettuceMetricsAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/PropertiesRedisConnectionDetails.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/PropertiesRedisConnectionDetails.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/PropertiesRedisConnectionDetails.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/PropertiesRedisConnectionDetails.java index 5fbf179fe267..7a4fa4c85ba4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/PropertiesRedisConnectionDetails.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/PropertiesRedisConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfiguration.java index 4f0dc6148a80..42139edd985d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -43,7 +43,7 @@ * @author Stephane Nicoll * @author Marco Aust * @author Mark Paluch - * @since 1.0.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(RedisOperations.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisConnectionConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisConnectionConfiguration.java index e8a8e75b288c..a65b09f2e6e8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisConnectionConfiguration.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails.Cluster; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails.Node; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails.Sentinel; -import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Pool; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Cluster; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Node; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Sentinel; +import org.springframework.boot.data.redis.autoconfigure.RedisProperties.Pool; import org.springframework.boot.ssl.SslBundle; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisNode; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionDetails.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisConnectionDetails.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionDetails.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisConnectionDetails.java index 4c38c2b1af92..c6fd15511cd4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionDetails.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.util.List; @@ -27,7 +27,7 @@ * * @author Moritz Halbritter * @author Andy Wilkinson - * @since 3.1.0 + * @since 4.0.0 */ public interface RedisConnectionDetails extends ConnectionDetails { @@ -102,7 +102,6 @@ default int getDatabase() { /** * SSL bundle to use. * @return the SSL bundle to use - * @since 3.5.0 */ default SslBundle getSslBundle() { return null; @@ -124,7 +123,6 @@ static Standalone of(String host, int port) { * @param port the port * @param sslBundle the SSL bundle * @return the new instance - * @since 3.5.0 */ static Standalone of(String host, int port, SslBundle sslBundle) { return of(host, port, 0, sslBundle); @@ -148,7 +146,6 @@ static Standalone of(String host, int port, int database) { * @param database the database * @param sslBundle the SSL bundle * @return the new instance - * @since 3.5.0 */ static Standalone of(String host, int port, int database, SslBundle sslBundle) { Assert.hasLength(host, "'host' must not be empty"); @@ -216,7 +213,6 @@ interface Sentinel { /** * SSL bundle to use. * @return the SSL bundle to use - * @since 3.5.0 */ default SslBundle getSslBundle() { return null; @@ -239,7 +235,6 @@ interface Cluster { /** * SSL bundle to use. * @return the SSL bundle to use - * @since 3.5.0 */ default SslBundle getSslBundle() { return null; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisProperties.java index ad2f19d29bec..3b821283facf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.time.Duration; import java.util.List; @@ -32,7 +32,7 @@ * @author Stephane Nicoll * @author Scott Frederick * @author Yanming Zhou - * @since 1.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.data.redis") public class RedisProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisReactiveAutoConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisReactiveAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisReactiveAutoConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisReactiveAutoConfiguration.java index fbabc9c21b80..7c3a88431fe5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisReactiveAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisReactiveAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import reactor.core.publisher.Flux; @@ -37,7 +37,7 @@ * * @author Mark Paluch * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = RedisAutoConfiguration.class) @ConditionalOnClass({ ReactiveRedisConnectionFactory.class, ReactiveRedisTemplate.class, Flux.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesAutoConfiguration.java index 544d3ff4cd80..14e314524383 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -33,7 +33,7 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.4.0 + * @since 4.0.0 * @see EnableRedisRepositories */ @AutoConfiguration(after = RedisAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesRegistrar.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesRegistrar.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesRegistrar.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesRegistrar.java index 3d5b623c712b..db3dd541ac32 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesRegistrar.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisRepositoriesRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.lang.annotation.Annotation; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrl.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrl.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrl.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrl.java index 713634bf930d..a846470dd0b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrl.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.net.URI; import java.net.URISyntaxException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxException.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxException.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxException.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxException.java index 18f1ff6d63d3..5729319c5312 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxException.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; /** * Exception thrown when a Redis URL is malformed or invalid. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxFailureAnalyzer.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxFailureAnalyzer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxFailureAnalyzer.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxFailureAnalyzer.java index a74adc1458a3..0ca1542f8b97 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.net.URI; import java.net.URISyntaxException; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/RedisHealthContributorAutoConfiguration.java similarity index 75% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/RedisHealthContributorAutoConfiguration.java index b49149c2c568..49f986202adb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/RedisHealthContributorAutoConfiguration.java @@ -14,19 +14,20 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure.health; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.data.redis.RedisHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.data.redis.health.RedisHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -37,10 +38,10 @@ * @author Richard Santana * @author Stephane Nicoll * @author Mark Paluch - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = { RedisAutoConfiguration.class, RedisReactiveHealthContributorAutoConfiguration.class }) -@ConditionalOnClass(RedisConnectionFactory.class) +@ConditionalOnClass({ RedisConnectionFactory.class, HealthIndicator.class, ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(RedisConnectionFactory.class) @ConditionalOnEnabledHealthIndicator("redis") public class RedisHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisReactiveHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/RedisReactiveHealthContributorAutoConfiguration.java similarity index 77% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisReactiveHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/RedisReactiveHealthContributorAutoConfiguration.java index 3fa77d6cb861..de29b2c15875 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisReactiveHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/RedisReactiveHealthContributorAutoConfiguration.java @@ -14,21 +14,22 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure.health; import reactor.core.publisher.Flux; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.data.redis.RedisReactiveHealthIndicator; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisReactiveAutoConfiguration; +import org.springframework.boot.data.redis.health.RedisReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; @@ -40,10 +41,11 @@ * @author Richard Santana * @author Stephane Nicoll * @author Mark Paluch - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = RedisReactiveAutoConfiguration.class) -@ConditionalOnClass({ ReactiveRedisConnectionFactory.class, Flux.class }) +@ConditionalOnClass({ ReactiveRedisConnectionFactory.class, Flux.class, ReactiveHealthIndicator.class, + ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(ReactiveRedisConnectionFactory.class) @ConditionalOnEnabledHealthIndicator("redis") public class RedisReactiveHealthContributorAutoConfiguration extends diff --git a/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..71f5680b8e5b --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data Redis health. + */ +package org.springframework.boot.data.redis.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/package-info.java new file mode 100644 index 000000000000..f1dbfe65a61d --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data Redis. + */ +package org.springframework.boot.data.redis.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/redis/RedisDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/docker/compose/RedisDockerComposeConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/redis/RedisDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/docker/compose/RedisDockerComposeConnectionDetailsFactory.java index 21dc20619cc5..2821c4bd5556 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/redis/RedisDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/docker/compose/RedisDockerComposeConnectionDetailsFactory.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.redis; +package org.springframework.boot.data.redis.docker.compose; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; diff --git a/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/docker/compose/package-info.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/docker/compose/package-info.java new file mode 100644 index 000000000000..ae342b260ed2 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Redis service connections. + */ +package org.springframework.boot.data.redis.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisHealth.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisHealth.java similarity index 81% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisHealth.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisHealth.java index 836d9d7b402e..6cb22ce5bb82 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisHealth.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisHealth.java @@ -14,12 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.data.redis; +package org.springframework.boot.data.redis.health; import java.util.Properties; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Health.Builder; +import org.springframework.boot.health.contributor.Health; import org.springframework.data.redis.connection.ClusterInfo; /** @@ -33,12 +32,12 @@ final class RedisHealth { private RedisHealth() { } - static Builder up(Health.Builder builder, Properties info) { + static Health.Builder up(Health.Builder builder, Properties info) { builder.withDetail("version", info.getProperty("redis_version")); return builder.up(); } - static Builder fromClusterInfo(Health.Builder builder, ClusterInfo clusterInfo) { + static Health.Builder fromClusterInfo(Health.Builder builder, ClusterInfo clusterInfo) { builder.withDetail("cluster_size", clusterInfo.getClusterSize()); builder.withDetail("slots_up", clusterInfo.getSlotsOk()); builder.withDetail("slots_fail", clusterInfo.getSlotsFail()); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisHealthIndicator.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisHealthIndicator.java similarity index 88% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisHealthIndicator.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisHealthIndicator.java index a53e74d44da5..a218a8607ba0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisHealthIndicator.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisHealthIndicator.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.data.redis; +package org.springframework.boot.data.redis.health; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.data.redis.connection.RedisClusterConnection; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -32,7 +32,7 @@ * @author Christian Dupuis * @author Richard Santana * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ public class RedisHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisReactiveHealthIndicator.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisReactiveHealthIndicator.java similarity index 90% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisReactiveHealthIndicator.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisReactiveHealthIndicator.java index 4a1de9702dc7..900c2d299652 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/RedisReactiveHealthIndicator.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.actuate.data.redis; +package org.springframework.boot.data.redis.health; import java.util.Properties; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; import org.springframework.data.redis.connection.ClusterInfo; import org.springframework.data.redis.connection.ReactiveRedisClusterConnection; import org.springframework.data.redis.connection.ReactiveRedisConnection; @@ -36,7 +36,7 @@ * @author Mark Paluch * @author Artsiom Yudovin * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ public class RedisReactiveHealthIndicator extends AbstractReactiveHealthIndicator { diff --git a/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/package-info.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/package-info.java new file mode 100644 index 000000000000..52c54ba4b9bf --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Redis health integration using Spring Data Redis. + */ +package org.springframework.boot.data.redis.health; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redis/RedisContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/testcontainers/RedisContainerConnectionDetailsFactory.java similarity index 87% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redis/RedisContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/testcontainers/RedisContainerConnectionDetailsFactory.java index a5adc69dac4c..afc5770b4352 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redis/RedisContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/testcontainers/RedisContainerConnectionDetailsFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.redis; +package org.springframework.boot.data.redis.testcontainers; import java.util.List; @@ -23,7 +23,7 @@ import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; @@ -54,8 +54,10 @@ class RedisContainerConnectionDetailsFactory protected boolean sourceAccepts(ContainerConnectionSource> source, Class requiredContainerType, Class requiredConnectionDetailsType) { return super.sourceAccepts(source, requiredContainerType, requiredConnectionDetailsType) - || source.accepts(ANY_CONNECTION_NAME, RedisContainer.class, requiredConnectionDetailsType) - || source.accepts(ANY_CONNECTION_NAME, RedisStackContainer.class, requiredConnectionDetailsType); + || source.accepts(ContainerConnectionDetailsFactory.ANY_CONNECTION_NAME, RedisContainer.class, + requiredConnectionDetailsType) + || source.accepts(ContainerConnectionDetailsFactory.ANY_CONNECTION_NAME, RedisStackContainer.class, + requiredConnectionDetailsType); } @Override diff --git a/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/testcontainers/package-info.java b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/testcontainers/package-info.java new file mode 100644 index 000000000000..c09f38df7ac4 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Redis service connections. + */ +package org.springframework.boot.data.redis.testcontainers; diff --git a/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..f15399905266 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,325 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.health.redis.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Redis health check.", + "defaultValue": true + }, + { + "name": "spring.data.redis.repositories.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Redis repositories.", + "defaultValue": true + }, + { + "name": "spring.data.redis.ssl", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.data.redis.ssl.enabled", + "level": "error" + } + }, + { + "name": "spring.redis.client-name", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.redis.client-name", + "level": "error" + } + }, + { + "name": "spring.redis.client-type", + "type": "org.springframework.boot.data.redis.autoconfigure.RedisProperties$ClientType", + "deprecation": { + "replacement": "spring.data.redis.client-type", + "level": "error" + } + }, + { + "name": "spring.redis.cluster.max-redirects", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.data.redis.cluster.max-redirects", + "level": "error" + } + }, + { + "name": "spring.redis.cluster.nodes", + "type": "java.util.List", + "deprecation": { + "replacement": "spring.data.redis.cluster.nodes", + "level": "error" + } + }, + { + "name": "spring.redis.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "replacement": "spring.data.redis.connect-timeout", + "level": "error" + } + }, + { + "name": "spring.redis.database", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.data.redis.database", + "level": "error" + } + }, + { + "name": "spring.redis.host", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.redis.host", + "level": "error" + } + }, + { + "name": "spring.redis.jedis.pool.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.jedis.pool.max-active", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.jedis.pool.max-idle", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.jedis.pool.max-wait", + "type": "java.time.Duration", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.jedis.pool.min-idle", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.jedis.pool.time-between-eviction-runs", + "type": "java.time.Duration", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.cluster.refresh.adaptive", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.data.redis.lettuce.cluster.refresh.adaptive", + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.cluster.refresh.dynamic-refresh-sources", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.data.redis.lettuce.cluster.refresh.dynamic-refresh-sources", + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.cluster.refresh.period", + "type": "java.time.Duration", + "deprecation": { + "replacement": "spring.data.redis.lettuce.cluster.refresh.period", + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.pool.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.pool.max-active", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.pool.max-idle", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.pool.max-wait", + "type": "java.time.Duration", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.pool.min-idle", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.pool.time-between-eviction-runs", + "type": "java.time.Duration", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.redis.lettuce.shutdown-timeout", + "type": "java.time.Duration", + "deprecation": { + "replacement": "spring.data.redis.lettuce.shutdown-timeout", + "level": "error" + } + }, + { + "name": "spring.redis.password", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.redis.password", + "level": "error" + } + }, + { + "name": "spring.redis.port", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.data.redis.port", + "level": "error" + } + }, + { + "name": "spring.redis.sentinel.master", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.redis.sentinel.master", + "level": "error" + } + }, + { + "name": "spring.redis.sentinel.nodes", + "type": "java.util.List", + "deprecation": { + "replacement": "spring.data.redis.sentinel.nodes", + "level": "error" + } + }, + { + "name": "spring.redis.sentinel.password", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.redis.sentinel.password", + "level": "error" + } + }, + { + "name": "spring.redis.sentinel.username", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.redis.sentinel.username", + "level": "error" + } + }, + { + "name": "spring.redis.ssl", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.data.redis.ssl", + "level": "error" + } + }, + { + "name": "spring.redis.timeout", + "type": "java.time.Duration", + "deprecation": { + "replacement": "spring.data.redis.timeout", + "level": "error" + } + }, + { + "name": "spring.redis.url", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.redis.url", + "level": "error" + } + }, + { + "name": "spring.redis.username", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.redis.username", + "level": "error" + } + } + ], + "hints": [ + { + "name": "spring.data.redis.lettuce.read-from", + "values": [ + { + "value": "any", + "description": "Read from any node." + }, + { + "value": "any-replica", + "description": "Read from any replica node." + }, + { + "value": "lowest-latency", + "description": "Read from the node with the lowest latency during topology discovery." + }, + { + "value": "regex:", + "description": "Read from any node that has RedisURI matching with the given pattern." + }, + { + "value": "replica", + "description": "Read from the replica only." + }, + { + "value": "replica-preferred", + "description": "Read preferred from replica and fall back to upstream if no replica is available." + }, + { + "value": "subnet:", + "description": "Read from any node in the subnets." + }, + { + "value": "upstream", + "description": "Read from the upstream only." + }, + { + "value": "upstream-preferred", + "description": "Read preferred from the upstream and fall back to a replica if the upstream is not available." + } + ], + "providers": [ + { + "name": "any" + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..ba4c19ec20ea --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/spring.factories @@ -0,0 +1,9 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.data.redis.docker.compose.RedisDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.data.redis.testcontainers.RedisContainerConnectionDetailsFactory + +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.boot.data.redis.autoconfigure.RedisUrlSyntaxFailureAnalyzer + diff --git a/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..3e923829fb82 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,6 @@ +org.springframework.boot.data.redis.autoconfigure.LettuceMetricsAutoConfiguration +org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration +org.springframework.boot.data.redis.autoconfigure.RedisReactiveAutoConfiguration +org.springframework.boot.data.redis.autoconfigure.RedisRepositoriesAutoConfiguration +org.springframework.boot.data.redis.autoconfigure.health.RedisHealthContributorAutoConfiguration +org.springframework.boot.data.redis.autoconfigure.health.RedisReactiveHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/LettuceMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/LettuceMetricsAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/LettuceMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/LettuceMetricsAutoConfigurationTests.java index a17b537d446e..db1fc83423d6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/redis/LettuceMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/LettuceMetricsAutoConfigurationTests.java @@ -14,16 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.redis; +package org.springframework.boot.data.redis.autoconfigure; import io.lettuce.core.metrics.MicrometerCommandLatencyRecorder; import io.lettuce.core.metrics.MicrometerOptions; import io.lettuce.core.resource.ClientResources; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,7 +42,7 @@ class LettuceMetricsAutoConfigurationTests { @Test void whenThereIsAMeterRegistryThenCommandLatencyRecorderIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) .run((context) -> { ClientResources clientResources = context.getBean(LettuceConnectionFactory.class).getClientResources(); @@ -54,7 +53,7 @@ void whenThereIsAMeterRegistryThenCommandLatencyRecorderIsAdded() { @Test void autoConfiguredMicrometerOptionsUsesLettucesDefaults() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) .run((context) -> { MicrometerOptions micrometerOptions = context.getBean(MicrometerOptions.class); @@ -68,7 +67,7 @@ void autoConfiguredMicrometerOptionsUsesLettucesDefaults() { @Test void whenUserDefinesAMicrometerOptionsBeanThenCommandLatencyRecorderUsesIt() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) .withUserConfiguration(CustomMicrometerOptionsConfiguration.class) .run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/PropertiesRedisConnectionDetailsTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/PropertiesRedisConnectionDetailsTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/PropertiesRedisConnectionDetailsTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/PropertiesRedisConnectionDetailsTests.java index 88cf9b7e81ae..9e87ca435e0f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/PropertiesRedisConnectionDetailsTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/PropertiesRedisConnectionDetailsTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails.Node; +import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Node; import org.springframework.boot.ssl.DefaultSslBundleRegistry; import org.springframework.boot.ssl.SslBundle; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationJedisTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationJedisTests.java index bdd92d0e6b58..bbe6f7845f8a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationJedisTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationLettuceWithoutCommonsPool2Tests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationLettuceWithoutCommonsPool2Tests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationLettuceWithoutCommonsPool2Tests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationLettuceWithoutCommonsPool2Tests.java index ba55bbf7e41a..de6367c7a748 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationLettuceWithoutCommonsPool2Tests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationLettuceWithoutCommonsPool2Tests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationTests.java index 51c4efc37fe0..fc1b8dba6f55 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.time.Duration; import java.util.Arrays; @@ -45,8 +45,8 @@ import org.junit.jupiter.params.provider.MethodSource; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Pool; import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisProperties.Pool; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisPropertiesTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisPropertiesTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisPropertiesTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisPropertiesTests.java index 9fe49f174eec..a71e9a947609 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisPropertiesTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import io.lettuce.core.cluster.ClusterTopologyRefreshOptions; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Lettuce; +import org.springframework.boot.data.redis.autoconfigure.RedisProperties.Lettuce; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisReactiveAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisReactiveAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisReactiveAutoConfigurationTests.java index fe14b537ef0f..d1ac253d5867 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisReactiveAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxFailureAnalyzerTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxFailureAnalyzerTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxFailureAnalyzerTests.java index fd31bfd51a55..6483aa51f063 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisUrlSyntaxFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/RedisUrlSyntaxFailureAnalyzerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/health/RedisHealthContributorAutoConfigurationTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/health/RedisHealthContributorAutoConfigurationTests.java index afa771b3084e..561cb395002f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/health/RedisHealthContributorAutoConfigurationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.data.redis.RedisHealthIndicator; -import org.springframework.boot.actuate.data.redis.RedisReactiveHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.data.redis.health.RedisHealthIndicator; +import org.springframework.boot.data.redis.health.RedisReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisReactiveHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/health/RedisReactiveHealthContributorAutoConfigurationTests.java similarity index 84% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisReactiveHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/health/RedisReactiveHealthContributorAutoConfigurationTests.java index b14c144227e9..879fddc92c51 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisReactiveHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/autoconfigure/health/RedisReactiveHealthContributorAutoConfigurationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.data.redis; +package org.springframework.boot.data.redis.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.data.redis.RedisHealthIndicator; -import org.springframework.boot.actuate.data.redis.RedisReactiveHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.data.redis.health.RedisHealthIndicator; +import org.springframework.boot.data.redis.health.RedisReactiveHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/city/City.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/city/City.java new file mode 100644 index 000000000000..80d6921e6519 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/city/City.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.redis.domain.city; + +import java.io.Serializable; + +import org.springframework.data.annotation.Id; +import org.springframework.data.redis.core.RedisHash; + +@RedisHash("cities") +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + private Long id; + + private String name; + + private String state; + + private String country; + + private String map; + + protected City() { + } + + public City(String name, String country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/city/CityRepository.java new file mode 100644 index 000000000000..f6b5f4a225e9 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/city/CityRepository.java @@ -0,0 +1,31 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.redis.domain.city; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.Repository; + +public interface CityRepository extends Repository { + + Page findAll(Pageable pageable); + + Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); + + City findByNameAndCountryAllIgnoringCase(String name, String country); + +} diff --git a/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/empty/EmptyPackage.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/empty/EmptyPackage.java new file mode 100644 index 000000000000..4569b144c8c0 --- /dev/null +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/domain/empty/EmptyPackage.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.redis.domain.empty; + +public class EmptyPackage { + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisHealthIndicatorTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/health/RedisHealthIndicatorTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisHealthIndicatorTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/health/RedisHealthIndicatorTests.java index b18dc8bb46b0..6c6ccc985276 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/health/RedisHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.redis; +package org.springframework.boot.data.redis.health; import java.util.Arrays; import java.util.List; @@ -22,9 +22,8 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.data.redis.RedisHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.data.redis.RedisConnectionFailureException; import org.springframework.data.redis.connection.ClusterInfo; import org.springframework.data.redis.connection.RedisClusterConnection; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/health/RedisReactiveHealthIndicatorTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicatorTests.java rename to spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/health/RedisReactiveHealthIndicatorTests.java index e9a1ed744e2d..7f0a31129071 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-data-redis/src/test/java/org/springframework/boot/data/redis/health/RedisReactiveHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.redis; +package org.springframework.boot.data.redis.health; import java.time.Duration; import java.util.Properties; @@ -24,9 +24,8 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import org.springframework.boot.actuate.data.redis.RedisReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.data.redis.RedisConnectionFailureException; import org.springframework.data.redis.connection.ClusterInfo; import org.springframework.data.redis.connection.ReactiveRedisClusterConnection; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/data/redis/test.jks b/spring-boot-project/spring-boot-data-redis/src/test/resources/org/springframework/boot/data/redis/autoconfigure/test.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/data/redis/test.jks rename to spring-boot-project/spring-boot-data-redis/src/test/resources/org/springframework/boot/data/redis/autoconfigure/test.jks diff --git a/spring-boot-project/spring-boot-data-rest/build.gradle b/spring-boot-project/spring-boot-data-rest/build.gradle new file mode 100644 index 000000000000..49d98786f382 --- /dev/null +++ b/spring-boot-project/spring-boot-data-rest/build.gradle @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Data REST" + +dependencies { + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-jackson")) + api(project(":spring-boot-project:spring-boot-webmvc")) + api("org.springframework.data:spring-data-rest-webmvc") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-data-jpa")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("jakarta.servlet:jakarta.servlet-api") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfiguration.java b/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestMvcAutoConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfiguration.java rename to spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestMvcAutoConfiguration.java index cf4beed49ea8..c3c8c8748ccc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestMvcAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.rest; +package org.springframework.boot.data.rest.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -23,9 +23,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.data.autoconfigure.web.SpringDataWebAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; @@ -45,9 +45,9 @@ * @author Rob Winch * @author Stephane Nicoll * @author Andy Wilkinson - * @since 1.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { HttpMessageConvertersAutoConfiguration.class, JacksonAutoConfiguration.class }) +@AutoConfiguration(before = SpringDataWebAutoConfiguration.class, after = JacksonAutoConfiguration.class) @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnMissingBean(RepositoryRestMvcConfiguration.class) @ConditionalOnClass(RepositoryRestMvcConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestProperties.java b/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestProperties.java rename to spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestProperties.java index 1d4816004c87..40906f250cdb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestProperties.java +++ b/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.rest; +package org.springframework.boot.data.rest.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; @@ -26,7 +26,7 @@ * Configuration properties for Spring Data REST. * * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.data.rest") public class RepositoryRestProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/SpringBootRepositoryRestConfigurer.java b/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/SpringBootRepositoryRestConfigurer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/SpringBootRepositoryRestConfigurer.java rename to spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/SpringBootRepositoryRestConfigurer.java index 2967a4b8f42e..479e33023b1f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/SpringBootRepositoryRestConfigurer.java +++ b/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/SpringBootRepositoryRestConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.rest; +package org.springframework.boot.data.rest.autoconfigure; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/package-info.java b/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/package-info.java new file mode 100644 index 000000000000..3bb7cbeaf6be --- /dev/null +++ b/spring-boot-project/spring-boot-data-rest/src/main/java/org/springframework/boot/data/rest/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Data REST. + */ +package org.springframework.boot.data.rest.autoconfigure; diff --git a/spring-boot-project/spring-boot-data-rest/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-data-rest/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..86483ab01f68 --- /dev/null +++ b/spring-boot-project/spring-boot-data-rest/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestMvcAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfigurationTests.java rename to spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestMvcAutoConfigurationTests.java index e10ebd7e736e..9f8ceadc46d2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/autoconfigure/RepositoryRestMvcAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.data.rest; +package org.springframework.boot.data.rest.autoconfigure; import java.net.URI; @@ -24,13 +24,13 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.data.jpa.city.City; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.data.jpa.autoconfigure.JpaRepositoriesAutoConfiguration; +import org.springframework.boot.data.rest.domain.city.City; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/domain/city/City.java b/spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/domain/city/City.java new file mode 100644 index 000000000000..82a993fb8cb1 --- /dev/null +++ b/spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/domain/city/City.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.rest.domain.city; + +import java.io.Serializable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + @Column(nullable = false) + private String country; + + @Column(nullable = false) + private String map; + + protected City() { + } + + public City(String name, String country) { + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/domain/city/CityRepository.java b/spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/domain/city/CityRepository.java new file mode 100644 index 000000000000..24b8eb167dd6 --- /dev/null +++ b/spring-boot-project/spring-boot-data-rest/src/test/java/org/springframework/boot/data/rest/domain/city/CityRepository.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.data.rest.domain.city; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CityRepository extends JpaRepository { + + @Override + Page findAll(Pageable pageable); + + Page findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable); + + City findByNameAndCountryAllIgnoringCase(String name, String country); + +} diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 2f9f4b4b92ac..7c4d76efc1c6 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1983,20 +1983,98 @@ bom { group("org.springframework.boot") { modules = [ "spring-boot", + "spring-boot-activemq", "spring-boot-actuator", "spring-boot-actuator-autoconfigure", + "spring-boot-amqp", + "spring-boot-artemis", "spring-boot-autoconfigure", "spring-boot-autoconfigure-processor", + "spring-boot-batch", "spring-boot-buildpack-platform", + "spring-boot-cache", + "spring-boot-cassandra", + "spring-boot-cloudfoundry", "spring-boot-configuration-metadata", "spring-boot-configuration-processor", + "spring-boot-couchbase", + "spring-boot-data-cassandra", + "spring-boot-data-commons", + "spring-boot-data-couchbase", + "spring-boot-data-elasticsearch", + "spring-boot-data-jdbc", + "spring-boot-data-jpa", + "spring-boot-data-ldap", + "spring-boot-data-mongodb", + "spring-boot-data-neo4j", + "spring-boot-data-r2dbc", + "spring-boot-data-redis", + "spring-boot-data-rest", "spring-boot-devtools", "spring-boot-docker-compose", + "spring-boot-elasticsearch", + "spring-boot-flyway", + "spring-boot-freemarker", + "spring-boot-graphql", + "spring-boot-graphql-test", + "spring-boot-groovy-templates", + "spring-boot-gson", + "spring-boot-h2console", + "spring-boot-hateoas", + "spring-boot-hazelcast", + "spring-boot-health", + "spring-boot-hibernate", + "spring-boot-http", + "spring-boot-http-client", + "spring-boot-http-client-reactive", + "spring-boot-http-codec", + "spring-boot-http-converter", + "spring-boot-integration", + "spring-boot-jackson", "spring-boot-jarmode-tools", + "spring-boot-jdbc", + "spring-boot-jersey", + "spring-boot-jetty", + "spring-boot-jms", + "spring-boot-jooq", + "spring-boot-jpa", + "spring-boot-jsonb", + "spring-boot-kafka", + "spring-boot-ldap", + "spring-boot-liquibase", "spring-boot-loader", "spring-boot-loader-classic", "spring-boot-loader-tools", + "spring-boot-mail", + "spring-boot-metrics", + "spring-boot-mongodb", + "spring-boot-mustache", + "spring-boot-neo4j", + "spring-boot-netty", + "spring-boot-observation", + "spring-boot-opentelemetry", "spring-boot-properties-migrator", + "spring-boot-pulsar", + "spring-boot-quartz", + "spring-boot-r2dbc", + "spring-boot-reactor", + "spring-boot-reactor-netty", + "spring-boot-restclient", + "spring-boot-restclient-test", + "spring-boot-rsocket", + "spring-boot-security", + "spring-boot-security-oauth2-authorization-server", + "spring-boot-security-oauth2-client", + "spring-boot-security-oauth2-resource-server", + "spring-boot-security-saml2", + "spring-boot-sendgrid", + "spring-boot-servlet", + "spring-boot-session", + "spring-boot-session-data-mongodb", + "spring-boot-session-data-redis", + "spring-boot-session-hazelcast", + "spring-boot-session-jdbc", + "spring-boot-sql", "spring-boot-starter", "spring-boot-starter-activemq", "spring-boot-starter-actuator", @@ -2054,7 +2132,21 @@ bom { "spring-boot-starter-websocket", "spring-boot-test", "spring-boot-test-autoconfigure", - "spring-boot-testcontainers" + "spring-boot-testcontainers", + "spring-boot-thymeleaf", + "spring-boot-tomcat", + "spring-boot-tracing", + "spring-boot-tx", + "spring-boot-undertow", + "spring-boot-validation", + "spring-boot-web-server", + "spring-boot-web-server-test", + "spring-boot-webclient", + "spring-boot-webflux", + "spring-boot-webmvc", + "spring-boot-webservices", + "spring-boot-websocket", + "spring-boot-zipkin" ] plugins = [ "spring-boot-maven-plugin" diff --git a/spring-boot-project/spring-boot-devtools/build.gradle b/spring-boot-project/spring-boot-devtools/build.gradle index 8ab847cf59cb..45fcafcb80eb 100644 --- a/spring-boot-project/spring-boot-devtools/build.gradle +++ b/spring-boot-project/spring-boot-devtools/build.gradle @@ -45,17 +45,21 @@ dependencies { intTestDependencies(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) intTestImplementation(project(":spring-boot-project:spring-boot-autoconfigure")) + intTestImplementation(project(":spring-boot-project:spring-boot-restclient")) intTestImplementation(project(":spring-boot-project:spring-boot-test")) intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + intTestImplementation(project(":spring-boot-project:spring-boot-web-server-test")) intTestImplementation("org.apache.httpcomponents.client5:httpclient5") - intTestImplementation("org.assertj:assertj-core") - intTestImplementation("org.awaitility:awaitility") - intTestImplementation("org.junit.jupiter:junit-jupiter") intTestImplementation("net.bytebuddy:byte-buddy") intTestRuntimeOnly("org.springframework:spring-web") - optional("io.projectreactor:reactor-core") + optional(project(":spring-boot-project:spring-boot-jdbc")) + optional(project(":spring-boot-project:spring-boot-jpa")) + optional(project(":spring-boot-project:spring-boot-r2dbc")) + optional(project(":spring-boot-project:spring-boot-reactor")) + optional(project(":spring-boot-project:spring-boot-security")) + optional(project(":spring-boot-project:spring-boot-web-server")) optional("io.r2dbc:r2dbc-spi") optional("jakarta.servlet:jakarta.servlet-api") optional("org.apache.derby:derbytools") @@ -68,8 +72,11 @@ dependencies { optional("org.springframework.data:spring-data-redis") optional("org.springframework.session:spring-session-core") - testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-freemarker")) testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-r2dbc"))) testImplementation("ch.qos.logback:logback-classic") testImplementation("com.h2database:h2") testImplementation("com.zaxxer:HikariCP") @@ -78,21 +85,13 @@ dependencies { testImplementation("org.apache.tomcat.embed:tomcat-embed-websocket") testImplementation("org.apache.tomcat.embed:tomcat-embed-core") testImplementation("org.apache.tomcat.embed:tomcat-embed-jasper") - testImplementation("org.assertj:assertj-core") - testImplementation("org.awaitility:awaitility") testImplementation("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-client") - testImplementation("org.hamcrest:hamcrest-library") testImplementation("org.hsqldb:hsqldb") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("org.postgresql:postgresql") - testImplementation("org.springframework:spring-test") testImplementation("org.springframework:spring-webmvc") testImplementation("org.springframework:spring-websocket") testImplementation("org.springframework.hateoas:spring-hateoas") testImplementation("org.springframework.security:spring-security-test") - testImplementation("org.freemarker:freemarker") testRuntimeOnly("org.aspectj:aspectjweaver") testRuntimeOnly("org.yaml:snakeyaml") diff --git a/spring-boot-project/spring-boot-devtools/src/intTest/java/com/example/DevToolsTestApplication.java b/spring-boot-project/spring-boot-devtools/src/intTest/java/com/example/DevToolsTestApplication.java index fe17b7bd0567..f3473ac07985 100644 --- a/spring-boot-project/spring-boot-devtools/src/intTest/java/com/example/DevToolsTestApplication.java +++ b/spring-boot-project/spring-boot-devtools/src/intTest/java/com/example/DevToolsTestApplication.java @@ -18,7 +18,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.context.WebServerPortFileWriter; +import org.springframework.boot.web.server.context.WebServerPortFileWriter; @SpringBootApplication class DevToolsTestApplication { diff --git a/spring-boot-project/spring-boot-devtools/src/intTest/java/org/springframework/boot/devtools/tests/DevToolsIntegrationTests.java b/spring-boot-project/spring-boot-devtools/src/intTest/java/org/springframework/boot/devtools/tests/DevToolsIntegrationTests.java index a96bf0f0c320..1baa9c915d00 100644 --- a/spring-boot-project/spring-boot-devtools/src/intTest/java/org/springframework/boot/devtools/tests/DevToolsIntegrationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/intTest/java/org/springframework/boot/devtools/tests/DevToolsIntegrationTests.java @@ -25,8 +25,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; diff --git a/spring-boot-project/spring-boot-devtools/src/intTest/java/org/springframework/boot/devtools/tests/DevToolsWithLazyInitializationIntegrationTests.java b/spring-boot-project/spring-boot-devtools/src/intTest/java/org/springframework/boot/devtools/tests/DevToolsWithLazyInitializationIntegrationTests.java index 28a0106a8333..a4fc13d8c3f1 100644 --- a/spring-boot-project/spring-boot-devtools/src/intTest/java/org/springframework/boot/devtools/tests/DevToolsWithLazyInitializationIntegrationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/intTest/java/org/springframework/boot/devtools/tests/DevToolsWithLazyInitializationIntegrationTests.java @@ -19,7 +19,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java index b8e5fa9248a8..81d5fc2f4eb3 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java @@ -36,14 +36,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor; -import org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration.DatabaseShutdownExecutorEntityManagerFactoryDependsOnPostProcessor; +import org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration.DatabaseShutdownExecutorEntityManagerFactoryDependsOnConfiguration; import org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration.DevToolsDataSourceCondition; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryDependsOnPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ConfigurationCondition; import org.springframework.context.annotation.Import; import org.springframework.core.type.AnnotatedTypeMetadata; @@ -60,8 +61,8 @@ @ConditionalOnClass(DataSource.class) @ConditionalOnEnabledDevTools @Conditional(DevToolsDataSourceCondition.class) -@AutoConfiguration(after = DataSourceAutoConfiguration.class) -@Import(DatabaseShutdownExecutorEntityManagerFactoryDependsOnPostProcessor.class) +@AutoConfiguration(afterName = "org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration") +@Import(DatabaseShutdownExecutorEntityManagerFactoryDependsOnConfiguration.class) public class DevToolsDataSourceAutoConfiguration { @Bean @@ -70,12 +71,19 @@ NonEmbeddedInMemoryDatabaseShutdownExecutor inMemoryDatabaseShutdownExecutor(Dat return new NonEmbeddedInMemoryDatabaseShutdownExecutor(dataSource, dataSourceProperties); } + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ EntityManagerFactoryDependsOnPostProcessor.class, + LocalContainerEntityManagerFactoryBean.class }) + @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) + @Import(DatabaseShutdownExecutorEntityManagerFactoryDependsOnPostProcessor.class) + static class DatabaseShutdownExecutorEntityManagerFactoryDependsOnConfiguration { + + } + /** * Post processor to ensure that {@link jakarta.persistence.EntityManagerFactory} * beans depend on the {@code inMemoryDatabaseShutdownExecutor} bean. */ - @ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class) - @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) static class DatabaseShutdownExecutorEntityManagerFactoryDependsOnPostProcessor extends EntityManagerFactoryDependsOnPostProcessor { diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfiguration.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfiguration.java index 659353e274a1..55d75ca580f2 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfiguration.java @@ -30,9 +30,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; import org.springframework.boot.devtools.autoconfigure.DevToolsR2dbcAutoConfiguration.DevToolsConnectionFactoryCondition; import org.springframework.boot.r2dbc.EmbeddedDatabaseConnection; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; @@ -51,7 +51,7 @@ @ConditionalOnClass(ConnectionFactory.class) @ConditionalOnEnabledDevTools @Conditional(DevToolsConnectionFactoryCondition.class) -@AutoConfiguration(after = R2dbcAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration") public class DevToolsR2dbcAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/OnEnabledDevToolsCondition.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/OnEnabledDevToolsCondition.java index f87e0c307cba..44734aea57ae 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/OnEnabledDevToolsCondition.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/OnEnabledDevToolsCondition.java @@ -27,12 +27,8 @@ * A condition that checks if DevTools should be enabled. * * @author Madhura Bhave - * @since 2.2.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link ConditionalOnEnabledDevTools @ConditionalOnEnabledDevTools} */ -@Deprecated(since = "3.5.0", forRemoval = true) -public class OnEnabledDevToolsCondition extends SpringBootCondition { +class OnEnabledDevToolsCondition extends SpringBootCondition { @Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfiguration.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfiguration.java index 0bee60eccdcb..08ad3887a866 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfiguration.java @@ -28,9 +28,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties.Servlet; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.devtools.remote.server.AccessManager; import org.springframework.boot.devtools.remote.server.Dispatcher; @@ -44,6 +41,8 @@ import org.springframework.boot.devtools.restart.server.HttpRestartServer; import org.springframework.boot.devtools.restart.server.HttpRestartServerHandler; import org.springframework.boot.devtools.restart.server.SourceDirectoryUrlFilter; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties.Servlet; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -59,10 +58,10 @@ * @author Madhura Bhave * @since 1.3.0 */ -@AutoConfiguration(after = SecurityAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration") @ConditionalOnEnabledDevTools @ConditionalOnProperty("spring.devtools.remote.secret") -@ConditionalOnClass({ Filter.class, ServerHttpRequest.class }) +@ConditionalOnClass({ Filter.class, ServerHttpRequest.class, ServerProperties.class }) @Import(RemoteDevtoolsSecurityConfiguration.class) @EnableConfigurationProperties({ ServerProperties.class, DevToolsProperties.class }) public class RemoteDevToolsAutoConfiguration { diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevtoolsSecurityConfiguration.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevtoolsSecurityConfiguration.java index fc5e6019d26a..8d685c6df3ee 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevtoolsSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevtoolsSecurityConfiguration.java @@ -17,8 +17,8 @@ package org.springframework.boot.devtools.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.security.autoconfigure.SecurityProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsEmbeddedDataSourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsEmbeddedDataSourceAutoConfigurationTests.java index 6041af2a0fab..61d5ccbf5e21 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsEmbeddedDataSourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsEmbeddedDataSourceAutoConfigurationTests.java @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.context.ConfigurableApplicationContext; diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsPooledDataSourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsPooledDataSourceAutoConfigurationTests.java index 6eb2babdafba..f61d0eb68310 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsPooledDataSourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsPooledDataSourceAutoConfigurationTests.java @@ -33,7 +33,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfigurationTests.java index d7630716566e..02426cfb9b47 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfigurationTests.java @@ -23,17 +23,15 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; -import io.r2dbc.spi.Connection; import io.r2dbc.spi.ConnectionFactory; -import io.r2dbc.spi.ConnectionFactoryMetadata; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.reactivestreams.Publisher; import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; import org.springframework.boot.devtools.autoconfigure.DevToolsR2dbcAutoConfiguration.R2dbcDatabaseShutdownEvent; +import org.springframework.boot.r2dbc.SimpleConnectionFactoryProvider.SimpleTestConnectionFactory; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.context.ApplicationListener; @@ -109,7 +107,7 @@ void emptyFactoryMethodMetadataIgnored() throws Exception { private ConfigurableApplicationContext getEmptyFactoryMethodMetadataIgnoredContext() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - ConnectionFactory connectionFactory = new MockConnectionFactory(); + ConnectionFactory connectionFactory = new SimpleTestConnectionFactory(); AnnotatedGenericBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition( connectionFactory.getClass()); context.registerBeanDefinition("connectionFactory", beanDefinition); @@ -170,7 +168,7 @@ static class SingleConnectionFactoryConfiguration { @Bean ConnectionFactory connectionFactory() { - return new MockConnectionFactory(); + return new SimpleTestConnectionFactory(); } } @@ -180,26 +178,12 @@ static class MultipleConnectionFactoriesConfiguration { @Bean ConnectionFactory connectionFactoryOne() { - return new MockConnectionFactory(); + return new SimpleTestConnectionFactory(); } @Bean ConnectionFactory connectionFactoryTwo() { - return new MockConnectionFactory(); - } - - } - - private static final class MockConnectionFactory implements ConnectionFactory { - - @Override - public Publisher create() { - return null; - } - - @Override - public ConnectionFactoryMetadata getMetadata() { - return null; + return new SimpleTestConnectionFactory(); } } diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfigurationTests.java index 9c61d61f52df..f0dafa7edf3e 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfigurationTests.java @@ -33,10 +33,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.autoconfigure.web.WebProperties.Resources; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.devtools.classpath.ClassPathChangedEvent; import org.springframework.boot.devtools.classpath.ClassPathFileSystemWatcher; import org.springframework.boot.devtools.livereload.LiveReloadServer; @@ -44,8 +42,10 @@ import org.springframework.boot.devtools.restart.MockRestartInitializer; import org.springframework.boot.devtools.restart.MockRestarter; import org.springframework.boot.devtools.restart.Restarter; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -258,14 +258,14 @@ private Map getDefaultProperties(Map specifiedPr } @Configuration(proxyBeanMethods = false) - @Import({ ServletWebServerFactoryAutoConfiguration.class, LocalDevToolsAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, LocalDevToolsAutoConfiguration.class, FreeMarkerAutoConfiguration.class }) static class Config { } @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, LocalDevToolsAutoConfiguration.class, + @ImportAutoConfiguration({ TomcatServletWebServerAutoConfiguration.class, LocalDevToolsAutoConfiguration.class, FreeMarkerAutoConfiguration.class }) static class ConfigWithMockLiveReload { @@ -277,7 +277,7 @@ LiveReloadServer liveReloadServer() { } @Configuration(proxyBeanMethods = false) - @Import({ ServletWebServerFactoryAutoConfiguration.class, LocalDevToolsAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, LocalDevToolsAutoConfiguration.class, WebProperties.class }) static class WebResourcesConfig { diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfigurationTests.java index 4ab34831afb9..7357882a3998 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfigurationTests.java @@ -27,13 +27,13 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.devtools.remote.server.DispatcherFilter; import org.springframework.boot.devtools.restart.MockRestarter; import org.springframework.boot.devtools.restart.server.HttpRestartServer; import org.springframework.boot.devtools.restart.server.SourceDirectoryUrlFilter; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/RemoteClientConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/RemoteClientConfigurationTests.java index df8594318707..21899871f78a 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/RemoteClientConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/RemoteClientConfigurationTests.java @@ -40,8 +40,8 @@ import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docker-compose/build.gradle b/spring-boot-project/spring-boot-docker-compose/build.gradle index 64d269ae1c89..067ff72d7405 100644 --- a/spring-boot-project/spring-boot-docker-compose/build.gradle +++ b/spring-boot-project/spring-boot-docker-compose/build.gradle @@ -16,50 +16,26 @@ plugins { id "java-library" + id "java-test-fixtures" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.deployed" id "org.springframework.boot.docker-test" id "org.springframework.boot.optional-dependencies" } -description = "Spring Boot Docker Compose Support" +description = "Spring Boot Docker Compose" dependencies { - api(project(":spring-boot-project:spring-boot")) - - dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) - dockerTestImplementation("com.hazelcast:hazelcast") - dockerTestImplementation("com.redis:testcontainers-redis") - dockerTestImplementation("org.assertj:assertj-core") - dockerTestImplementation("org.awaitility:awaitility") - dockerTestImplementation("org.junit.jupiter:junit-jupiter") - dockerTestImplementation("org.testcontainers:testcontainers") - - dockerTestRuntimeOnly("com.clickhouse:clickhouse-jdbc") - dockerTestRuntimeOnly("com.clickhouse:clickhouse-r2dbc") - dockerTestRuntimeOnly("com.microsoft.sqlserver:mssql-jdbc") - dockerTestRuntimeOnly("com.oracle.database.r2dbc:oracle-r2dbc") - dockerTestRuntimeOnly("io.r2dbc:r2dbc-mssql") - dockerTestRuntimeOnly("org.postgresql:postgresql") - dockerTestRuntimeOnly("org.postgresql:r2dbc-postgresql") + api(project(":spring-boot-project:spring-boot-autoconfigure")) implementation("com.fasterxml.jackson.core:jackson-databind") implementation("com.fasterxml.jackson.module:jackson-module-parameter-names") - optional(project(":spring-boot-project:spring-boot-autoconfigure")) - optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) - optional("com.hazelcast:hazelcast") - optional("io.r2dbc:r2dbc-spi") - optional("org.mongodb:mongodb-driver-core") - optional("org.neo4j.driver:neo4j-java-driver") - optional("org.springframework.data:spring-data-r2dbc") + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation("ch.qos.logback:logback-classic") - testImplementation("org.assertj:assertj-core") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.springframework:spring-core-test") - testImplementation("org.springframework:spring-test") + + testFixturesImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) } diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/package-info.java deleted file mode 100644 index d789c4dd3232..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/activemq/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose ActiveMQ service connections. - */ -package org.springframework.boot.docker.compose.service.connection.activemq; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/package-info.java deleted file mode 100644 index e9807a592a61..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/cassandra/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Cassandra service connections. - */ -package org.springframework.boot.docker.compose.service.connection.cassandra; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseEnvironment.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseEnvironment.java deleted file mode 100644 index 58f7cb5832bd..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseEnvironment.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.clickhouse; - -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * ClickHouse environment details. - * - * @author Stephane Nicoll - */ -class ClickHouseEnvironment { - - private final String username; - - private final String password; - - private final String database; - - ClickHouseEnvironment(Map env) { - this.username = env.getOrDefault("CLICKHOUSE_USER", "default"); - this.password = extractPassword(env); - this.database = env.getOrDefault("CLICKHOUSE_DB", "default"); - } - - private String extractPassword(Map env) { - boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD"); - String password = env.get("CLICKHOUSE_PASSWORD"); - Assert.state(StringUtils.hasLength(password) || allowEmpty, "No ClickHouse password found"); - return (password != null) ? password : ""; - } - - String getUsername() { - return this.username; - } - - String getPassword() { - return this.password; - } - - String getDatabase() { - return this.database; - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/package-info.java deleted file mode 100644 index df097fcb8b13..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose ClickHouse service connections. - */ -package org.springframework.boot.docker.compose.service.connection.clickhouse; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/package-info.java deleted file mode 100644 index dbe2b86e2930..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Elasticsearch service connections. - */ -package org.springframework.boot.docker.compose.service.connection.elasticsearch; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/flyway/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/flyway/package-info.java deleted file mode 100644 index 1d5488e44e77..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/flyway/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Flyway service connections. - */ -package org.springframework.boot.docker.compose.service.connection.flyway; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/package-info.java deleted file mode 100644 index ee778037a006..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Hazelcast service connections. - */ -package org.springframework.boot.docker.compose.service.connection.hazelcast; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/jdbc/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/jdbc/package-info.java deleted file mode 100644 index 480669626ab1..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/jdbc/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Utilities to help when creating - * {@link org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails}. - */ -package org.springframework.boot.docker.compose.service.connection.jdbc; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/package-info.java deleted file mode 100644 index 7c90bbef1ed7..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose LDAP service connections. - */ -package org.springframework.boot.docker.compose.service.connection.ldap; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/liquibase/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/liquibase/package-info.java deleted file mode 100644 index 2ac0e9d8b8d4..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/liquibase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Liquibase service connections. - */ -package org.springframework.boot.docker.compose.service.connection.liquibase; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbEnvironment.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbEnvironment.java deleted file mode 100644 index 7d29db976615..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbEnvironment.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.mariadb; - -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * MariaDB environment details. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @author Scott Frederick - */ -class MariaDbEnvironment { - - private final String username; - - private final String password; - - private final String database; - - MariaDbEnvironment(Map env) { - this.username = extractUsername(env); - this.password = extractPassword(env); - this.database = extractDatabase(env); - } - - private String extractUsername(Map env) { - String user = env.get("MARIADB_USER"); - return (user != null) ? user : env.getOrDefault("MYSQL_USER", "root"); - } - - private String extractPassword(Map env) { - Assert.state(!env.containsKey("MARIADB_RANDOM_ROOT_PASSWORD"), "MARIADB_RANDOM_ROOT_PASSWORD is not supported"); - Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported"); - Assert.state(!env.containsKey("MARIADB_ROOT_PASSWORD_HASH"), "MARIADB_ROOT_PASSWORD_HASH is not supported"); - boolean allowEmpty = env.containsKey("MARIADB_ALLOW_EMPTY_PASSWORD") - || env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD"); - String password = env.get("MARIADB_PASSWORD"); - password = (password != null) ? password : env.get("MYSQL_PASSWORD"); - password = (password != null) ? password : env.get("MARIADB_ROOT_PASSWORD"); - password = (password != null) ? password : env.get("MYSQL_ROOT_PASSWORD"); - Assert.state(StringUtils.hasLength(password) || allowEmpty, "No MariaDB password found"); - return (password != null) ? password : ""; - } - - private String extractDatabase(Map env) { - String database = env.get("MARIADB_DATABASE"); - database = (database != null) ? database : env.get("MYSQL_DATABASE"); - Assert.state(database != null, "No MARIADB_DATABASE defined"); - return database; - } - - String getUsername() { - return this.username; - } - - String getPassword() { - return this.password; - } - - String getDatabase() { - return this.database; - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/package-info.java deleted file mode 100644 index 45eb594d92a6..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose MariaDB service connections. - */ -package org.springframework.boot.docker.compose.service.connection.mariadb; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/package-info.java deleted file mode 100644 index 7d5dfac70a59..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose MongoDB service connections. - */ -package org.springframework.boot.docker.compose.service.connection.mongo; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlEnvironment.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlEnvironment.java deleted file mode 100644 index 3d7729c6b493..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlEnvironment.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.mysql; - -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * MySQL environment details. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @author Scott Frederick - */ -class MySqlEnvironment { - - private final String username; - - private final String password; - - private final String database; - - MySqlEnvironment(Map env) { - this.username = env.getOrDefault("MYSQL_USER", "root"); - this.password = extractPassword(env); - this.database = extractDatabase(env); - } - - private String extractPassword(Map env) { - Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported"); - boolean allowEmpty = env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD"); - String password = env.get("MYSQL_PASSWORD"); - password = (password != null) ? password : env.get("MYSQL_ROOT_PASSWORD"); - Assert.state(StringUtils.hasLength(password) || allowEmpty, "No MySQL password found"); - return (password != null) ? password : ""; - } - - private String extractDatabase(Map env) { - String database = env.get("MYSQL_DATABASE"); - Assert.state(database != null, "No MYSQL_DATABASE defined"); - return database; - } - - String getUsername() { - return this.username; - } - - String getPassword() { - return this.password; - } - - String getDatabase() { - return this.database; - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/package-info.java deleted file mode 100644 index 48f02a646ba4..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose MySQL service connections. - */ -package org.springframework.boot.docker.compose.service.connection.mysql; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/package-info.java deleted file mode 100644 index 3bb4703a79ff..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Neo4j service connections. - */ -package org.springframework.boot.docker.compose.service.connection.neo4j; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleContainer.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleContainer.java deleted file mode 100644 index c3272fc4cdf8..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleContainer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.oracle; - -/** - * Enumeration of supported Oracle containers. - * - * @author Andy Wilkinson - */ -enum OracleContainer { - - FREE("gvenzl/oracle-free", "freepdb1"), - - XE("gvenzl/oracle-xe", "xepdb1"); - - private final String imageName; - - private final String defaultDatabase; - - OracleContainer(String imageName, String defaultDatabase) { - this.imageName = imageName; - this.defaultDatabase = defaultDatabase; - } - - String getImageName() { - return this.imageName; - } - - String getDefaultDatabase() { - return this.defaultDatabase; - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleEnvironment.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleEnvironment.java deleted file mode 100644 index 95b206fbf8cc..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleEnvironment.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.oracle; - -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Oracle Database environment details. - * - * @author Andy Wilkinson - */ -class OracleEnvironment { - - private final String username; - - private final String password; - - private final String database; - - OracleEnvironment(Map env, String defaultDatabase) { - this.username = env.getOrDefault("APP_USER", "system"); - this.password = extractPassword(env); - this.database = env.getOrDefault("ORACLE_DATABASE", defaultDatabase); - } - - private String extractPassword(Map env) { - if (env.containsKey("APP_USER")) { - String password = env.get("APP_USER_PASSWORD"); - Assert.state(StringUtils.hasLength(password), "No Oracle app password found"); - return password; - } - Assert.state(!env.containsKey("ORACLE_RANDOM_PASSWORD"), - "ORACLE_RANDOM_PASSWORD is not supported without APP_USER and APP_USER_PASSWORD"); - String password = env.get("ORACLE_PASSWORD"); - Assert.state(StringUtils.hasLength(password), "No Oracle password found"); - return password; - } - - String getUsername() { - return this.username; - } - - String getPassword() { - return this.password; - } - - String getDatabase() { - return this.database; - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/package-info.java deleted file mode 100644 index b929a51d2632..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose MySQL service connections. - */ -package org.springframework.boot.docker.compose.service.connection.oracle; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/package-info.java deleted file mode 100644 index 65e5f41f7da7..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for Docker Compose OpenTelemetry service connections. - */ -package org.springframework.boot.docker.compose.service.connection.otlp; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java deleted file mode 100644 index 5726237e4b82..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.postgres; - -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Postgres environment details. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @author Scott Frederick - * @author Sidmar Theodoro - * @author He Zean - */ -class PostgresEnvironment { - - private static final String[] USERNAME_KEYS = new String[] { "POSTGRES_USER", "POSTGRESQL_USER", - "POSTGRESQL_USERNAME" }; - - private static final String DEFAULT_USERNAME = "postgres"; - - private static final String[] DATABASE_KEYS = new String[] { "POSTGRES_DB", "POSTGRESQL_DB", - "POSTGRESQL_DATABASE" }; - - private final String username; - - private final String password; - - private final String database; - - PostgresEnvironment(Map env) { - this.username = extract(env, USERNAME_KEYS, DEFAULT_USERNAME); - this.password = extractPassword(env); - this.database = extract(env, DATABASE_KEYS, this.username); - } - - private String extract(Map env, String[] keys, String defaultValue) { - for (String key : keys) { - if (env.containsKey(key)) { - return env.get(key); - } - } - return defaultValue; - } - - private String extractPassword(Map env) { - if (isUsingTrustHostAuthMethod(env)) { - return null; - } - String password = env.getOrDefault("POSTGRES_PASSWORD", env.get("POSTGRESQL_PASSWORD")); - boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD"); - Assert.state(allowEmpty || StringUtils.hasLength(password), "No PostgreSQL password found"); - return (password != null) ? password : ""; - } - - private boolean isUsingTrustHostAuthMethod(Map env) { - String hostAuthMethod = env.get("POSTGRES_HOST_AUTH_METHOD"); - return "trust".equals(hostAuthMethod); - } - - String getUsername() { - return this.username; - } - - String getPassword() { - return this.password; - } - - String getDatabase() { - return this.database; - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/package-info.java deleted file mode 100644 index 424124efdee1..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Postgres service connections. - */ -package org.springframework.boot.docker.compose.service.connection.postgres; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/pulsar/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/pulsar/package-info.java deleted file mode 100644 index 93f822efcb13..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/pulsar/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Pulsar service connections. - */ -package org.springframework.boot.docker.compose.service.connection.pulsar; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/r2dbc/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/r2dbc/package-info.java deleted file mode 100644 index 05de7501883d..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/r2dbc/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Utilities to help when creating - * {@link org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails}. - */ -package org.springframework.boot.docker.compose.service.connection.r2dbc; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/package-info.java deleted file mode 100644 index ea5805377aca..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/rabbit/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose RabbitMQ service connections. - */ -package org.springframework.boot.docker.compose.service.connection.rabbit; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/redis/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/redis/package-info.java deleted file mode 100644 index afdf67a3e12d..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/redis/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Redis service connections. - */ -package org.springframework.boot.docker.compose.service.connection.redis; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerEnvironment.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerEnvironment.java deleted file mode 100644 index a83b55f0782b..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerEnvironment.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.sqlserver; - -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * MS SQL Server environment details. - * - * @author Andy Wilkinson - */ -class SqlServerEnvironment { - - private final String username = "SA"; - - private final String password; - - SqlServerEnvironment(Map env) { - this.password = extractPassword(env); - } - - private String extractPassword(Map env) { - String password = env.get("MSSQL_SA_PASSWORD"); - password = (password != null) ? password : env.get("SA_PASSWORD"); - Assert.state(StringUtils.hasLength(password), "No MSSQL password found"); - return password; - } - - String getUsername() { - return this.username; - } - - String getPassword() { - return this.password; - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/package-info.java deleted file mode 100644 index 626620e5fa70..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose MS SQL Server service connections. - */ -package org.springframework.boot.docker.compose.service.connection.sqlserver; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/zipkin/package-info.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/zipkin/package-info.java deleted file mode 100644 index 23c25593ad4c..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/zipkin/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Auto-configuration for Docker Compose Zipkin service connections. - */ -package org.springframework.boot.docker.compose.service.connection.zipkin; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-docker-compose/src/main/resources/META-INF/spring.factories index d2defa268464..a5abc18cd2f7 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-docker-compose/src/main/resources/META-INF/spring.factories @@ -2,39 +2,3 @@ org.springframework.context.ApplicationListener=\ org.springframework.boot.docker.compose.lifecycle.DockerComposeListener,\ org.springframework.boot.docker.compose.service.connection.DockerComposeServiceConnectionsApplicationListener - -# Connection Details Factories -org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ -org.springframework.boot.docker.compose.service.connection.activemq.ActiveMQClassicDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.activemq.ActiveMQDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.activemq.ArtemisDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.cassandra.CassandraDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.clickhouse.ClickHouseJdbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.clickhouse.ClickHouseR2dbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.elasticsearch.ElasticsearchDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.flyway.JdbcAdaptingFlywayConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.hazelcast.HazelcastDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.ldap.LLdapDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.ldap.OpenLdapDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.liquibase.JdbcAdaptingLiquibaseConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.mariadb.MariaDbJdbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.mariadb.MariaDbR2dbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.mongo.MongoDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.mysql.MySqlJdbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.mysql.MySqlR2dbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.neo4j.Neo4jDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.oracle.OracleFreeJdbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.oracle.OracleFreeR2dbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.oracle.OracleXeJdbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.oracle.OracleXeR2dbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.otlp.OpenTelemetryLoggingDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.otlp.OpenTelemetryMetricsDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.otlp.OpenTelemetryTracingDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.postgres.PostgresJdbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.postgres.PostgresR2dbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.pulsar.PulsarDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.rabbit.RabbitDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.redis.RedisDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.sqlserver.SqlServerJdbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.sqlserver.SqlServerR2dbcDockerComposeConnectionDetailsFactory,\ -org.springframework.boot.docker.compose.service.connection.zipkin.ZipkinDockerComposeConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseEnvironmentTests.java b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseEnvironmentTests.java deleted file mode 100644 index 20743dc203f0..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseEnvironmentTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.clickhouse; - -import java.util.Collections; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link ClickHouseEnvironment}. - * - * @author Stephane Nicoll - */ -class ClickHouseEnvironmentTests { - - @Test - void createWhenNoPasswordThrowsException() { - assertThatIllegalStateException().isThrownBy(() -> new ClickHouseEnvironment(Collections.emptyMap())) - .withMessage("No ClickHouse password found"); - } - - @Test - void getPasswordWhenHasPassword() { - ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { - ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "true")); - assertThat(environment.getPassword()).isEmpty(); - } - - @Test - void getPasswordWhenHasNoPasswordAndAllowEmptyPasswordIsYes() { - ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes")); - assertThat(environment.getPassword()).isEmpty(); - } - - @Test - void getUsernameWhenNoUser() { - ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("default"); - } - - @Test - void getUsernameWhenHasUser() { - ClickHouseEnvironment environment = new ClickHouseEnvironment( - Map.of("CLICKHOUSE_USER", "me", "CLICKHOUSE_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("me"); - } - - @Test - void getDatabaseWhenNoDatabase() { - ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("default"); - } - - @Test - void getDatabaseWhenHasDatabase() { - ClickHouseEnvironment environment = new ClickHouseEnvironment( - Map.of("CLICKHOUSE_DB", "db", "CLICKHOUSE_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbEnvironmentTests.java b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbEnvironmentTests.java deleted file mode 100644 index 54e94ec49169..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbEnvironmentTests.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.mariadb; - -import java.util.Collections; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link MariaDbEnvironment}. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @author Jinseong Hwang - * @author Scott Frederick - */ -class MariaDbEnvironmentTests { - - @Test - void createWhenHasMariadbRandomRootPasswordThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_RANDOM_ROOT_PASSWORD", "true"))) - .withMessage("MARIADB_RANDOM_ROOT_PASSWORD is not supported"); - } - - @Test - void createWhenHasMysqlRandomRootPasswordThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new MariaDbEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"))) - .withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported"); - } - - @Test - void createWhenHasMariadbRootPasswordHashThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_ROOT_PASSWORD_HASH", "0FF"))) - .withMessage("MARIADB_ROOT_PASSWORD_HASH is not supported"); - } - - @Test - void createWhenHasNoPasswordThrowsException() { - assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Collections.emptyMap())) - .withMessage("No MariaDB password found"); - } - - @Test - void createWhenHasNoDatabaseThrowsException() { - assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_PASSWORD", "secret"))) - .withMessage("No MARIADB_DATABASE defined"); - } - - @Test - void getUsernameWhenHasMariadbUser() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); - assertThat(environment.getUsername()).isEqualTo("myself"); - } - - @Test - void getUsernameWhenHasMysqlUser() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MYSQL_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); - assertThat(environment.getUsername()).isEqualTo("myself"); - } - - @Test - void getUsernameWhenHasMariadbUserAndMysqlUser() { - MariaDbEnvironment environment = new MariaDbEnvironment(Map.of("MARIADB_USER", "myself", "MYSQL_USER", "me", - "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); - assertThat(environment.getUsername()).isEqualTo("myself"); - } - - @Test - void getUsernameWhenHasNoMariadbUserOrMysqlUser() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); - assertThat(environment.getUsername()).isEqualTo("root"); - } - - @Test - void getPasswordWhenHasMariadbPassword() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasMysqlPassword() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MYSQL_PASSWORD", "secret", "MARIADB_DATABASE", "db")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasMysqlRootPassword() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MYSQL_ROOT_PASSWORD", "secret", "MARIADB_DATABASE", "db")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasMariadbPasswordAndMysqlPassword() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_PASSWORD", "secret", "MYSQL_PASSWORD", "donttell", "MARIADB_DATABASE", "db")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasMariadbPasswordAndMysqlRootPassword() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_PASSWORD", "secret", "MYSQL_ROOT_PASSWORD", "donttell", "MARIADB_DATABASE", "db")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); - assertThat(environment.getPassword()).isEmpty(); - } - - @Test - void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyPassword() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); - assertThat(environment.getPassword()).isEmpty(); - } - - @Test - void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); - assertThat(environment.getPassword()).isEmpty(); - } - - @Test - void getDatabaseWhenHasMariadbDatabase() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - - @Test - void getDatabaseWhenHasMysqlDatabase() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - - @Test - void getDatabaseWhenHasMariadbAndMysqlDatabase() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb")); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlEnvironmentTests.java b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlEnvironmentTests.java deleted file mode 100644 index dafb961141b6..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlEnvironmentTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.mysql; - -import java.util.Collections; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link MySqlEnvironment}. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @author Jinseong Hwang - * @author Scott Frederick - */ -class MySqlEnvironmentTests { - - @Test - void createWhenHasMysqlRandomRootPasswordThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"))) - .withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported"); - } - - @Test - void createWhenHasNoPasswordThrowsException() { - assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Collections.emptyMap())) - .withMessage("No MySQL password found"); - } - - @Test - void createWhenHasNoDatabaseThrowsException() { - assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret"))) - .withMessage("No MYSQL_DATABASE defined"); - } - - @Test - void getUsernameWhenHasMysqlUser() { - MySqlEnvironment environment = new MySqlEnvironment( - Map.of("MYSQL_USER", "myself", "MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); - assertThat(environment.getUsername()).isEqualTo("myself"); - } - - @Test - void getUsernameWhenHasNoMysqlUser() { - MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); - assertThat(environment.getUsername()).isEqualTo("root"); - } - - @Test - void getPasswordWhenHasMysqlPassword() { - MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasMysqlRootPassword() { - MySqlEnvironment environment = new MySqlEnvironment( - Map.of("MYSQL_ROOT_PASSWORD", "secret", "MYSQL_DATABASE", "db")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() { - MySqlEnvironment environment = new MySqlEnvironment( - Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); - assertThat(environment.getPassword()).isEmpty(); - } - - @Test - void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { - MySqlEnvironment environment = new MySqlEnvironment( - Map.of("ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); - assertThat(environment.getPassword()).isEmpty(); - } - - @Test - void getDatabaseWhenHasMysqlDatabase() { - MySqlEnvironment environment = new MySqlEnvironment( - Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleEnvironmentTests.java b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleEnvironmentTests.java deleted file mode 100644 index 75a755d7bf26..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleEnvironmentTests.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.oracle; - -import java.util.Collections; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.assertj.core.api.Assertions.assertThatNoException; - -/** - * Tests for {@link OracleEnvironment}. - * - * @author Andy Wilkinson - */ -class OracleEnvironmentTests { - - @Test - void getUsernameWhenHasAppUser() { - OracleEnvironment environment = new OracleEnvironment( - Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret"), "defaultDb"); - assertThat(environment.getUsername()).isEqualTo("alice"); - } - - @Test - void getUsernameWhenHasNoAppUser() { - OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); - assertThat(environment.getUsername()).isEqualTo("system"); - } - - @Test - void getPasswordWhenHasAppPassword() { - OracleEnvironment environment = new OracleEnvironment( - Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret"), "defaultDb"); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasOraclePassword() { - OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void createWhenRandomPasswordAndAppPasswordDoesNotThrow() { - assertThatNoException().isThrownBy(() -> new OracleEnvironment( - Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret", "ORACLE_RANDOM_PASSWORD", "true"), - "defaultDb")); - } - - @Test - void createWhenRandomPasswordThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new OracleEnvironment(Map.of("ORACLE_RANDOM_PASSWORD", "true"), "defaultDb")) - .withMessage("ORACLE_RANDOM_PASSWORD is not supported without APP_USER and APP_USER_PASSWORD"); - } - - @Test - void createWhenAppUserAndNoAppPasswordThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new OracleEnvironment(Map.of("APP_USER", "alice"), "defaultDb")) - .withMessage("No Oracle app password found"); - } - - @Test - void createWhenAppUserAndEmptyAppPasswordThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new OracleEnvironment(Map.of("APP_USER", "alice", "APP_USER_PASSWORD", ""), "defaultDb")) - .withMessage("No Oracle app password found"); - } - - @Test - void createWhenHasNoPasswordThrowsException() { - assertThatIllegalStateException().isThrownBy(() -> new OracleEnvironment(Collections.emptyMap(), "defaultDb")) - .withMessage("No Oracle password found"); - } - - @Test - void createWhenHasEmptyPasswordThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> new OracleEnvironment(Map.of("ORACLE_PASSWORD", ""), "defaultDb")) - .withMessage("No Oracle password found"); - } - - @Test - void getDatabaseWhenHasNoOracleDatabase() { - OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); - assertThat(environment.getDatabase()).isEqualTo("defaultDb"); - } - - @Test - void getDatabaseWhenHasOracleDatabase() { - OracleEnvironment environment = new OracleEnvironment( - Map.of("ORACLE_PASSWORD", "secret", "ORACLE_DATABASE", "db"), "defaultDb"); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java deleted file mode 100644 index ec14b7ccd758..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.postgres; - -import java.util.Collections; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link PostgresEnvironment}. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @author Scott Frederick - * @author Sidmar Theodoro - * @author He Zean - */ -class PostgresEnvironmentTests { - - @Test - void createWhenNoPostgresPasswordThrowsException() { - assertThatIllegalStateException().isThrownBy(() -> new PostgresEnvironment(Collections.emptyMap())) - .withMessage("No PostgreSQL password found"); - } - - @Test - void getUsernameWhenNoPostgresUser() { - PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("postgres"); - } - - @Test - void getUsernameWhenNoPostgresqlUser() { - PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("postgres"); - } - - @Test - void getUsernameWhenHasPostgresUser() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("me"); - } - - @Test - void getUsernameWhenHasPostgresqlUser() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRESQL_USER", "me", "POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("me"); - } - - @Test - void getUsernameWhenHasPostgresqlUsername() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("me"); - } - - @Test - void getPasswordWhenHasPostgresPassword() { - PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasPostgresqlPassword() { - PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasTrustHostAuthMethod() { - PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_HOST_AUTH_METHOD", "trust")); - assertThat(environment.getPassword()).isNull(); - } - - @Test - void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { - PostgresEnvironment environment = new PostgresEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes")); - assertThat(environment.getPassword()).isEmpty(); - } - - @Test - void getDatabaseWhenNoPostgresDbOrPostgresUser() { - PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("postgres"); - } - - @Test - void getDatabaseWhenNoPostgresqlDbOrPostgresUser() { - PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("postgres"); - } - - @Test - void getDatabaseWhenNoPostgresDbAndPostgresUser() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("me"); - } - - @Test - void getDatabaseWhenNoPostgresqlDbAndPostgresUser() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRESQL_USER", "me", "POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("me"); - } - - @Test - void getDatabaseWhenNoPostgresqlDatabaseAndPostgresqlUsername() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("me"); - } - - @Test - void getDatabaseWhenHasPostgresDb() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRES_DB", "db", "POSTGRES_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - - @Test - void getDatabaseWhenHasPostgresqlDb() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRESQL_DB", "db", "POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - - @Test - void getDatabaseWhenHasPostgresqlDatabase() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRESQL_DATABASE", "db", "POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getDatabase()).isEqualTo("db"); - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerEnvironmentTests.java b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerEnvironmentTests.java deleted file mode 100644 index 8c6771cf634e..000000000000 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerEnvironmentTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.docker.compose.service.connection.sqlserver; - -import java.util.Collections; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link SqlServerEnvironment}. - * - * @author Andy Wilkinson - */ -class SqlServerEnvironmentTests { - - @Test - void createWhenHasNoPasswordThrowsException() { - assertThatIllegalStateException().isThrownBy(() -> new SqlServerEnvironment(Collections.emptyMap())) - .withMessage("No MSSQL password found"); - } - - @Test - void getUsernameWhenHasNoMsSqlUser() { - SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("MSSQL_SA_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("SA"); - } - - @Test - void getPasswordWhenHasMsSqlSaPassword() { - SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("MSSQL_SA_PASSWORD", "secret")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasSaPassword() { - SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("SA_PASSWORD", "secret")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - - @Test - void getPasswordWhenHasMsSqlSaPasswordAndSaPasswordPrefersMsSqlSaPassword() { - SqlServerEnvironment environment = new SqlServerEnvironment( - Map.of("MSSQL_SA_PASSWORD", "secret", "SA_PASSWORD", "not used")); - assertThat(environment.getPassword()).isEqualTo("secret"); - } - -} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTest.java b/spring-boot-project/spring-boot-docker-compose/src/testFixtures/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTest.java similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTest.java rename to spring-boot-project/spring-boot-docker-compose/src/testFixtures/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTest.java diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTestExtension.java b/spring-boot-project/spring-boot-docker-compose/src/testFixtures/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTestExtension.java similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTestExtension.java rename to spring-boot-project/spring-boot-docker-compose/src/testFixtures/java/org/springframework/boot/docker/compose/service/connection/test/DockerComposeTestExtension.java diff --git a/spring-boot-project/spring-boot-docs/build.gradle b/spring-boot-project/spring-boot-docs/build.gradle index 7e3a333e8a58..1ff7165908ad 100644 --- a/spring-boot-project/spring-boot-docs/build.gradle +++ b/spring-boot-project/spring-boot-docs/build.gradle @@ -75,33 +75,214 @@ plugins.withType(EclipsePlugin) { } dependencies { + autoConfiguration(project(path: ":spring-boot-project:spring-boot-activemq", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-actuator-autoconfigure", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-amqp", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-artemis", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-autoconfigure", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-batch", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-cache", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-cassandra", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-couchbase", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-cassandra", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-commons", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-couchbase", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-elasticsearch", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-jdbc", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-jpa", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-ldap", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-mongodb", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-neo4j", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-r2dbc", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-redis", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-data-rest", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-devtools", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-elasticsearch", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-flyway", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-freemarker", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-graphql", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-gson", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-h2console", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-hateoas", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-hazelcast", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-hibernate", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-http-client", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-http-converter", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-http-codec", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-integration", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-jackson", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-jdbc", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-jersey", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-jetty", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-jms", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-jooq", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-jsonb", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-kafka", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-ldap", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-liquibase", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-mail", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-metrics", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-mongodb", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-mustache", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-neo4j", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-netty", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-observation", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-opentelemetry", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-pulsar", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-quartz", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-r2dbc", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-reactor", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-reactor-netty", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-restclient", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-rsocket", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-security", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-security-oauth2-authorization-server", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-security-oauth2-client", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-security-oauth2-resource-server", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-security-saml2", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-sendgrid", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-servlet", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-session", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-session-data-mongodb", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-session-data-redis", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-session-hazelcast", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-session-jdbc", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-testcontainers", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-thymeleaf", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-tomcat", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-tracing", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-tx", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-undertow", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-validation", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-webclient", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-webflux", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-webmvc", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-webservices", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-websocket", configuration: "autoConfigurationMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-activemq", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-actuator", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-actuator-autoconfigure", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-amqp", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-artemis", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-autoconfigure", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-batch", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-cache", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-cassandra", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-couchbase", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-cassandra", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-commons", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-couchbase", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-elasticsearch", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-jdbc", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-jpa", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-ldap", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-neo4j", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-r2dbc", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-redis", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-data-rest", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-devtools", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-docker-compose", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-elasticsearch", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-flyway", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-freemarker", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-graphql", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-gson", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-h2console", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-hateoas", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-hazelcast", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-hibernate", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-http-client", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-http-converter", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-http-codec", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-integration", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-jackson", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-jdbc", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-jersey", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-jooq", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-jpa", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-jetty", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-jms", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-kafka", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-ldap", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-liquibase", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-mail", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-metrics", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-mongodb", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-mustache", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-neo4j", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-netty", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-observation", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-opentelemetry", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-pulsar", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-quartz", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-r2dbc", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-reactor", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-reactor-netty", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-rsocket", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-security", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-security-oauth2-authorization-server", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-security-oauth2-client", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-security-oauth2-resource-server", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-security-saml2", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-sendgrid", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-servlet", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-session", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-session-data-mongodb", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-session-data-redis", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-session-hazelcast", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-session-jdbc", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-sql", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-test-autoconfigure", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-testcontainers", configuration: "configurationPropertiesMetadata")) - - dokkatoo(project(path: ":spring-boot-project:spring-boot")) - dokkatoo(project(path: ":spring-boot-project:spring-boot-test")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-thymeleaf", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-tomcat", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-tracing", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-tx", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-undertow", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-web-server", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-webflux", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-webmvc", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-webservices", configuration: "configurationPropertiesMetadata")) implementation(project(path: ":spring-boot-project:spring-boot-actuator")) implementation(project(path: ":spring-boot-project:spring-boot-actuator-autoconfigure")) - implementation(project(path: ":spring-boot-project:spring-boot-autoconfigure")) + implementation(project(path: ":spring-boot-project:spring-boot-amqp")) + implementation(project(path: ":spring-boot-project:spring-boot-cache")) + implementation(project(path: ":spring-boot-project:spring-boot-data-cassandra")) + implementation(project(path: ":spring-boot-project:spring-boot-data-elasticsearch")) + implementation(project(path: ":spring-boot-project:spring-boot-data-neo4j")) implementation(project(path: ":spring-boot-project:spring-boot-devtools")) implementation(project(path: ":spring-boot-project:spring-boot-docker-compose")) + implementation(project(path: ":spring-boot-project:spring-boot-health")) + implementation(project(path: ":spring-boot-project:spring-boot-hibernate")) + implementation(project(path: ":spring-boot-project:spring-boot-http-converter")) + implementation(project(path: ":spring-boot-project:spring-boot-http-codec")) + implementation(project(path: ":spring-boot-project:spring-boot-integration")) + implementation(project(path: ":spring-boot-project:spring-boot-jackson")) + implementation(project(path: ":spring-boot-project:spring-boot-jdbc")) + implementation(project(path: ":spring-boot-project:spring-boot-jpa")) + implementation(project(path: ":spring-boot-project:spring-boot-jms")) + implementation(project(path: ":spring-boot-project:spring-boot-jsonb")) + implementation(project(path: ":spring-boot-project:spring-boot-ldap")) + implementation(project(path: ":spring-boot-project:spring-boot-metrics")) + implementation(project(path: ":spring-boot-project:spring-boot-r2dbc")) + implementation(project(path: ":spring-boot-project:spring-boot-reactor-netty")) + implementation(project(path: ":spring-boot-project:spring-boot-restclient")) + implementation(project(path: ":spring-boot-project:spring-boot-security")) implementation(project(path: ":spring-boot-project:spring-boot-test")) implementation(project(path: ":spring-boot-project:spring-boot-test-autoconfigure")) implementation(project(path: ":spring-boot-project:spring-boot-testcontainers")) + implementation(project(path: ":spring-boot-project:spring-boot-tomcat")) implementation(project(path: ":spring-boot-project:spring-boot-tools:spring-boot-cli")) implementation(project(path: ":spring-boot-project:spring-boot-tools:spring-boot-loader-tools")) + implementation(project(path: ":spring-boot-project:spring-boot-undertow")) + implementation(project(path: ":spring-boot-project:spring-boot-web-server-test")) + implementation(project(path: ":spring-boot-project:spring-boot-webclient")) + implementation(project(path: ":spring-boot-project:spring-boot-webflux")) + implementation(project(path: ":spring-boot-project:spring-boot-webmvc")) + implementation(project(path: ":spring-boot-project:spring-boot-webservices")) implementation("ch.qos.logback:logback-classic") implementation("com.redis:testcontainers-redis") implementation("com.zaxxer:HikariCP") @@ -153,9 +334,7 @@ dependencies { implementation("org.springframework.amqp:spring-amqp") implementation("org.springframework.amqp:spring-rabbit") implementation("org.springframework.batch:spring-batch-core") - implementation("org.springframework.data:spring-data-cassandra") implementation("org.springframework.data:spring-data-couchbase") - implementation("org.springframework.data:spring-data-elasticsearch") implementation("org.springframework.data:spring-data-envers") { exclude group: "javax.activation", module: "javax.activation-api" exclude group: "javax.persistence", module: "javax.persistence-api" @@ -164,7 +343,6 @@ dependencies { implementation("org.springframework.data:spring-data-jpa") implementation("org.springframework.data:spring-data-ldap") implementation("org.springframework.data:spring-data-mongodb") - implementation("org.springframework.data:spring-data-neo4j") implementation("org.springframework.data:spring-data-redis") implementation("org.springframework.data:spring-data-r2dbc") implementation("org.springframework.graphql:spring-graphql") @@ -201,8 +379,6 @@ dependencies { testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("org.assertj:assertj-core") - testImplementation("org.junit.jupiter:junit-jupiter") testRuntimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) testRuntimeOnly("com.h2database:h2") @@ -311,7 +487,7 @@ def getRelativeExamplesPath(var outputs) { antoraDependencies { 'actuator-rest-api' { - path = ":spring-boot-project:spring-boot-actuator-autoconfigure" + path = ":spring-boot-project:spring-boot-actuator-docs" source() aggregateContent() } diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/data-access.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/data-access.adoc index c539f635f3c5..baacfeeebf76 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/data-access.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/data-access.adoc @@ -229,7 +229,7 @@ For example, if you want to configure Hibernate's batch size you must use `+spri If you use other forms, such as `batchSize` or `batch-size`, Hibernate will not apply the setting. ==== -TIP: If you need to apply advanced customization to Hibernate properties, consider registering a javadoc:org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer[] bean that will be invoked prior to creating the javadoc:jakarta.persistence.EntityManagerFactory[]. +TIP: If you need to apply advanced customization to Hibernate properties, consider registering a javadoc:org.springframework.boot.jpa.autoconfigure.hibernate.HibernatePropertiesCustomizer[] bean that will be invoked prior to creating the javadoc:jakarta.persistence.EntityManagerFactory[]. This takes precedence over anything that is applied by the auto-configuration. @@ -275,7 +275,7 @@ Hibernate {url-hibernate-userguide}#caching[second-level cache] can be configure Rather than configuring Hibernate to lookup the cache provider again, it is better to provide the one that is available in the context whenever possible. To do this with JCache, first make sure that `org.hibernate.orm:hibernate-jcache` is available on the classpath. -Then, add a javadoc:org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer[] bean as shown in the following example: +Then, add a javadoc:org.springframework.boot.jpa.autoconfigure.hibernate.HibernatePropertiesCustomizer[] bean as shown in the following example: include-code::MyHibernateSecondLevelCacheConfiguration[] @@ -290,7 +290,7 @@ For details, see {url-hibernate-userguide}#caching-provider-jcache[the Hibernate By default, Spring Boot registers a javadoc:org.hibernate.resource.beans.container.spi.BeanContainer[] implementation that uses the javadoc:org.springframework.beans.factory.BeanFactory[] so that converters and entity listeners can use regular dependency injection. -You can disable or tune this behavior by registering a javadoc:org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer[] that removes or changes the `hibernate.resource.beans.container` property. +You can disable or tune this behavior by registering a javadoc:org.springframework.boot.jpa.autoconfigure.hibernate.HibernatePropertiesCustomizer[] that removes or changes the `hibernate.resource.beans.container` property. @@ -301,7 +301,7 @@ To take full control of the configuration of the javadoc:jakarta.persistence.Ent Spring Boot auto-configuration switches off its entity manager in the presence of a bean of that type. NOTE: When you create a bean for javadoc:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean[] yourself, any customization that was applied during the creation of the auto-configured javadoc:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean[] is lost. -Make sure to use the auto-configured javadoc:org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder[] to retain JPA and vendor properties. +Make sure to use the auto-configured javadoc:org.springframework.boot.jpa.EntityManagerFactoryBuilder[] to retain JPA and vendor properties. This is particularly important if you were relying on `spring.jpa.*` properties for configuring things like the naming strategy or the DDL mode. @@ -311,7 +311,7 @@ This is particularly important if you were relying on `spring.jpa.*` properties If you need to use JPA against multiple datasources, you likely need one javadoc:jakarta.persistence.EntityManagerFactory[] per datasource. The javadoc:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean[] from Spring ORM allows you to configure an javadoc:jakarta.persistence.EntityManagerFactory[] for your needs. -You can also reuse javadoc:org.springframework.boot.autoconfigure.orm.jpa.JpaProperties[] to bind settings for a second javadoc:jakarta.persistence.EntityManagerFactory[]. +You can also reuse javadoc:org.springframework.boot.jpa.autoconfigure.JpaProperties[] to bind settings for a second javadoc:jakarta.persistence.EntityManagerFactory[]. Building upon xref:how-to:data-access.adoc#howto.data-access.configure-two-datasources[the example for configuring a second javadoc:javax.sql.DataSource[]], a second javadoc:jakarta.persistence.EntityManagerFactory[] can be defined as shown in the following example: include-code::MyAdditionalEntityManagerFactoryConfiguration[] @@ -390,7 +390,7 @@ If you want to configure a component that JPA uses, then you need to ensure that When the component is auto-configured, Spring Boot takes care of this for you. For example, when Flyway is auto-configured, Hibernate is configured to depend on Flyway so that Flyway has a chance to initialize the database before Hibernate tries to use it. -If you are configuring a component yourself, you can use an javadoc:org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor[] subclass as a convenient way of setting up the necessary dependencies. +If you are configuring a component yourself, you can use an javadoc:org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryDependsOnPostProcessor[] subclass as a convenient way of setting up the necessary dependencies. For example, if you use Hibernate Search with Elasticsearch as its index manager, any javadoc:jakarta.persistence.EntityManagerFactory[] beans must be configured to depend on the `elasticsearchClient` bean, as shown in the following example: include-code::ElasticsearchEntityManagerFactoryDependsOnPostProcessor[] @@ -403,4 +403,4 @@ include-code::ElasticsearchEntityManagerFactoryDependsOnPostProcessor[] If you need to use jOOQ with multiple data sources, you should create your own javadoc:org.jooq.DSLContext[] for each one. See {code-spring-boot-autoconfigure-src}/jooq/JooqAutoConfiguration.java[`JooqAutoConfiguration`] for more details. -TIP: In particular, javadoc:org.springframework.boot.autoconfigure.jooq.ExceptionTranslatorExecuteListener[] and javadoc:org.springframework.boot.autoconfigure.jooq.SpringTransactionProvider[] can be reused to provide similar features to what the auto-configuration does with a single javadoc:javax.sql.DataSource[]. +TIP: In particular, javadoc:org.springframework.boot.jooq.autoconfigure.ExceptionTranslatorExecuteListener[] and javadoc:org.springframework.boot.jooq.autoconfigure.SpringTransactionProvider[] can be reused to provide similar features to what the auto-configuration does with a single javadoc:javax.sql.DataSource[]. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/messaging.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/messaging.adoc index 1edd9a2e3cbb..b3b7d9cb3b3a 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/messaging.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/messaging.adoc @@ -11,7 +11,7 @@ This section answers questions that arise from using messaging with Spring Boot. If your JMS broker does not support transacted sessions, you have to disable the support of transactions altogether. If you create your own javadoc:org.springframework.jms.config.JmsListenerContainerFactory[], there is nothing to do, since, by default it cannot be transacted. -If you want to use the javadoc:org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer[] to reuse Spring Boot's default, you can disable transacted sessions, as follows: +If you want to use the javadoc:org.springframework.boot.jms.autoconfigure.DefaultJmsListenerContainerFactoryConfigurer[] to reuse Spring Boot's default, you can disable transacted sessions, as follows: include-code::MyJmsConfiguration[] diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc index d5278a153696..26a4e7127799 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc @@ -55,7 +55,7 @@ NOTE: To get the server to render XML instead of JSON, you might have to send an [[howto.spring-mvc.customize-jackson-objectmapper]] == Customize the Jackson ObjectMapper -Spring MVC (client and server side) uses javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] to negotiate content conversion in an HTTP exchange. +Spring MVC (client and server side) uses javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] to negotiate content conversion in an HTTP exchange. If Jackson is on the classpath, you already get the default converter(s) provided by javadoc:org.springframework.http.converter.json.Jackson2ObjectMapperBuilder[], an instance of which is auto-configured for you. The javadoc:com.fasterxml.jackson.databind.ObjectMapper[] (or javadoc:com.fasterxml.jackson.dataformat.xml.XmlMapper[] for Jackson XML converter) instance (created by default) has the following customized properties: @@ -125,7 +125,7 @@ When defining an javadoc:com.fasterxml.jackson.databind.ObjectMapper[] bean, mar Note that, in either case, doing so disables all auto-configuration of the javadoc:com.fasterxml.jackson.databind.ObjectMapper[]. If you provide any javadoc:java.beans.Beans[format=annotation] of type javadoc:org.springframework.http.converter.json.MappingJackson2HttpMessageConverter[], they replace the default value in the MVC configuration. -Also, a convenience bean of type javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] is provided (and is always available if you use the default MVC configuration). +Also, a convenience bean of type javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] is provided (and is always available if you use the default MVC configuration). It has some useful methods to access the default and user-enhanced message converters. See the xref:spring-mvc.adoc#howto.spring-mvc.customize-responsebody-rendering[] section and the {code-spring-boot-autoconfigure-src}/web/servlet/WebMvcAutoConfiguration.java[`WebMvcAutoConfiguration`] source code for more details. @@ -135,10 +135,10 @@ See the xref:spring-mvc.adoc#howto.spring-mvc.customize-responsebody-rendering[] [[howto.spring-mvc.customize-responsebody-rendering]] == Customize the @ResponseBody Rendering -Spring uses javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] to render javadoc:org.springframework.web.bind.annotation.ResponseBody[format=annotation] (or responses from javadoc:org.springframework.web.bind.annotation.RestController[format=annotation]). +Spring uses javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] to render javadoc:org.springframework.web.bind.annotation.ResponseBody[format=annotation] (or responses from javadoc:org.springframework.web.bind.annotation.RestController[format=annotation]). You can contribute additional converters by adding beans of the appropriate type in a Spring Boot context. If a bean you add is of a type that would have been included by default anyway (such as javadoc:org.springframework.http.converter.json.MappingJackson2HttpMessageConverter[] for JSON conversions), it replaces the default value. -A convenience bean of type javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] is provided and is always available if you use the default MVC configuration. +A convenience bean of type javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] is provided and is always available if you use the default MVC configuration. It has some useful methods to access the default and user-enhanced message converters (For example, it can be useful if you want to manually inject them into a custom javadoc:org.springframework.web.client.RestTemplate[]). As in normal MVC usage, any javadoc:org.springframework.web.servlet.config.annotation.WebMvcConfigurer[] beans that you provide can also contribute converters by overriding the `configureMessageConverters` method. @@ -154,7 +154,7 @@ See the {code-spring-boot-autoconfigure-src}/web/servlet/WebMvcAutoConfiguration Spring Boot embraces the servlet 5 javadoc:jakarta.servlet.http.Part[] API to support uploading files. By default, Spring Boot configures Spring MVC with a maximum size of 1MB per file and a maximum of 10MB of file data in a single request. -You may override these values, the location to which intermediate data is stored (for example, to the `/tmp` directory), and the threshold past which data is flushed to disk by using the properties exposed in the javadoc:org.springframework.boot.autoconfigure.web.servlet.MultipartProperties[] class. +You may override these values, the location to which intermediate data is stored (for example, to the `/tmp` directory), and the threshold past which data is flushed to disk by using the properties exposed in the javadoc:org.springframework.boot.servlet.autoconfigure.MultipartProperties[] class. For example, if you want to specify that files be unlimited, set the configprop:spring.servlet.multipart.max-file-size[] property to `-1`. The multipart support is helpful when you want to receive multipart encoded file data as a javadoc:org.springframework.web.bind.annotation.RequestParam[format=annotation]-annotated parameter of type javadoc:org.springframework.web.multipart.MultipartFile[] in a Spring MVC controller handler method. @@ -233,11 +233,11 @@ javadoc:org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfigurati It looks for resources in a loader path by surrounding the view name with a prefix and suffix (externalized to `spring.groovy.template.prefix` and `spring.groovy.template.suffix`). The prefix and suffix have default values of '`classpath:/templates/`' and '`.tpl`', respectively. You can override javadoc:org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver[] by providing a bean of the same name. -* If you use Mustache, you also have a javadoc:org.springframework.boot.web.servlet.view.MustacheViewResolver[] named '`mustacheViewResolver`'. +* If you use Mustache, you also have a javadoc:org.springframework.boot.mustache.servlet.view.MustacheViewResolver[] named '`mustacheViewResolver`'. It looks for resources by surrounding the view name with a prefix and suffix. The prefix is `spring.mustache.prefix`, and the suffix is `spring.mustache.suffix`. The values of the prefix and suffix default to '`classpath:/templates/`' and '`.mustache`', respectively. - You can override javadoc:org.springframework.boot.web.servlet.view.MustacheViewResolver[] by providing a bean of the same name. + You can override javadoc:org.springframework.boot.mustache.servlet.view.MustacheViewResolver[] by providing a bean of the same name. For more detail, see the following sections: diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc index ee76e5df1d68..d9fd2e0cb22a 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc @@ -581,7 +581,7 @@ You can configure the roles by using the configprop:management.endpoint.health.r NOTE: If you have secured your application and wish to use `always`, your security configuration must permit access to the health endpoint for both authenticated and unauthenticated users. -Health information is collected from the content of a javadoc:org.springframework.boot.actuate.health.HealthContributorRegistry[] (by default, all javadoc:org.springframework.boot.actuate.health.HealthContributor[] instances defined in your javadoc:org.springframework.context.ApplicationContext[]). +Health information is collected from the content of a javadoc:org.springframework.boot.health.registry.HealthContributorRegistry[] (by default, all javadoc:org.springframework.boot.actuate.health.HealthContributor[] instances defined in your javadoc:org.springframework.context.ApplicationContext[]). Spring Boot includes a number of auto-configured javadoc:org.springframework.boot.actuate.health.HealthContributor[] beans, and you can also write your own. A javadoc:org.springframework.boot.actuate.health.HealthContributor[] can be either a javadoc:org.springframework.boot.actuate.health.HealthIndicator[] or a javadoc:org.springframework.boot.actuate.health.CompositeHealthContributor[]. @@ -593,7 +593,7 @@ By default, the final system health is derived by a javadoc:org.springframework. The first status in the sorted list is used as the overall health status. If no javadoc:org.springframework.boot.actuate.health.HealthIndicator[] returns a status that is known to the javadoc:org.springframework.boot.actuate.health.StatusAggregator[], an `UNKNOWN` status is used. -TIP: You can use the javadoc:org.springframework.boot.actuate.health.HealthContributorRegistry[] to register and unregister health indicators at runtime. +TIP: You can use the javadoc:org.springframework.boot.health.registry.HealthContributorRegistry[] to register and unregister health indicators at runtime. @@ -653,7 +653,7 @@ with the `key` listed in the following table: | Checks that a Neo4j database is up. | `ping` -| javadoc:org.springframework.boot.actuate.health.PingHealthIndicator[] +| javadoc:org.springframework.boot.health.contributor.PingHealthIndicator[] | Always responds with `UP`. | `rabbit` @@ -771,10 +771,10 @@ The following table shows the default status mappings for the built-in statuses: === Reactive Health Indicators For reactive applications, such as those that use Spring WebFlux, javadoc:org.springframework.boot.actuate.health.ReactiveHealthContributor[] provides a non-blocking contract for getting application health. -Similar to a traditional javadoc:org.springframework.boot.actuate.health.HealthContributor[], health information is collected from the content of a javadoc:org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry[] (by default, all javadoc:org.springframework.boot.actuate.health.HealthContributor[] and javadoc:org.springframework.boot.actuate.health.ReactiveHealthContributor[] instances defined in your javadoc:org.springframework.context.ApplicationContext[]). +Similar to a traditional javadoc:org.springframework.boot.actuate.health.HealthContributor[], health information is collected from the content of a javadoc:org.springframework.boot.health.registry.ReactiveHealthContributorRegistry[] (by default, all javadoc:org.springframework.boot.actuate.health.HealthContributor[] and javadoc:org.springframework.boot.actuate.health.ReactiveHealthContributor[] instances defined in your javadoc:org.springframework.context.ApplicationContext[]). Regular javadoc:org.springframework.boot.actuate.health.HealthContributor[] instances that do not check against a reactive API are executed on the elastic scheduler. -TIP: In a reactive application, you should use the javadoc:org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry[] to register and unregister health indicators at runtime. +TIP: In a reactive application, you should use the javadoc:org.springframework.boot.health.registry.ReactiveHealthContributorRegistry[] to register and unregister health indicators at runtime. If you need to register a regular javadoc:org.springframework.boot.actuate.health.HealthContributor[], you should wrap it with `ReactiveHealthContributor#adapt`. To provide custom health information from a reactive API, you can register Spring beans that implement the javadoc:org.springframework.boot.actuate.health.ReactiveHealthIndicator[] interface. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/loggers.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/loggers.adoc index 5eedc916eb45..b061a87c5b3e 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/loggers.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/loggers.adoc @@ -42,9 +42,10 @@ You have to provide the location of the OpenTelemetry logs endpoint to configure [configprops,yaml] ---- management: - otlp: + opentelemetry: logging: - endpoint: "https://otlp.example.com:4318/v1/logs" + export: + endpoint: "https://otlp.example.com:4318/v1/logs" ---- NOTE: The OpenTelemetry Logback appender and Log4j appender are not part of Spring Boot. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/tracing.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/tracing.adoc index b3dee9d618d4..b2d775d1d125 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/tracing.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/tracing.adoc @@ -138,7 +138,7 @@ Tracing with OpenTelemetry and reporting using OTLP requires the following depen Use the `management.otlp.tracing.*` configuration properties to configure reporting using OTLP. -NOTE: If you need to apply advanced customizations to OTLP span exporters, consider registering javadoc:org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpHttpSpanExporterBuilderCustomizer[] or javadoc:org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpGrpcSpanExporterBuilderCustomizer[] beans. +NOTE: If you need to apply advanced customizations to OTLP span exporters, consider registering javadoc:org.springframework.boot.tracing.autoconfigure.otlp.OtlpHttpSpanExporterBuilderCustomizer[] or javadoc:org.springframework.boot.tracing.autoconfigure.otlp.OtlpGrpcSpanExporterBuilderCustomizer[] beans. These will be invoked before the creation of the `OtlpHttpSpanExporter` or `OtlpGrpcSpanExporter`. The customizers take precedence over anything applied by the auto-configuration. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/nosql.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/nosql.adoc index 3710fcf6c3be..703a344f2ccc 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/nosql.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/nosql.adoc @@ -72,9 +72,9 @@ spring: ---- -TIP: You can also register an arbitrary number of beans that implement javadoc:org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer[] for more advanced customizations. -javadoc:io.lettuce.core.resource.ClientResources[] can also be customized using javadoc:org.springframework.boot.autoconfigure.data.redis.ClientResourcesBuilderCustomizer[]. -If you use Jedis, javadoc:org.springframework.boot.autoconfigure.data.redis.JedisClientConfigurationBuilderCustomizer[] is also available. +TIP: You can also register an arbitrary number of beans that implement javadoc:org.springframework.boot.data.redis.autoconfigure.LettuceClientConfigurationBuilderCustomizer[] for more advanced customizations. +javadoc:io.lettuce.core.resource.ClientResources[] can also be customized using javadoc:org.springframework.boot.data.redis.autoconfigure.ClientResourcesBuilderCustomizer[]. +If you use Jedis, javadoc:org.springframework.boot.data.redis.autoconfigure.JedisClientConfigurationBuilderCustomizer[] is also available. Alternatively, you can register a bean of type javadoc:org.springframework.data.redis.connection.RedisStandaloneConfiguration[], javadoc:org.springframework.data.redis.connection.RedisSentinelConfiguration[], or javadoc:org.springframework.data.redis.connection.RedisClusterConfiguration[] to take full control over the configuration. If you add your own javadoc:org.springframework.context.annotation.Bean[format=annotation] of any of the auto-configured types, it replaces the default (except in the case of javadoc:org.springframework.data.redis.core.RedisTemplate[], when the exclusion is based on the bean name, `redisTemplate`, not its type). @@ -261,7 +261,7 @@ spring: ---- The auto-configured javadoc:org.neo4j.driver.Driver[] is created using `org.neo4j.driver.Config$ConfigBuilder`. -To fine-tune its configuration, declare one or more javadoc:org.springframework.boot.autoconfigure.neo4j.ConfigBuilderCustomizer[] beans. +To fine-tune its configuration, declare one or more javadoc:org.springframework.boot.neo4j.autoconfigure.ConfigBuilderCustomizer[] beans. Each will be called in order with the `org.neo4j.driver.Config$ConfigBuilder` that is used to build the javadoc:org.neo4j.driver.Driver[]. @@ -335,7 +335,7 @@ spring: ==== Connecting to Elasticsearch Using RestClient If you have `elasticsearch-rest-client` on the classpath, Spring Boot will auto-configure and register a javadoc:org.springframework.web.client.RestClient[] bean. -In addition to the properties described previously, to fine-tune the javadoc:org.springframework.web.client.RestClient[] you can register an arbitrary number of beans that implement javadoc:org.springframework.boot.autoconfigure.elasticsearch.RestClientBuilderCustomizer[] for more advanced customizations. +In addition to the properties described previously, to fine-tune the javadoc:org.springframework.web.client.RestClient[] you can register an arbitrary number of beans that implement javadoc:org.springframework.boot.elasticsearch.autoconfigure.RestClientBuilderCustomizer[] for more advanced customizations. To take full control over the clients' configuration, define a javadoc:org.elasticsearch.client.RestClientBuilder[] bean. @@ -501,8 +501,8 @@ The Cassandra driver has its own configuration infrastructure that loads an `app Spring Boot does not look for such a file by default but can load one using `spring.cassandra.config`. If a property is both present in `+spring.cassandra.*+` and the configuration file, the value in `+spring.cassandra.*+` takes precedence. -For more advanced driver customizations, you can register an arbitrary number of beans that implement javadoc:org.springframework.boot.autoconfigure.cassandra.DriverConfigLoaderBuilderCustomizer[]. -The `CqlSession` can be customized with a bean of type javadoc:org.springframework.boot.autoconfigure.cassandra.CqlSessionBuilderCustomizer[]. +For more advanced driver customizations, you can register an arbitrary number of beans that implement javadoc:org.springframework.boot.cassandra.autoconfigure.DriverConfigLoaderBuilderCustomizer[]. +The `CqlSession` can be customized with a bean of type javadoc:org.springframework.boot.cassandra.autoconfigure.CqlSessionBuilderCustomizer[]. ==== NOTE: If you use `CqlSessionBuilder` to create multiple `CqlSession` beans, keep in mind the builder is mutable so make sure to inject a fresh copy for each session. @@ -602,7 +602,7 @@ spring: ---- TIP: Check the `spring.couchbase.env.*` properties for more details. -To take more control, one or more javadoc:org.springframework.boot.autoconfigure.couchbase.ClusterEnvironmentBuilderCustomizer[] beans can be used. +To take more control, one or more javadoc:org.springframework.boot.couchbase.autoconfigure.ClusterEnvironmentBuilderCustomizer[] beans can be used. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/sql.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/sql.adoc index 4a1615f10f22..178fd6457102 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/sql.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/data/sql.adoc @@ -252,7 +252,7 @@ include-code::CityRepository[] Spring Data JPA repositories support three different modes of bootstrapping: default, deferred, and lazy. To enable deferred or lazy bootstrapping, set the configprop:spring.data.jpa.repositories.bootstrap-mode[] property to `deferred` or `lazy` respectively. -When using deferred or lazy bootstrapping, the auto-configured javadoc:org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder[] will use the context's javadoc:org.springframework.core.task.AsyncTaskExecutor[], if any, as the bootstrap executor. +When using deferred or lazy bootstrapping, the auto-configured javadoc:org.springframework.boot.jpa.EntityManagerFactoryBuilder[] will use the context's javadoc:org.springframework.core.task.AsyncTaskExecutor[], if any, as the bootstrap executor. If more than one exists, the one named `applicationTaskExecutor` will be used. [NOTE] @@ -457,7 +457,7 @@ NOTE: Spring Boot can only auto-configure dialects supported by the open source [[data.sql.jooq.customizing]] === Customizing jOOQ -More advanced customizations can be achieved by defining your own javadoc:org.springframework.boot.autoconfigure.jooq.DefaultConfigurationCustomizer[] bean that will be invoked prior to creating the javadoc:org.jooq.Configuration[] javadoc:org.springframework.context.annotation.Bean[format=annotation]. +More advanced customizations can be achieved by defining your own javadoc:org.springframework.boot.jooq.autoconfigure.DefaultConfigurationCustomizer[] bean that will be invoked prior to creating the javadoc:org.jooq.Configuration[] javadoc:org.springframework.context.annotation.Bean[format=annotation]. This takes precedence to anything that is applied by the auto-configuration. You can also create your own javadoc:org.jooq.Configuration[] javadoc:org.springframework.context.annotation.Bean[format=annotation] if you want to take complete control of the jOOQ configuration. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc index af495d1af2b4..4b383d7c4a4e 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc @@ -89,10 +89,10 @@ The following service connections are currently supported: | javadoc:org.springframework.boot.autoconfigure.jms.artemis.ArtemisConnectionDetails[] | Containers named "apache/activemq-artemis" -| javadoc:org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails[] +| javadoc:org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails[] | Containers named "cassandra" or "bitnami/cassandra" -| javadoc:org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails[] +| javadoc:org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails[] | Containers named "elasticsearch" or "bitnami/elasticsearch" | javadoc:org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails[] @@ -101,22 +101,22 @@ The following service connections are currently supported: | javadoc:org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails[] | Containers named "clickhouse/clickhouse-server", "bitnami/clickhouse", "gvenzl/oracle-free", "gvenzl/oracle-xe", "mariadb", "bitnami/mariadb", "mssql/server", "mysql", "bitnami/mysql", "postgres", or "bitnami/postgresql" -| javadoc:org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails[] +| javadoc:org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails[] | Containers named "osixia/openldap", "lldap/lldap" | javadoc:org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails[] | Containers named "mongo" or "bitnami/mongodb" -| javadoc:org.springframework.boot.autoconfigure.neo4j.Neo4jConnectionDetails[] +| javadoc:org.springframework.boot.neo4j.autoconfigure.Neo4jConnectionDetails[] | Containers named "neo4j" or "bitnami/neo4j" -| javadoc:org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails[] +| javadoc:org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails[] | Containers named "otel/opentelemetry-collector-contrib", "grafana/otel-lgtm" -| javadoc:org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails[] +| javadoc:org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsConnectionDetails[] | Containers named "otel/opentelemetry-collector-contrib", "grafana/otel-lgtm" -| javadoc:org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails[] +| javadoc:org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails[] | Containers named "otel/opentelemetry-collector-contrib", "grafana/otel-lgtm" | javadoc:org.springframework.boot.autoconfigure.pulsar.PulsarConnectionDetails[] @@ -128,10 +128,10 @@ The following service connections are currently supported: | javadoc:org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails[] | Containers named "rabbitmq" or "bitnami/rabbitmq" -| javadoc:org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails[] +| javadoc:org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails[] | Containers named "redis", "bitnami/redis", "redis/redis-stack" or "redis/redis-stack-server" -| javadoc:org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails[] +| javadoc:org.springframework.boot.tracing.autoconfigure.zipkin.ZipkinConnectionDetails[] | Containers named "openzipkin/zipkin". |=== diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/external-config.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/external-config.adoc index f83238592204..95edc9c3948d 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/external-config.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/features/external-config.adoc @@ -782,7 +782,7 @@ The preceding POJO defines the following properties: * `my.service.enabled`, with a value of `false` by default. * `my.service.remote-address`, with a type that can be coerced from javadoc:java.lang.String[]. * `my.service.security.username`, with a nested "security" object whose name is determined by the name of the property. - In particular, the type is not used at all there and could have been javadoc:org.springframework.boot.autoconfigure.security.SecurityProperties[]. + In particular, the type is not used at all there and could have been javadoc:org.springframework.boot.security.autoconfigure.SecurityProperties[]. * `my.service.security.password`. * `my.service.security.roles`, with a collection of javadoc:java.lang.String[] that defaults to `USER`. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/email.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/email.adoc index be4cc8b04503..2a995b4968ae 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/email.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/email.adoc @@ -7,7 +7,7 @@ TIP: See the {url-spring-framework-docs}/integration/email.html[reference docume If `spring.mail.host` and the relevant libraries (as defined by `spring-boot-starter-mail`) are available, a default javadoc:org.springframework.mail.javamail.JavaMailSender[] is created if none exists. The sender can be further customized by configuration items from the `spring.mail` namespace. -See javadoc:org.springframework.boot.autoconfigure.mail.MailProperties[] for more details. +See javadoc:org.springframework.boot.mail.autoconfigure.MailProperties[] for more details. In particular, certain default timeout values are infinite, and you may want to change that to avoid having a thread blocked by an unresponsive mail server, as shown in the following example: diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/quartz.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/quartz.adoc index 7ff87db760f4..c572fc1ac3ea 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/quartz.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/quartz.adoc @@ -37,18 +37,18 @@ To use a custom script, set the configprop:spring.quartz.jdbc.schema[] property. Some of the standard scripts – such as those for SQL Server, Azure SQL, and Sybase – cannot be used without modification. In these cases, make a copy of the script and edit it as directed in the script's comments then set configprop:spring.quartz.jdbc.schema[] to use your customized script. -To have Quartz use a javadoc:javax.sql.DataSource[] other than the application's main javadoc:javax.sql.DataSource[], declare a javadoc:javax.sql.DataSource[] bean, annotating its javadoc:org.springframework.context.annotation.Bean[format=annotation] method with javadoc:org.springframework.boot.autoconfigure.quartz.QuartzDataSource[format=annotation]. +To have Quartz use a javadoc:javax.sql.DataSource[] other than the application's main javadoc:javax.sql.DataSource[], declare a javadoc:javax.sql.DataSource[] bean, annotating its javadoc:org.springframework.context.annotation.Bean[format=annotation] method with javadoc:org.springframework.boot.quartz.autoconfigure.QuartzDataSource[format=annotation]. Doing so ensures that the Quartz-specific javadoc:javax.sql.DataSource[] is used by both the javadoc:org.springframework.scheduling.quartz.SchedulerFactoryBean[] and for schema initialization. -Similarly, to have Quartz use a javadoc:org.springframework.transaction.TransactionManager[] other than the application's main javadoc:org.springframework.transaction.TransactionManager[] declare a javadoc:org.springframework.transaction.TransactionManager[] bean, annotating its javadoc:org.springframework.context.annotation.Bean[format=annotation] method with javadoc:org.springframework.boot.autoconfigure.quartz.QuartzTransactionManager[format=annotation]. +Similarly, to have Quartz use a javadoc:org.springframework.transaction.TransactionManager[] other than the application's main javadoc:org.springframework.transaction.TransactionManager[] declare a javadoc:org.springframework.transaction.TransactionManager[] bean, annotating its javadoc:org.springframework.context.annotation.Bean[format=annotation] method with javadoc:org.springframework.boot.quartz.autoconfigure.QuartzTransactionManager[format=annotation]. By default, jobs created by configuration will not overwrite already registered jobs that have been read from a persistent job store. To enable overwriting existing job definitions set the configprop:spring.quartz.overwrite-existing-jobs[] property. -Quartz Scheduler configuration can be customized using `spring.quartz` properties and javadoc:org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer[] beans, which allow programmatic javadoc:org.springframework.scheduling.quartz.SchedulerFactoryBean[] customization. +Quartz Scheduler configuration can be customized using `spring.quartz` properties and javadoc:org.springframework.boot.quartz.autoconfigure.SchedulerFactoryBeanCustomizer[] beans, which allow programmatic javadoc:org.springframework.scheduling.quartz.SchedulerFactoryBean[] customization. Advanced Quartz configuration properties can be customized using `spring.quartz.properties.*`. NOTE: In particular, an javadoc:java.util.concurrent.Executor[] bean is not associated with the scheduler as Quartz offers a way to configure the scheduler through `spring.quartz.properties`. -If you need to customize the task executor, consider implementing javadoc:org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer[]. +If you need to customize the task executor, consider implementing javadoc:org.springframework.boot.quartz.autoconfigure.SchedulerFactoryBeanCustomizer[]. Jobs can define setters to inject data map properties. Regular beans can also be injected in a similar manner, as shown in the following example: diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/rest-client.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/rest-client.adoc index 9d16ff97b17a..e26736c9a2c7 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/rest-client.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/rest-client.adoc @@ -127,7 +127,7 @@ The javadoc:org.springframework.web.client.RestClient[] interface provides a fun Spring Boot creates and pre-configures a prototype javadoc:org.springframework.web.client.RestClient$Builder[] bean for you. It is strongly advised to inject it in your components and use it to create javadoc:org.springframework.web.client.RestClient[] instances. -Spring Boot is configuring that builder with javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] and an appropriate javadoc:org.springframework.http.client.ClientHttpRequestFactory[]. +Spring Boot is configuring that builder with javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] and an appropriate javadoc:org.springframework.http.client.ClientHttpRequestFactory[]. The following code shows a typical example: @@ -156,9 +156,9 @@ TIP: You can also change the xref:io/rest-client.adoc#io.rest-client.clienthttpr [[io.rest-client.restclient.ssl]] === RestClient SSL Support -If you need custom SSL configuration on the javadoc:org.springframework.http.client.ClientHttpRequestFactory[] used by the javadoc:org.springframework.web.client.RestClient[], you can inject a javadoc:org.springframework.boot.autoconfigure.web.client.RestClientSsl[] instance that can be used with the builder's `apply` method. +If you need custom SSL configuration on the javadoc:org.springframework.http.client.ClientHttpRequestFactory[] used by the javadoc:org.springframework.web.client.RestClient[], you can inject a javadoc:org.springframework.boot.restclient.autoconfigure.RestClientSsl[] instance that can be used with the builder's `apply` method. -The javadoc:org.springframework.boot.autoconfigure.web.client.RestClientSsl[] interface provides access to any xref:features/ssl.adoc#features.ssl.bundles[SSL bundles] that you have defined in your `application.properties` or `application.yaml` file. +The javadoc:org.springframework.boot.restclient.autoconfigure.RestClientSsl[] interface provides access to any xref:features/ssl.adoc#features.ssl.bundles[SSL bundles] that you have defined in your `application.properties` or `application.yaml` file. The following code shows a typical example: @@ -178,7 +178,7 @@ You might choose to use javadoc:org.springframework.web.client.RestTemplate[] wh Since javadoc:org.springframework.web.client.RestTemplate[] instances often need to be customized before being used, Spring Boot does not provide any single auto-configured javadoc:org.springframework.web.client.RestTemplate[] bean. It does, however, auto-configure a javadoc:org.springframework.boot.web.client.RestTemplateBuilder[], which can be used to create javadoc:org.springframework.web.client.RestTemplate[] instances when needed. -The auto-configured javadoc:org.springframework.boot.web.client.RestTemplateBuilder[] ensures that sensible javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] and an appropriate javadoc:org.springframework.http.client.ClientHttpRequestFactory[] are applied to javadoc:org.springframework.web.client.RestTemplate[] instances. +The auto-configured javadoc:org.springframework.boot.web.client.RestTemplateBuilder[] ensures that sensible javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] and an appropriate javadoc:org.springframework.http.client.ClientHttpRequestFactory[] are applied to javadoc:org.springframework.web.client.RestTemplate[] instances. The following code shows a typical example: diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/messaging/jms.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/messaging/jms.adoc index f90e04902828..7076811b571b 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/messaging/jms.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/messaging/jms.adoc @@ -180,7 +180,7 @@ include-code::MyBean[] TIP: See the javadoc:org.springframework.jms.annotation.EnableJms[format=annotation] API documentation for more details. -If you need to create more javadoc:org.springframework.jms.config.JmsListenerContainerFactory[] instances or if you want to override the default, Spring Boot provides a javadoc:org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer[] that you can use to initialize a javadoc:org.springframework.jms.config.DefaultJmsListenerContainerFactory[] with the same settings as the one that is auto-configured. +If you need to create more javadoc:org.springframework.jms.config.JmsListenerContainerFactory[] instances or if you want to override the default, Spring Boot provides a javadoc:org.springframework.boot.jms.autoconfigure.DefaultJmsListenerContainerFactoryConfigurer[] that you can use to initialize a javadoc:org.springframework.jms.config.DefaultJmsListenerContainerFactory[] with the same settings as the one that is auto-configured. For instance, the following example exposes another factory that uses a specific javadoc:org.springframework.jms.support.converter.MessageConverter[]: diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/spring-boot-applications.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/spring-boot-applications.adoc index f9b8ac9a02db..76f404b91e91 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/spring-boot-applications.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/spring-boot-applications.adoc @@ -233,7 +233,7 @@ Regardless of your classpath, tracing components which are reporting data are no If you need those components as part of an integration test, annotate the test with javadoc:org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability[format=annotation]. -If you have created your own reporting components (e.g. a custom javadoc:io.opentelemetry.sdk.trace.export.SpanExporter[] or `brave.handler.SpanHandler`) and you don't want them to be active in tests, you can use the javadoc:org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing[format=annotation] annotation to disable them. +If you have created your own reporting components (e.g. a custom javadoc:io.opentelemetry.sdk.trace.export.SpanExporter[] or `brave.handler.SpanHandler`) and you don't want them to be active in tests, you can use the javadoc:org.springframework.boot.tracing.autoconfigure.ConditionalOnEnabledTracing[format=annotation] annotation to disable them. If you annotate xref:testing/spring-boot-applications.adoc#testing.spring-boot-applications.autoconfigured-tests[a sliced test] with javadoc:org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability[format=annotation], it auto-configures a no-op javadoc:io.micrometer.tracing.Tracer[]. Data exporting in sliced tests is not supported with the javadoc:org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability[format=annotation] annotation. @@ -426,7 +426,7 @@ There are javadoc:org.springframework.graphql.test.tester.GraphQlTester[] varian Spring Boot helps you to test your {url-spring-graphql-docs}/controllers.html[Spring GraphQL Controllers] with the javadoc:org.springframework.boot.test.autoconfigure.graphql.GraphQlTest[format=annotation] annotation. javadoc:org.springframework.boot.test.autoconfigure.graphql.GraphQlTest[format=annotation] auto-configures the Spring GraphQL infrastructure, without any transport nor server being involved. -This limits scanned beans to javadoc:org.springframework.stereotype.Controller[format=annotation], javadoc:org.springframework.graphql.execution.RuntimeWiringConfigurer[], javadoc:org.springframework.boot.jackson.JsonComponent[], javadoc:org.springframework.core.convert.converter.Converter[], javadoc:org.springframework.core.convert.converter.GenericConverter[], javadoc:org.springframework.graphql.execution.DataFetcherExceptionResolver[], javadoc:graphql.execution.instrumentation.Instrumentation[] and javadoc:org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer[]. +This limits scanned beans to javadoc:org.springframework.stereotype.Controller[format=annotation], javadoc:org.springframework.graphql.execution.RuntimeWiringConfigurer[], javadoc:org.springframework.boot.jackson.JsonComponent[], javadoc:org.springframework.core.convert.converter.Converter[], javadoc:org.springframework.core.convert.converter.GenericConverter[], javadoc:org.springframework.graphql.execution.DataFetcherExceptionResolver[], javadoc:graphql.execution.instrumentation.Instrumentation[] and javadoc:org.springframework.boot.graphql.autoconfigure.GraphQlSourceBuilderCustomizer[]. Regular javadoc:org.springframework.stereotype.Component[format=annotation] and javadoc:org.springframework.boot.context.properties.ConfigurationProperties[format=annotation] beans are not scanned when the javadoc:org.springframework.boot.test.autoconfigure.graphql.GraphQlTest[format=annotation] annotation is used. javadoc:org.springframework.boot.context.properties.EnableConfigurationProperties[format=annotation] can be used to include javadoc:org.springframework.boot.context.properties.ConfigurationProperties[format=annotation] beans. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc index e91148b517d0..6cae636a7898 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/testing/testcontainers.adoc @@ -107,7 +107,7 @@ When using Testcontainers, connection details can be automatically created for a include-code::MyIntegrationTests[] Thanks to javadoc:org.springframework.boot.testcontainers.service.connection.ServiceConnection[format=annotation], the above configuration allows Neo4j-related beans in the application to communicate with Neo4j running inside the Testcontainers-managed Docker container. -This is done by automatically defining a javadoc:org.springframework.boot.autoconfigure.neo4j.Neo4jConnectionDetails[] bean which is then used by the Neo4j auto-configuration, overriding any connection-related configuration properties. +This is done by automatically defining a javadoc:org.springframework.boot.neo4j.autoconfigure.Neo4jConnectionDetails[] bean which is then used by the Neo4j auto-configuration, overriding any connection-related configuration properties. NOTE: You'll need to add the `spring-boot-testcontainers` module as a test dependency in order to use service connections with Testcontainers. @@ -125,13 +125,13 @@ The following service connection factories are provided in the `spring-boot-test | javadoc:org.springframework.boot.autoconfigure.jms.artemis.ArtemisConnectionDetails[] | Containers of type javadoc:org.testcontainers.activemq.ArtemisContainer[] -| javadoc:org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails[] +| javadoc:org.springframework.boot.cassandra.autoconfigure.CassandraConnectionDetails[] | Containers of type javadoc:org.testcontainers.cassandra.CassandraContainer[] -| javadoc:org.springframework.boot.autoconfigure.couchbase.CouchbaseConnectionDetails[] +| javadoc:org.springframework.boot.couchbase.autoconfigure.CouchbaseConnectionDetails[] | Containers of type javadoc:org.testcontainers.couchbase.CouchbaseContainer[] -| javadoc:org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails[] +| javadoc:org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails[] | Containers of type javadoc:org.testcontainers.elasticsearch.ElasticsearchContainer[] | javadoc:org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails[] @@ -143,7 +143,7 @@ The following service connection factories are provided in the `spring-boot-test | javadoc:org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails[] | Containers of type javadoc:org.testcontainers.kafka.KafkaContainer[], javadoc:org.testcontainers.kafka.ConfluentKafkaContainer[] or javadoc:org.testcontainers.redpanda.RedpandaContainer[] -| javadoc:org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails[] +| javadoc:org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails[] | Containers named "osixia/openldap" or of type javadoc:org.testcontainers.ldap.LLdapContainer[] | javadoc:org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails[] @@ -152,16 +152,16 @@ The following service connection factories are provided in the `spring-boot-test | javadoc:org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails[] | Containers of type javadoc:{url-testcontainers-mongodb-javadoc}/org.testcontainers.containers.MongoDBContainer[] -| javadoc:org.springframework.boot.autoconfigure.neo4j.Neo4jConnectionDetails[] +| javadoc:org.springframework.boot.neo4j.autoconfigure.Neo4jConnectionDetails[] | Containers of type javadoc:{url-testcontainers-neo4j-javadoc}/org.testcontainers.containers.Neo4jContainer[] -| javadoc:org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails[] +| javadoc:org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails[] | Containers named "otel/opentelemetry-collector-contrib" or of type javadoc:org.testcontainers.grafana.LgtmStackContainer[] -| javadoc:org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails[] +| javadoc:org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsConnectionDetails[] | Containers named "otel/opentelemetry-collector-contrib" or of type javadoc:org.testcontainers.grafana.LgtmStackContainer[] -| javadoc:org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails[] +| javadoc:org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails[] | Containers named "otel/opentelemetry-collector-contrib" or of type javadoc:org.testcontainers.grafana.LgtmStackContainer[] | javadoc:org.springframework.boot.autoconfigure.pulsar.PulsarConnectionDetails[] @@ -176,10 +176,10 @@ javadoc:org.testcontainers.oracle.OracleContainer[OracleContainer (free)], javad | javadoc:org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails[] | Containers of type javadoc:{url-testcontainers-rabbitmq-javadoc}/org.testcontainers.containers.RabbitMQContainer[] -| javadoc:org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails[] +| javadoc:org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails[] | Containers of type javadoc:com.redis.testcontainers.RedisContainer[] or javadoc:com.redis.testcontainers.RedisStackContainer[], or containers named "redis", "redis/redis-stack" or "redis/redis-stack-server" -| javadoc:org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails[] +| javadoc:org.springframework.boot.tracing.autoconfigure.zipkin.ZipkinConnectionDetails[] | Containers named "openzipkin/zipkin" |=== @@ -205,7 +205,7 @@ include-code::MyRedisConfiguration[] Spring Boot can't tell from javadoc:org.testcontainers.containers.GenericContainer[] which container image is used, so the `name` attribute from javadoc:org.springframework.boot.testcontainers.service.connection.ServiceConnection[format=annotation] must be used to provide that hint. You can also use the `name` attribute of javadoc:org.springframework.boot.testcontainers.service.connection.ServiceConnection[format=annotation] to override which connection detail will be used, for example when using custom images. -If you are using the Docker image `registry.mycompany.com/mirror/myredis`, you'd use `@ServiceConnection(name="redis")` to ensure javadoc:org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails[] are created. +If you are using the Docker image `registry.mycompany.com/mirror/myredis`, you'd use `@ServiceConnection(name="redis")` to ensure javadoc:org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails[] are created. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc index ef92b27b99c7..791010816561 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc @@ -269,7 +269,7 @@ When it does so, the orders shown in the following table will be used: | javadoc:org.springframework.security.web.server.WebFilterChainProxy[] (Spring Security) | `-100` -| javadoc:org.springframework.boot.actuate.web.exchanges.reactive.HttpExchangesWebFilter[] +| javadoc:org.springframework.boot.webflux.actuate.web.exchanges.HttpExchangesWebFilter[] | `Ordered.LOWEST_PRECEDENCE - 10` |=== diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/servlet.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/servlet.adoc index ba3088f09176..e411e5c2bb1d 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/servlet.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/servlet.adoc @@ -40,7 +40,7 @@ In addition to Spring MVC's defaults, the auto-configuration provides the follow * Inclusion of javadoc:org.springframework.web.servlet.view.ContentNegotiatingViewResolver[] and javadoc:org.springframework.web.servlet.view.BeanNameViewResolver[] beans. * Support for serving static resources, including support for WebJars (covered xref:web/servlet.adoc#web.servlet.spring-mvc.static-content[later in this document]). * Automatic registration of javadoc:org.springframework.core.convert.converter.Converter[], javadoc:org.springframework.core.convert.converter.GenericConverter[], and javadoc:org.springframework.format.Formatter[] beans. -* Support for javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] (covered xref:web/servlet.adoc#web.servlet.spring-mvc.message-converters[later in this document]). +* Support for javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] (covered xref:web/servlet.adoc#web.servlet.spring-mvc.message-converters[later in this document]). * Automatic registration of javadoc:org.springframework.validation.MessageCodesResolver[] (covered xref:web/servlet.adoc#web.servlet.spring-mvc.message-codes[later in this document]). * Static `index.html` support. * Automatic use of a javadoc:org.springframework.web.bind.support.ConfigurableWebBindingInitializer[] bean (covered xref:web/servlet.adoc#web.servlet.spring-mvc.binding-initializer[later in this document]). @@ -97,11 +97,11 @@ By default, strings are encoded in `UTF-8`. Any javadoc:org.springframework.http.converter.HttpMessageConverter[] bean that is present in the context is added to the list of converters. You can also override default converters in the same way. -If you need to add or customize converters, you can use Spring Boot's javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] class, as shown in the following listing: +If you need to add or customize converters, you can use Spring Boot's javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] class, as shown in the following listing: include-code::MyHttpMessageConvertersConfiguration[] -For further control, you can also sub-class javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] and override its `postProcessConverters` and/or `postProcessPartConverters` methods. +For further control, you can also sub-class javadoc:org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters[] and override its `postProcessConverters` and/or `postProcessPartConverters` methods. This can be useful when you want to re-order or remove some of the converters that Spring MVC configures by default. diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/spring-security.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/spring-security.adoc index 859cee78a190..25188324c4b2 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/spring-security.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/spring-security.adoc @@ -17,14 +17,14 @@ Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35 This generated password is for development use only. Your security configuration must be updated before running your application in production. ---- -NOTE: If you fine-tune your logging configuration, ensure that the `org.springframework.boot.autoconfigure.security` category is set to log `WARN`-level messages. +NOTE: If you fine-tune your logging configuration, ensure that the `org.springframework.boot.security.autoconfigure` category is set to log `WARN`-level messages. Otherwise, the default password is not printed. You can change the username and password by providing a `spring.security.user.name` and `spring.security.user.password`. The basic features you get by default in a web application are: -* A javadoc:org.springframework.security.core.userdetails.UserDetailsService[] (or javadoc:org.springframework.security.core.userdetails.ReactiveUserDetailsService[] in case of a WebFlux application) bean with in-memory store and a single user with a generated password (see javadoc:org.springframework.boot.autoconfigure.security.SecurityProperties$User[] for the properties of the user). +* A javadoc:org.springframework.security.core.userdetails.UserDetailsService[] (or javadoc:org.springframework.security.core.userdetails.ReactiveUserDetailsService[] in case of a WebFlux application) bean with in-memory store and a single user with a generated password (see javadoc:org.springframework.boot.security.autoconfigure.SecurityProperties$User[] for the properties of the user). * Form-based login or HTTP Basic security (depending on the `Accept` header in the request) for the entire application (including actuator endpoints if actuator is on the classpath). * A javadoc:org.springframework.security.authentication.DefaultAuthenticationEventPublisher[] for publishing authentication events. @@ -35,8 +35,8 @@ You can provide a different javadoc:org.springframework.security.authentication. [[web.security.spring-mvc]] == MVC Security -The default security configuration is implemented in javadoc:org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration[] and javadoc:org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration[]. -javadoc:org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration[] imports `SpringBootWebSecurityConfiguration` for web security and javadoc:org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration[] for authentication. +The default security configuration is implemented in javadoc:org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration[] and javadoc:org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration[]. +javadoc:org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration[] imports `SpringBootWebSecurityConfiguration` for web security and javadoc:org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration[] for authentication. To completely switch off the default web application security configuration, including Actuator security, or to combine multiple Spring Security components such as OAuth2 Client and Resource Server, add a bean of type javadoc:org.springframework.security.web.SecurityFilterChain[] (doing so does not disable the javadoc:org.springframework.security.core.userdetails.UserDetailsService[] configuration). To also switch off the javadoc:org.springframework.security.core.userdetails.UserDetailsService[] configuration, add a bean of type javadoc:org.springframework.security.core.userdetails.UserDetailsService[], javadoc:org.springframework.security.authentication.AuthenticationProvider[], or javadoc:org.springframework.security.authentication.AuthenticationManager[]. @@ -52,7 +52,7 @@ To use javadoc:org.springframework.security.core.userdetails.UserDetailsService[ Access rules can be overridden by adding a custom javadoc:org.springframework.security.web.SecurityFilterChain[] bean. Spring Boot provides convenience methods that can be used to override access rules for actuator endpoints and static resources. javadoc:org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest[] can be used to create a javadoc:org.springframework.security.web.util.matcher.RequestMatcher[] that is based on the configprop:management.endpoints.web.base-path[] property. -javadoc:org.springframework.boot.autoconfigure.security.servlet.PathRequest[] can be used to create a javadoc:org.springframework.security.web.util.matcher.RequestMatcher[] for resources in commonly used locations. +javadoc:org.springframework.boot.security.autoconfigure.servlet.PathRequest[] can be used to create a javadoc:org.springframework.security.web.util.matcher.RequestMatcher[] for resources in commonly used locations. @@ -60,8 +60,8 @@ javadoc:org.springframework.boot.autoconfigure.security.servlet.PathRequest[] ca == WebFlux Security Similar to Spring MVC applications, you can secure your WebFlux applications by adding the `spring-boot-starter-security` dependency. -The default security configuration is implemented in javadoc:org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration[] and javadoc:org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration[]. -javadoc:org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration[] imports `WebFluxSecurityConfiguration` for web security and javadoc:org.springframework.boot.autoconfigure.security.reactive.UserDetailsServiceAutoConfiguration[] for authentication. +The default security configuration is implemented in javadoc:org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration[] and javadoc:org.springframework.boot.security.autoconfigure.reactive.ReactiveUserDetailsServiceAutoConfiguration[]. +javadoc:org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration[] imports `WebFluxSecurityConfiguration` for web security and javadoc:org.springframework.boot.security.autoconfigure.reactive.ReactiveUserDetailsServiceAutoConfiguration[] for authentication. In addition to reactive web applications, the latter is also auto-configured when RSocket is in use. To completely switch off the default web application security configuration, including Actuator security, add a bean of type javadoc:org.springframework.security.web.server.WebFilterChainProxy[] (doing so does not disable the javadoc:org.springframework.security.core.userdetails.ReactiveUserDetailsService[] configuration). @@ -78,7 +78,7 @@ Access rules and the use of multiple Spring Security components such as OAuth 2 Spring Boot provides convenience methods that can be used to override access rules for actuator endpoints and static resources. javadoc:org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest[] can be used to create a javadoc:org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher[] that is based on the configprop:management.endpoints.web.base-path[] property. -javadoc:org.springframework.boot.autoconfigure.security.reactive.PathRequest[] can be used to create a javadoc:org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher[] for resources in commonly used locations. +javadoc:org.springframework.boot.security.autoconfigure.PathRequest[] can be used to create a javadoc:org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher[] for resources in commonly used locations. For example, you can customize your security configuration by adding something like: @@ -97,7 +97,7 @@ https://oauth.net/2/[OAuth2] is a widely used authorization framework that is su === Client If you have `spring-security-oauth2-client` on your classpath, you can take advantage of some auto-configuration to set up OAuth2/Open ID Connect clients. -This configuration makes use of the properties under javadoc:org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties[]. +This configuration makes use of the properties under javadoc:org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientProperties[]. The same properties are applicable to both servlet and reactive applications. You can register multiple OAuth2 clients and providers under the `spring.security.oauth2.client` prefix, as shown in the following example: @@ -356,7 +356,7 @@ Additional information can be found in the {url-spring-authorization-server-docs === Relying Party If you have `spring-security-saml2-service-provider` on your classpath, you can take advantage of some auto-configuration to set up a SAML 2.0 Relying Party. -This configuration makes use of the properties under javadoc:org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties[]. +This configuration makes use of the properties under javadoc:org.springframework.boot.security.autoconfigure.saml2.Saml2RelyingPartyProperties[]. A relying party registration represents a paired configuration between an Identity Provider, IDP, and a Service Provider, SP. You can register multiple relying parties under the `spring.security.saml2.relyingparty` prefix, as shown in the following example: diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/specification/pages/configuration-metadata/format.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/specification/pages/configuration-metadata/format.adoc index ae560f89901b..4b7e96f898be 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/specification/pages/configuration-metadata/format.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/specification/pages/configuration-metadata/format.adoc @@ -14,8 +14,8 @@ They use a JSON format with items categorized under either "`groups`" or "`prope }, { "name": "spring.jpa.hibernate", - "type": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate", - "sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties", + "type": "org.springframework.boot.jpa.autoconfigure.JpaProperties$Hibernate", + "sourceType": "org.springframework.boot.jpa.autoconfigure.JpaProperties", "sourceMethod": "getHibernate()" } ... @@ -34,7 +34,7 @@ They use a JSON format with items categorized under either "`groups`" or "`prope "name": "spring.jpa.hibernate.ddl-auto", "type": "java.lang.String", "description": "DDL mode. This is actually a shortcut for the \"hibernate.hbm2ddl.auto\" property.", - "sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate" + "sourceType": "org.springframework.boot.jpa.autoconfigure.JpaProperties$Hibernate" } ... ],"hints": [ diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyCloudFoundryConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyCloudFoundryConfiguration.java index 9508798905a5..3474d0b8bcfc 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyCloudFoundryConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyCloudFoundryConfiguration.java @@ -30,7 +30,7 @@ import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyReactiveCloudFoundryConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyReactiveCloudFoundryConfiguration.java index a265ed85c48f..2831080a19a3 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyReactiveCloudFoundryConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyReactiveCloudFoundryConfiguration.java @@ -20,8 +20,8 @@ import reactor.core.publisher.Mono; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.webflux.autoconfigure.WebFluxProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/health/reactivehealthindicators/MyReactiveHealthIndicator.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/health/reactivehealthindicators/MyReactiveHealthIndicator.java index e464cddc41a4..40673f4257cd 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/health/reactivehealthindicators/MyReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/health/reactivehealthindicators/MyReactiveHealthIndicator.java @@ -18,8 +18,8 @@ import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; import org.springframework.stereotype.Component; @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/health/writingcustomhealthindicators/MyHealthIndicator.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/health/writingcustomhealthindicators/MyHealthIndicator.java index 0e275f73c819..f2d6d35dfccf 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/health/writingcustomhealthindicators/MyHealthIndicator.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/health/writingcustomhealthindicators/MyHealthIndicator.java @@ -16,8 +16,8 @@ package org.springframework.boot.docs.actuator.endpoints.health.writingcustomhealthindicators; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.stereotype.Component; @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.java index f7b48ab12a7c..e8840663d993 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.endpoints.security.exposeall; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.java index 06adec63f493..20ed72a11b17 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.endpoints.security.typical; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/gettingstarted/commontags/MyMeterRegistryConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/gettingstarted/commontags/MyMeterRegistryConfiguration.java index 6d2fbfd23945..986c3bac4bae 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/gettingstarted/commontags/MyMeterRegistryConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/gettingstarted/commontags/MyMeterRegistryConfiguration.java @@ -18,7 +18,7 @@ import io.micrometer.core.instrument.MeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; +import org.springframework.boot.metrics.autoconfigure.MeterRegistryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/gettingstarted/specifictype/MyMeterRegistryConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/gettingstarted/specifictype/MyMeterRegistryConfiguration.java index 874496c3c796..4a5969eef7bb 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/gettingstarted/specifictype/MyMeterRegistryConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/gettingstarted/specifictype/MyMeterRegistryConfiguration.java @@ -20,7 +20,7 @@ import io.micrometer.core.instrument.config.NamingConvention; import io.micrometer.graphite.GraphiteMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; +import org.springframework.boot.metrics.autoconfigure.MeterRegistryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java index 5da48737906b..265af6d339f3 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/h2webconsole/springsecurity/DevProfileSecurityConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.data.sql.h2webconsole.springsecurity; -import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.boot.security.autoconfigure.servlet.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/r2dbc/MyPostgresR2dbcConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/r2dbc/MyPostgresR2dbcConfiguration.java index 1476c0b0d588..2b47e2458b88 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/r2dbc/MyPostgresR2dbcConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/r2dbc/MyPostgresR2dbcConfiguration.java @@ -21,7 +21,7 @@ import io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider; -import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer; +import org.springframework.boot.r2dbc.autoconfigure.ConnectionFactoryOptionsBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/r2dbc/MyR2dbcConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/r2dbc/MyR2dbcConfiguration.java index 3b99e7068fab..590bda22e10d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/r2dbc/MyR2dbcConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/data/sql/r2dbc/MyR2dbcConfiguration.java @@ -18,7 +18,7 @@ import io.r2dbc.spi.ConnectionFactoryOptions; -import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer; +import org.springframework.boot.r2dbc.autoconfigure.ConnectionFactoryOptionsBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MyHealthMetricsExportConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MyHealthMetricsExportConfiguration.java index 19af53f53e44..57cc3e2f3c05 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MyHealthMetricsExportConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MyHealthMetricsExportConfiguration.java @@ -20,7 +20,7 @@ import io.micrometer.core.instrument.MeterRegistry; import org.springframework.boot.actuate.health.HealthEndpoint; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Status; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configureacomponentthatisusedbyjpa/ElasticsearchEntityManagerFactoryDependsOnPostProcessor.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configureacomponentthatisusedbyjpa/ElasticsearchEntityManagerFactoryDependsOnPostProcessor.java index 88609cddb272..cbb295390b98 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configureacomponentthatisusedbyjpa/ElasticsearchEntityManagerFactoryDependsOnPostProcessor.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configureacomponentthatisusedbyjpa/ElasticsearchEntityManagerFactoryDependsOnPostProcessor.java @@ -18,7 +18,7 @@ import jakarta.persistence.EntityManagerFactory; -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryDependsOnPostProcessor; import org.springframework.stereotype.Component; /** diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configurecustomdatasource/configurable/MyDataSourceConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configurecustomdatasource/configurable/MyDataSourceConfiguration.java index 5a09972856fe..349c373e1243 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configurecustomdatasource/configurable/MyDataSourceConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configurecustomdatasource/configurable/MyDataSourceConfiguration.java @@ -18,8 +18,8 @@ import com.zaxxer.hikari.HikariDataSource; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configurehibernatesecondlevelcaching/MyHibernateSecondLevelCacheConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configurehibernatesecondlevelcaching/MyHibernateSecondLevelCacheConfiguration.java index 3b91491ef536..c2728ee48804 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configurehibernatesecondlevelcaching/MyHibernateSecondLevelCacheConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configurehibernatesecondlevelcaching/MyHibernateSecondLevelCacheConfiguration.java @@ -18,7 +18,7 @@ import org.hibernate.cache.jcache.ConfigSettings; -import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; +import org.springframework.boot.hibernate.autoconfigure.HibernatePropertiesCustomizer; import org.springframework.cache.jcache.JCacheCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteAdditionalDataSourceConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteAdditionalDataSourceConfiguration.java index 4153c61335bf..517f5d4b1bd7 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteAdditionalDataSourceConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteAdditionalDataSourceConfiguration.java @@ -19,8 +19,8 @@ import com.zaxxer.hikari.HikariDataSource; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/usemultipleentitymanagers/MyAdditionalEntityManagerFactoryConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/usemultipleentitymanagers/MyAdditionalEntityManagerFactoryConfiguration.java index 5edd1010fd32..8eab233044c9 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/usemultipleentitymanagers/MyAdditionalEntityManagerFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/dataaccess/usemultipleentitymanagers/MyAdditionalEntityManagerFactoryConfiguration.java @@ -23,9 +23,9 @@ import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jpa.autoconfigure.JpaProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.JpaVendorAdapter; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/messaging/disabletransactedjmssession/MyJmsConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/messaging/disabletransactedjmssession/MyJmsConfiguration.java index a1b1b321960b..e9ce2e12e0f2 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/messaging/disabletransactedjmssession/MyJmsConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/messaging/disabletransactedjmssession/MyJmsConfiguration.java @@ -18,8 +18,8 @@ import jakarta.jms.ConnectionFactory; -import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.boot.jms.ConnectionFactoryUnwrapper; +import org.springframework.boot.jms.autoconfigure.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/configure/MyTomcatWebServerCustomizer.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/configure/MyTomcatWebServerCustomizer.java index 5531fa48a9f2..cdd744dc5b39 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/configure/MyTomcatWebServerCustomizer.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/configure/MyTomcatWebServerCustomizer.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.howto.webserver.configure; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java index 47279a9d6785..6c5739954e19 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java @@ -18,7 +18,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyWebIntegrationTests { diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultipleconnectorsintomcat/MyTomcatConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultipleconnectorsintomcat/MyTomcatConfiguration.java index 40d0cbe81473..4a75b16c4b51 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultipleconnectorsintomcat/MyTomcatConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultipleconnectorsintomcat/MyTomcatConfiguration.java @@ -18,7 +18,7 @@ import org.apache.catalina.connector.Connector; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -28,7 +28,7 @@ public class MyTomcatConfiguration { @Bean public WebServerFactoryCustomizer connectorCustomizer() { - return (tomcat) -> tomcat.addAdditionalTomcatConnectors(createConnector()); + return (tomcat) -> tomcat.addAdditionalConnectors(createConnector()); } private Connector createConnector() { diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.java index b06062b3f4e9..2f8d48bbaba0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.java @@ -18,7 +18,7 @@ import io.undertow.Undertow.Builder; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/MyCacheManagerConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/MyCacheManagerConfiguration.java index 651f9b05dda8..84ec0bc57795 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/MyCacheManagerConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/MyCacheManagerConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.caching.provider; -import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer; +import org.springframework.boot.cache.autoconfigure.CacheManagerCustomizer; import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/cache2k/MyCache2kDefaultsConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/cache2k/MyCache2kDefaultsConfiguration.java index 0334ed2391e8..4f7f2be94ad2 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/cache2k/MyCache2kDefaultsConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/cache2k/MyCache2kDefaultsConfiguration.java @@ -18,7 +18,7 @@ import java.util.concurrent.TimeUnit; -import org.springframework.boot.autoconfigure.cache.Cache2kBuilderCustomizer; +import org.springframework.boot.cache.autoconfigure.Cache2kBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/couchbase/MyCouchbaseCacheManagerConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/couchbase/MyCouchbaseCacheManagerConfiguration.java index 089c8a7d396b..c2a28e87dfa6 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/couchbase/MyCouchbaseCacheManagerConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/couchbase/MyCouchbaseCacheManagerConfiguration.java @@ -18,7 +18,7 @@ import java.time.Duration; -import org.springframework.boot.autoconfigure.cache.CouchbaseCacheManagerBuilderCustomizer; +import org.springframework.boot.cache.autoconfigure.CouchbaseCacheManagerBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.couchbase.cache.CouchbaseCacheConfiguration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/redis/MyRedisCacheManagerConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/redis/MyRedisCacheManagerConfiguration.java index e18f529a4126..d6d1747529aa 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/redis/MyRedisCacheManagerConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/caching/provider/redis/MyRedisCacheManagerConfiguration.java @@ -18,7 +18,7 @@ import java.time.Duration; -import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer; +import org.springframework.boot.cache.autoconfigure.RedisCacheManagerBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/restclient/ssl/MyService.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/restclient/ssl/MyService.java index 305eee262202..4175411fb353 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/restclient/ssl/MyService.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/restclient/ssl/MyService.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.restclient.restclient.ssl; -import org.springframework.boot.autoconfigure.web.client.RestClientSsl; +import org.springframework.boot.restclient.autoconfigure.RestClientSsl; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/MyService.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/MyService.java index 8715ab5462be..a537d11bf0b2 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/MyService.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/MyService.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.restclient.resttemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateBuilderConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateBuilderConfiguration.java index 7fea4f3ee870..f9a6d113bbeb 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateBuilderConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateBuilderConfiguration.java @@ -18,8 +18,8 @@ import java.time.Duration; -import org.springframework.boot.autoconfigure.web.client.RestTemplateBuilderConfigurer; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.autoconfigure.RestTemplateBuilderConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateCustomizer.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateCustomizer.java index 124ddf2655e8..98e052a18636 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateCustomizer.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateCustomizer.java @@ -24,7 +24,7 @@ import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.protocol.HttpContext; -import org.springframework.boot.web.client.RestTemplateCustomizer; +import org.springframework.boot.restclient.RestTemplateCustomizer; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/ssl/MyService.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/ssl/MyService.java index 247f986d42a7..d488da14a66c 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/ssl/MyService.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/resttemplate/ssl/MyService.java @@ -17,8 +17,8 @@ package org.springframework.boot.docs.io.restclient.resttemplate.ssl; import org.springframework.boot.docs.io.restclient.resttemplate.Details; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/webclient/ssl/MyService.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/webclient/ssl/MyService.java index 8fb3c38ea3f8..fbc972ace30d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/webclient/ssl/MyService.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/webclient/ssl/MyService.java @@ -18,7 +18,7 @@ import reactor.core.publisher.Mono; -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientSsl; +import org.springframework.boot.webclient.autoconfigure.WebClientSsl; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/messaging/amqp/receiving/custom/MyRabbitConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/messaging/amqp/receiving/custom/MyRabbitConfiguration.java index 36e398302cd3..e109d5de244a 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/messaging/amqp/receiving/custom/MyRabbitConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/messaging/amqp/receiving/custom/MyRabbitConfiguration.java @@ -18,7 +18,7 @@ import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; -import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer; +import org.springframework.boot.amqp.autoconfigure.SimpleRabbitListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/messaging/jms/receiving/custom/MyJmsConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/messaging/jms/receiving/custom/MyJmsConfiguration.java index 4dbaac9b3dfa..851dc043abdc 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/messaging/jms/receiving/custom/MyJmsConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/messaging/jms/receiving/custom/MyJmsConfiguration.java @@ -18,8 +18,8 @@ import jakarta.jms.ConnectionFactory; -import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.boot.jms.ConnectionFactoryUnwrapper; +import org.springframework.boot.jms.autoconfigure.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/additionalautoconfigurationandslicing/MyJdbcTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/additionalautoconfigurationandslicing/MyJdbcTests.java index d9df1dc8e8e7..caea37553698 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/additionalautoconfigurationandslicing/MyJdbcTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/additionalautoconfigurationandslicing/MyJdbcTests.java @@ -17,7 +17,7 @@ package org.springframework.boot.docs.testing.springbootapplications.additionalautoconfigurationandslicing; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; +import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; @JdbcTest diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringdataldap/server/MyDataLdapTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringdataldap/server/MyDataLdapTests.java index 0dc47aaa3098..db2fa363a285 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringdataldap/server/MyDataLdapTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringdataldap/server/MyDataLdapTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.testing.springbootapplications.autoconfiguredspringdataldap.server; -import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration; +import org.springframework.boot.ldap.autoconfigure.embedded.EmbeddedLdapAutoConfiguration; import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest; @DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java index 7b3c93dd0bc0..2822d1ff4831 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java @@ -23,7 +23,7 @@ import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.is; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.java index 9e89a153f0a5..79718c1d3515 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.java @@ -17,7 +17,7 @@ package org.springframework.boot.docs.testing.springbootapplications.autoconfiguredspringrestdocs.withwebtestclient; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer; +import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; import org.springframework.context.annotation.Bean; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/withrunningserver/MyRandomPortTestRestTemplateTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/withrunningserver/MyRandomPortTestRestTemplateTests.java index 4798052fdc48..c8787d8b0aa8 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/withrunningserver/MyRandomPortTestRestTemplateTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/withrunningserver/MyRandomPortTestRestTemplateTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTests.java index 9d7304022e85..7dfa0bc3ef78 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTests.java @@ -21,11 +21,11 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTestsConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTestsConfiguration.java index 07867259fc10..10f4ad060ac0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTestsConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTestsConfiguration.java @@ -20,16 +20,16 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootConfiguration(proxyBeanMethods = false) -@ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, +@ImportAutoConfiguration({ TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) public class MySpringBootTestsConfiguration { diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MyTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MyTests.java index e4106823ac29..a8767d9c7682 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MyTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/utilities/testresttemplate/MyTests.java @@ -18,7 +18,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.ResponseEntity; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/using/autoconfiguration/disablingspecific/MyApplication.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/using/autoconfiguration/disablingspecific/MyApplication.java index 726c4c7e44df..79714e1ab6e0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/using/autoconfiguration/disablingspecific/MyApplication.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/using/autoconfiguration/disablingspecific/MyApplication.java @@ -17,7 +17,7 @@ package org.springframework.boot.docs.using.autoconfiguration.disablingspecific; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) public class MyApplication { diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyNettyWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyNettyWebServerFactoryCustomizer.java index f31e9687cb27..ee1c66cb2969 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyNettyWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyNettyWebServerFactoryCustomizer.java @@ -18,7 +18,7 @@ import java.time.Duration; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyWebServerFactoryCustomizer.java index f413a13c05f2..89364155a824 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyWebServerFactoryCustomizer.java @@ -16,8 +16,8 @@ package org.springframework.boot.docs.web.reactive.reactiveserver.customizing.programmatic; -import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; import org.springframework.stereotype.Component; @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyErrorWebExceptionHandler.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyErrorWebExceptionHandler.java index 67ebd284edb4..3d3f5e0b7b17 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyErrorWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyErrorWebExceptionHandler.java @@ -19,8 +19,8 @@ import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.web.WebProperties; -import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; -import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.boot.webflux.autoconfigure.error.AbstractErrorWebExceptionHandler; +import org.springframework.boot.webflux.error.ErrorAttributes; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/httpcodecs/MyCodecsConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/httpcodecs/MyCodecsConfiguration.java index df6eb1ee4b2b..1f62500cc4d2 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/httpcodecs/MyCodecsConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/reactive/webflux/httpcodecs/MyCodecsConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.web.reactive.webflux.httpcodecs; -import org.springframework.boot.web.codec.CodecCustomizer; +import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.codec.ServerSentEventHttpMessageReader; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/security/springwebflux/MyWebFluxSecurityConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/security/springwebflux/MyWebFluxSecurityConfiguration.java index b0b3dbb83cd5..98337dac5514 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/security/springwebflux/MyWebFluxSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/security/springwebflux/MyWebFluxSecurityConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.web.security.springwebflux; -import org.springframework.boot.autoconfigure.security.reactive.PathRequest; +import org.springframework.boot.security.autoconfigure.reactive.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.web.server.ServerHttpSecurity; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyTomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyTomcatWebServerFactoryCustomizer.java index dbfd16ec4d3e..3e0bcbb4b719 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyTomcatWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyTomcatWebServerFactoryCustomizer.java @@ -18,7 +18,7 @@ import java.time.Duration; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyWebServerFactoryCustomizer.java index 681c1a223192..42d6fd8b7a1b 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyWebServerFactoryCustomizer.java @@ -17,7 +17,7 @@ package org.springframework.boot.docs.web.servlet.embeddedcontainer.customizing.programmatic; import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; import org.springframework.stereotype.Component; @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/samesite/MySameSiteConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/samesite/MySameSiteConfiguration.java index 35b1d7f8682e..51b71c867c02 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/samesite/MySameSiteConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/samesite/MySameSiteConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.web.servlet.embeddedcontainer.customizing.samesite; -import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier; +import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpages/MyErrorViewResolver.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpages/MyErrorViewResolver.java index 5effa076d37a..bfeda38e9658 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpages/MyErrorViewResolver.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpages/MyErrorViewResolver.java @@ -20,7 +20,7 @@ import jakarta.servlet.http.HttpServletRequest; -import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver; +import org.springframework.boot.webmvc.autoconfigure.error.ErrorViewResolver; import org.springframework.http.HttpStatus; import org.springframework.web.servlet.ModelAndView; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpageswithoutspringmvc/MyErrorPagesConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpageswithoutspringmvc/MyErrorPagesConfiguration.java index 5bf4a03f9849..0022ed7674e3 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpageswithoutspringmvc/MyErrorPagesConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpageswithoutspringmvc/MyErrorPagesConfiguration.java @@ -16,9 +16,9 @@ package org.springframework.boot.docs.web.servlet.springmvc.errorhandling.errorpageswithoutspringmvc; -import org.springframework.boot.web.server.ErrorPage; -import org.springframework.boot.web.server.ErrorPageRegistrar; -import org.springframework.boot.web.server.ErrorPageRegistry; +import org.springframework.boot.web.error.ErrorPage; +import org.springframework.boot.web.error.ErrorPageRegistrar; +import org.springframework.boot.web.error.ErrorPageRegistry; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.java index 46207390f1ac..531f3313a2ae 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.web.servlet.springmvc.messageconverters; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyCloudFoundryConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyCloudFoundryConfiguration.kt index 7fdcf444fbd6..82346ce9b580 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyCloudFoundryConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyCloudFoundryConfiguration.kt @@ -26,7 +26,7 @@ import jakarta.servlet.ServletResponse import org.apache.catalina.Host import org.apache.catalina.core.StandardContext import org.apache.catalina.startup.Tomcat.FixContextListener -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory import org.springframework.boot.web.servlet.ServletContextInitializer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyReactiveCloudFoundryConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyReactiveCloudFoundryConfiguration.kt index a9fe12bc72cb..4b4871019cd2 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyReactiveCloudFoundryConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/cloudfoundry/customcontextpath/MyReactiveCloudFoundryConfiguration.kt @@ -15,8 +15,8 @@ */ package org.springframework.boot.docs.actuator.cloudfoundry.customcontextpath -import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.boot.webflux.autoconfigure.WebFluxProperties import org.springframework.context.ApplicationContext import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/health/reactivehealthindicators/MyReactiveHealthIndicator.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/health/reactivehealthindicators/MyReactiveHealthIndicator.kt index fb7c9a07eef8..b9c18e2b9804 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/health/reactivehealthindicators/MyReactiveHealthIndicator.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/health/reactivehealthindicators/MyReactiveHealthIndicator.kt @@ -16,8 +16,8 @@ package org.springframework.boot.docs.actuator.endpoints.health.reactivehealthindicators -import org.springframework.boot.actuate.health.Health -import org.springframework.boot.actuate.health.ReactiveHealthIndicator +import org.springframework.boot.health.contributor.Health +import org.springframework.boot.health.contributor.ReactiveHealthIndicator import org.springframework.stereotype.Component import reactor.core.publisher.Mono diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/health/writingcustomhealthindicators/MyHealthIndicator.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/health/writingcustomhealthindicators/MyHealthIndicator.kt index d9453f00b91b..392872498046 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/health/writingcustomhealthindicators/MyHealthIndicator.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/health/writingcustomhealthindicators/MyHealthIndicator.kt @@ -16,8 +16,8 @@ package org.springframework.boot.docs.actuator.endpoints.health.writingcustomhealthindicators -import org.springframework.boot.actuate.health.Health -import org.springframework.boot.actuate.health.HealthIndicator +import org.springframework.boot.health.contributor.Health +import org.springframework.boot.health.contributor.HealthIndicator import org.springframework.stereotype.Component @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt index cf58ee101b2e..00183a6d8a1d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.endpoints.security.exposeall -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.config.annotation.web.builders.HttpSecurity diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.kt index a66fb842afa3..b6800f8daa0f 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/typical/MySecurityConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.endpoints.security.typical -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.config.Customizer.withDefaults diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/gettingstarted/commontags/MyMeterRegistryConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/gettingstarted/commontags/MyMeterRegistryConfiguration.kt index e7124ef43a09..f3771835009a 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/gettingstarted/commontags/MyMeterRegistryConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/gettingstarted/commontags/MyMeterRegistryConfiguration.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.actuator.metrics.gettingstarted.commontags import io.micrometer.core.instrument.MeterRegistry -import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer +import org.springframework.boot.metrics.autoconfigure.MeterRegistryCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/gettingstarted/specifictype/MyMeterRegistryConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/gettingstarted/specifictype/MyMeterRegistryConfiguration.kt index a6907bcdb640..dc86e17bc080 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/gettingstarted/specifictype/MyMeterRegistryConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/gettingstarted/specifictype/MyMeterRegistryConfiguration.kt @@ -19,7 +19,7 @@ package org.springframework.boot.docs.actuator.metrics.gettingstarted.specificty import io.micrometer.core.instrument.Meter import io.micrometer.core.instrument.config.NamingConvention import io.micrometer.graphite.GraphiteMeterRegistry -import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer +import org.springframework.boot.metrics.autoconfigure.MeterRegistryCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/data/sql/r2dbc/MyPostgresR2dbcConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/data/sql/r2dbc/MyPostgresR2dbcConfiguration.kt index d2abf197973b..acf9fd2022c7 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/data/sql/r2dbc/MyPostgresR2dbcConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/data/sql/r2dbc/MyPostgresR2dbcConfiguration.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.data.sql.r2dbc import io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider -import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer +import org.springframework.boot.r2dbc.autoconfigure.ConnectionFactoryOptionsBuilderCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/data/sql/r2dbc/MyR2dbcConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/data/sql/r2dbc/MyR2dbcConfiguration.kt index 34859b252417..5f2851e1746a 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/data/sql/r2dbc/MyR2dbcConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/data/sql/r2dbc/MyR2dbcConfiguration.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.data.sql.r2dbc import io.r2dbc.spi.ConnectionFactoryOptions -import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer +import org.springframework.boot.r2dbc.autoconfigure.ConnectionFactoryOptionsBuilderCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MyHealthMetricsExportConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MyHealthMetricsExportConfiguration.kt index b24eb17d02f1..3c79f539459a 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MyHealthMetricsExportConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MyHealthMetricsExportConfiguration.kt @@ -19,7 +19,7 @@ package org.springframework.boot.docs.howto.actuator.maphealthindicatorstometric import io.micrometer.core.instrument.Gauge import io.micrometer.core.instrument.MeterRegistry import org.springframework.boot.actuate.health.HealthEndpoint -import org.springframework.boot.actuate.health.Status +import org.springframework.boot.health.contributor.Status import org.springframework.context.annotation.Configuration @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configureacomponentthatisusedbyjpa/ElasticsearchEntityManagerFactoryDependsOnPostProcessor.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configureacomponentthatisusedbyjpa/ElasticsearchEntityManagerFactoryDependsOnPostProcessor.kt index b4118e7edcb4..dbb890c188a0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configureacomponentthatisusedbyjpa/ElasticsearchEntityManagerFactoryDependsOnPostProcessor.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configureacomponentthatisusedbyjpa/ElasticsearchEntityManagerFactoryDependsOnPostProcessor.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.howto.dataaccess.configureacomponentthatisusedbyjpa -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryDependsOnPostProcessor import org.springframework.stereotype.Component @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configurecustomdatasource/configurable/MyDataSourceConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configurecustomdatasource/configurable/MyDataSourceConfiguration.kt index 4f08bed3c528..5a859b6d3189 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configurecustomdatasource/configurable/MyDataSourceConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configurecustomdatasource/configurable/MyDataSourceConfiguration.kt @@ -17,8 +17,8 @@ package org.springframework.boot.docs.howto.dataaccess.configurecustomdatasource.configurable import com.zaxxer.hikari.HikariDataSource -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Primary diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configurehibernatesecondlevelcaching/MyHibernateSecondLevelCacheConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configurehibernatesecondlevelcaching/MyHibernateSecondLevelCacheConfiguration.kt index 1dac5f121e49..f108fd3e92ee 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configurehibernatesecondlevelcaching/MyHibernateSecondLevelCacheConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configurehibernatesecondlevelcaching/MyHibernateSecondLevelCacheConfiguration.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.howto.dataaccess.configurehibernatesecondlevelcaching import org.hibernate.cache.jcache.ConfigSettings -import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer +import org.springframework.boot.hibernate.autoconfigure.HibernatePropertiesCustomizer import org.springframework.cache.jcache.JCacheCacheManager import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteAdditionalDataSourceConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteAdditionalDataSourceConfiguration.kt index daf9dd9b95c9..c389cb3d42d7 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteAdditionalDataSourceConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/configuretwodatasources/MyCompleteAdditionalDataSourceConfiguration.kt @@ -19,8 +19,8 @@ package org.springframework.boot.docs.howto.dataaccess.configuretwodatasources import com.zaxxer.hikari.HikariDataSource import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/usemultipleentitymanagers/MyAdditionalEntityManagerFactoryConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/usemultipleentitymanagers/MyAdditionalEntityManagerFactoryConfiguration.kt index 1bbda4121ddb..e39aafd8a933 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/usemultipleentitymanagers/MyAdditionalEntityManagerFactoryConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/dataaccess/usemultipleentitymanagers/MyAdditionalEntityManagerFactoryConfiguration.kt @@ -17,9 +17,9 @@ package org.springframework.boot.docs.howto.dataaccess.usemultipleentitymanagers import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties import org.springframework.boot.context.properties.ConfigurationProperties -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder +import org.springframework.boot.jpa.EntityManagerFactoryBuilder +import org.springframework.boot.jpa.autoconfigure.JpaProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.orm.jpa.JpaVendorAdapter diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/messaging/disabletransactedjmssession/MyJmsConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/messaging/disabletransactedjmssession/MyJmsConfiguration.kt index de6aa8f011f0..4205f4ee862e 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/messaging/disabletransactedjmssession/MyJmsConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/messaging/disabletransactedjmssession/MyJmsConfiguration.kt @@ -18,7 +18,7 @@ package org.springframework.boot.docs.howto.messaging.disabletransactedjmssessio import jakarta.jms.ConnectionFactory import org.springframework.boot.jms.ConnectionFactoryUnwrapper -import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer +import org.springframework.boot.jms.autoconfigure.DefaultJmsListenerContainerFactoryConfigurer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.jms.config.DefaultJmsListenerContainerFactory diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/configure/MyTomcatWebServerCustomizer.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/configure/MyTomcatWebServerCustomizer.kt index 97320940e259..04a571c1db10 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/configure/MyTomcatWebServerCustomizer.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/configure/MyTomcatWebServerCustomizer.kt @@ -16,8 +16,8 @@ package org.springframework.boot.docs.howto.webserver.configure -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory import org.springframework.boot.web.server.WebServerFactoryCustomizer +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory import org.springframework.stereotype.Component @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt index f737592a3abe..672b9a331df6 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt @@ -18,7 +18,7 @@ package org.springframework.boot.docs.howto.webserver.discoverport import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment -import org.springframework.boot.test.web.server.LocalServerPort +import org.springframework.boot.web.server.test.LocalServerPort @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyWebIntegrationTests { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultipleconnectorsintomcat/MyTomcatConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultipleconnectorsintomcat/MyTomcatConfiguration.kt index 2612b735e39e..92e7aa6fc706 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultipleconnectorsintomcat/MyTomcatConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultipleconnectorsintomcat/MyTomcatConfiguration.kt @@ -17,8 +17,8 @@ package org.springframework.boot.docs.howto.webserver.enablemultipleconnectorsintomcat import org.apache.catalina.connector.Connector -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory import org.springframework.boot.web.server.WebServerFactoryCustomizer +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -28,9 +28,7 @@ class MyTomcatConfiguration { @Bean fun connectorCustomizer(): WebServerFactoryCustomizer { return WebServerFactoryCustomizer { tomcat: TomcatServletWebServerFactory -> - tomcat.addAdditionalTomcatConnectors( - createConnector() - ) + tomcat.addAdditionalConnectors(createConnector()) } } diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.kt index bdfd73c7f07d..dbe48766915b 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/enablemultiplelistenersinundertow/MyUndertowConfiguration.kt @@ -17,9 +17,9 @@ package org.springframework.boot.docs.howto.webserver.enablemultiplelistenersinundertow import io.undertow.Undertow -import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory import org.springframework.boot.web.server.WebServerFactoryCustomizer +import org.springframework.boot.undertow.UndertowBuilderCustomizer +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/MyCacheManagerConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/MyCacheManagerConfiguration.kt index 9820c188474b..98c9135e9772 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/MyCacheManagerConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/MyCacheManagerConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.caching.provider -import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer +import org.springframework.boot.cache.autoconfigure.CacheManagerCustomizer import org.springframework.cache.concurrent.ConcurrentMapCacheManager import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/cache2k/MyCache2kDefaultsConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/cache2k/MyCache2kDefaultsConfiguration.kt index c97e5fddd219..0523e26a48c5 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/cache2k/MyCache2kDefaultsConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/cache2k/MyCache2kDefaultsConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.caching.provider.cache2k -import org.springframework.boot.autoconfigure.cache.Cache2kBuilderCustomizer +import org.springframework.boot.cache.autoconfigure.Cache2kBuilderCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import java.util.concurrent.TimeUnit diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/couchbase/MyCouchbaseCacheManagerConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/couchbase/MyCouchbaseCacheManagerConfiguration.kt index eeee0dd7d4b3..c4b021d27cea 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/couchbase/MyCouchbaseCacheManagerConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/couchbase/MyCouchbaseCacheManagerConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.caching.provider.couchbase -import org.springframework.boot.autoconfigure.cache.CouchbaseCacheManagerBuilderCustomizer +import org.springframework.boot.cache.autoconfigure.CouchbaseCacheManagerBuilderCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.data.couchbase.cache.CouchbaseCacheConfiguration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/redis/MyRedisCacheManagerConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/redis/MyRedisCacheManagerConfiguration.kt index 677e9973bf89..811c3b8c8a3a 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/redis/MyRedisCacheManagerConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/caching/provider/redis/MyRedisCacheManagerConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.caching.provider.redis -import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer +import org.springframework.boot.cache.autoconfigure.RedisCacheManagerBuilderCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.data.redis.cache.RedisCacheConfiguration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/restclient/ssl/MyService.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/restclient/ssl/MyService.kt index 9392e91033b7..28350f3c08f6 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/restclient/ssl/MyService.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/restclient/ssl/MyService.kt @@ -16,8 +16,8 @@ package org.springframework.boot.docs.io.restclient.restclient.ssl -import org.springframework.boot.autoconfigure.web.client.RestClientSsl import org.springframework.boot.docs.io.restclient.restclient.ssl.settings.Details +import org.springframework.boot.restclient.autoconfigure.RestClientSsl import org.springframework.stereotype.Service import org.springframework.web.client.RestClient diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/MyService.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/MyService.kt index bbf7ad557b17..3778c5ed5c57 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/MyService.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/MyService.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.restclient.resttemplate -import org.springframework.boot.web.client.RestTemplateBuilder +import org.springframework.boot.restclient.RestTemplateBuilder import org.springframework.stereotype.Service import org.springframework.web.client.RestTemplate diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateBuilderConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateBuilderConfiguration.kt index 7b2bb7f8051a..57bfd52ebd68 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateBuilderConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateBuilderConfiguration.kt @@ -16,8 +16,8 @@ package org.springframework.boot.docs.io.restclient.resttemplate.customization -import org.springframework.boot.autoconfigure.web.client.RestTemplateBuilderConfigurer -import org.springframework.boot.web.client.RestTemplateBuilder +import org.springframework.boot.restclient.autoconfigure.RestTemplateBuilderConfigurer +import org.springframework.boot.restclient.RestTemplateBuilder import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import java.time.Duration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateCustomizer.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateCustomizer.kt index 0a9a52cfec47..4bdc28fae721 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateCustomizer.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/customization/MyRestTemplateCustomizer.kt @@ -23,7 +23,7 @@ import org.apache.hc.client5.http.routing.HttpRoutePlanner import org.apache.hc.core5.http.HttpException import org.apache.hc.core5.http.HttpHost import org.apache.hc.core5.http.protocol.HttpContext -import org.springframework.boot.web.client.RestTemplateCustomizer +import org.springframework.boot.restclient.RestTemplateCustomizer import org.springframework.http.client.HttpComponentsClientHttpRequestFactory import org.springframework.web.client.RestTemplate diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/ssl/MyService.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/ssl/MyService.kt index efc63f614bf3..cbf24622815e 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/ssl/MyService.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/resttemplate/ssl/MyService.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.io.restclient.resttemplate.ssl import org.springframework.boot.docs.io.restclient.resttemplate.Details import org.springframework.boot.ssl.SslBundles -import org.springframework.boot.web.client.RestTemplateBuilder +import org.springframework.boot.restclient.RestTemplateBuilder import org.springframework.stereotype.Service import org.springframework.web.client.RestTemplate diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/webclient/ssl/MyService.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/webclient/ssl/MyService.kt index 74149c637d1c..ecfb0fa3dcae 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/webclient/ssl/MyService.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/webclient/ssl/MyService.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.io.restclient.webclient.ssl -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientSsl +import org.springframework.boot.webclient.autoconfigure.WebClientSsl import org.springframework.stereotype.Service import org.springframework.web.reactive.function.client.WebClient import reactor.core.publisher.Mono diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/messaging/amqp/receiving/custom/MyRabbitConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/messaging/amqp/receiving/custom/MyRabbitConfiguration.kt index a4ebcdde07fc..902b7c4f2687 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/messaging/amqp/receiving/custom/MyRabbitConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/messaging/amqp/receiving/custom/MyRabbitConfiguration.kt @@ -18,7 +18,7 @@ package org.springframework.boot.docs.messaging.amqp.receiving.custom import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory import org.springframework.amqp.rabbit.connection.ConnectionFactory -import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer +import org.springframework.boot.amqp.autoconfigure.SimpleRabbitListenerContainerFactoryConfigurer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/messaging/jms/receiving/custom/MyJmsConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/messaging/jms/receiving/custom/MyJmsConfiguration.kt index 1f0f60faecde..6df2e32454d5 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/messaging/jms/receiving/custom/MyJmsConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/messaging/jms/receiving/custom/MyJmsConfiguration.kt @@ -17,8 +17,8 @@ package org.springframework.boot.docs.messaging.jms.receiving.custom import jakarta.jms.ConnectionFactory -import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer import org.springframework.boot.jms.ConnectionFactoryUnwrapper +import org.springframework.boot.jms.autoconfigure.DefaultJmsListenerContainerFactoryConfigurer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.jms.config.DefaultJmsListenerContainerFactory diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/additionalautoconfigurationandslicing/MyJdbcTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/additionalautoconfigurationandslicing/MyJdbcTests.kt index 9047dbe7caec..3f7cf0ce0e19 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/additionalautoconfigurationandslicing/MyJdbcTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/additionalautoconfigurationandslicing/MyJdbcTests.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.testing.springbootapplications.additionalautoconfigurationandslicing import org.springframework.boot.autoconfigure.ImportAutoConfiguration -import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration +import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest @JdbcTest diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringdataldap/server/MyDataLdapTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringdataldap/server/MyDataLdapTests.kt index 1e1e34d4eaee..7a4228809520 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringdataldap/server/MyDataLdapTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringdataldap/server/MyDataLdapTests.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.testing.springbootapplications.autoconfiguredspringdataldap.server -import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration +import org.springframework.boot.ldap.autoconfigure.embedded.EmbeddedLdapAutoConfiguration import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest @DataLdapTest(excludeAutoConfiguration = [EmbeddedLdapAutoConfiguration::class]) diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt index 53579222856e..3879a9aa1a90 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment -import org.springframework.boot.test.web.server.LocalServerPort +import org.springframework.boot.web.server.test.LocalServerPort import org.springframework.restdocs.restassured.RestAssuredRestDocumentation @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.kt index 431a54b61325..b7f99bd95242 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.testing.springbootapplications.autoconfiguredspringrestdocs.withwebtestclient import org.springframework.boot.test.context.TestConfiguration -import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer +import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer import org.springframework.context.annotation.Bean import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation import org.springframework.test.web.reactive.server.WebTestClient diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/withrunningserver/MyRandomPortTestRestTemplateTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/withrunningserver/MyRandomPortTestRestTemplateTests.kt index beaac78319a8..bc85b291d453 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/withrunningserver/MyRandomPortTestRestTemplateTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/withrunningserver/MyRandomPortTestRestTemplateTests.kt @@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment -import org.springframework.boot.test.web.client.TestRestTemplate +import org.springframework.boot.web.server.test.client.TestRestTemplate @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyRandomPortTestRestTemplateTests { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTests.kt index 77b120c143e2..e2635bdb2da1 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTests.kt @@ -22,8 +22,8 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment import org.springframework.boot.test.context.TestConfiguration -import org.springframework.boot.test.web.client.TestRestTemplate -import org.springframework.boot.web.client.RestTemplateBuilder +import org.springframework.boot.web.server.test.client.TestRestTemplate +import org.springframework.boot.restclient.RestTemplateBuilder import org.springframework.context.annotation.Bean import java.time.Duration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTestsConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTestsConfiguration.kt index e1d8d3419e3d..1878d5fbc285 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTestsConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MySpringBootTestsConfiguration.kt @@ -18,10 +18,10 @@ package org.springframework.boot.docs.testing.utilities.testresttemplate import org.springframework.boot.SpringBootConfiguration import org.springframework.boot.autoconfigure.ImportAutoConfiguration -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @@ -29,7 +29,7 @@ import java.net.URI @SpringBootConfiguration(proxyBeanMethods = false) @ImportAutoConfiguration( - ServletWebServerFactoryAutoConfiguration::class, + TomcatServletWebServerAutoConfiguration::class, DispatcherServletAutoConfiguration::class, JacksonAutoConfiguration::class, HttpMessageConvertersAutoConfiguration::class diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MyTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MyTests.kt index f3ce2e1e0ee9..671f2559c9b2 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MyTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/utilities/testresttemplate/MyTests.kt @@ -18,7 +18,7 @@ package org.springframework.boot.docs.testing.utilities.testresttemplate import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -import org.springframework.boot.test.web.client.TestRestTemplate +import org.springframework.boot.web.server.test.client.TestRestTemplate class MyTests { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/using/autoconfiguration/disablingspecific/MyApplication.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/using/autoconfiguration/disablingspecific/MyApplication.kt index 82d8a6c3a353..8585f8cd4ef7 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/using/autoconfiguration/disablingspecific/MyApplication.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/using/autoconfiguration/disablingspecific/MyApplication.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.using.autoconfiguration.disablingspecific import org.springframework.boot.autoconfigure.SpringBootApplication -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration @SpringBootApplication(exclude = [DataSourceAutoConfiguration::class]) class MyApplication diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyNettyWebServerFactoryCustomizer.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyNettyWebServerFactoryCustomizer.kt index 957a55cca860..63e18d6aff4b 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyNettyWebServerFactoryCustomizer.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyNettyWebServerFactoryCustomizer.kt @@ -16,8 +16,8 @@ package org.springframework.boot.docs.web.reactive.reactiveserver.customizing.programmatic -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory import org.springframework.boot.web.server.WebServerFactoryCustomizer +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory import org.springframework.stereotype.Component import java.time.Duration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyWebServerFactoryCustomizer.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyWebServerFactoryCustomizer.kt index b0c9b74b80eb..5132ee3eef40 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyWebServerFactoryCustomizer.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/reactiveserver/customizing/programmatic/MyWebServerFactoryCustomizer.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.web.reactive.reactiveserver.customizing.programmatic import org.springframework.boot.web.server.WebServerFactoryCustomizer -import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory import org.springframework.stereotype.Component @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyErrorWebExceptionHandler.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyErrorWebExceptionHandler.kt index 67570ea15213..f356d07d96f6 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyErrorWebExceptionHandler.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/errorhandling/MyErrorWebExceptionHandler.kt @@ -17,8 +17,8 @@ package org.springframework.boot.docs.web.reactive.webflux.errorhandling import org.springframework.boot.autoconfigure.web.WebProperties -import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler -import org.springframework.boot.web.reactive.error.ErrorAttributes +import org.springframework.boot.webflux.error.ErrorAttributes +import org.springframework.boot.webflux.autoconfigure.error.AbstractErrorWebExceptionHandler import org.springframework.context.ApplicationContext import org.springframework.http.HttpStatus import org.springframework.http.MediaType diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/httpcodecs/MyCodecsConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/httpcodecs/MyCodecsConfiguration.kt index b30142e8052f..857bd7d7e494 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/httpcodecs/MyCodecsConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/reactive/webflux/httpcodecs/MyCodecsConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.web.reactive.webflux.httpcodecs -import org.springframework.boot.web.codec.CodecCustomizer +import org.springframework.boot.http.codec.CodecCustomizer import org.springframework.context.annotation.Bean import org.springframework.http.codec.CodecConfigurer import org.springframework.http.codec.ServerSentEventHttpMessageReader diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/security/springwebflux/MyWebFluxSecurityConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/security/springwebflux/MyWebFluxSecurityConfiguration.kt index 3830c056b1d4..eb97ed61949c 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/security/springwebflux/MyWebFluxSecurityConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/security/springwebflux/MyWebFluxSecurityConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.web.security.springwebflux -import org.springframework.boot.autoconfigure.security.reactive.PathRequest +import org.springframework.boot.security.autoconfigure.reactive.PathRequest import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.config.Customizer.withDefaults diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyTomcatWebServerFactoryCustomizer.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyTomcatWebServerFactoryCustomizer.kt index 595384b31868..755653949d33 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyTomcatWebServerFactoryCustomizer.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyTomcatWebServerFactoryCustomizer.kt @@ -16,8 +16,8 @@ package org.springframework.boot.docs.web.servlet.embeddedcontainer.customizing.programmatic -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory import org.springframework.boot.web.server.WebServerFactoryCustomizer +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory import org.springframework.stereotype.Component import java.time.Duration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyWebServerFactoryCustomizer.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyWebServerFactoryCustomizer.kt index 26684eefa0ba..730b28123aa3 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyWebServerFactoryCustomizer.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/programmatic/MyWebServerFactoryCustomizer.kt @@ -16,8 +16,8 @@ package org.springframework.boot.docs.web.servlet.embeddedcontainer.customizing.programmatic +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory import org.springframework.boot.web.server.WebServerFactoryCustomizer -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory import org.springframework.stereotype.Component @Component diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/samesite/MySameSiteConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/samesite/MySameSiteConfiguration.kt index 15c313a65585..62fe614e2fd7 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/samesite/MySameSiteConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/embeddedcontainer/customizing/samesite/MySameSiteConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.web.servlet.embeddedcontainer.customizing.samesite -import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier +import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpages/MyErrorViewResolver.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpages/MyErrorViewResolver.kt index 3e5d146dab85..3e40a75b97ad 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpages/MyErrorViewResolver.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpages/MyErrorViewResolver.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.web.servlet.springmvc.errorhandling.errorpages import jakarta.servlet.http.HttpServletRequest -import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver +import org.springframework.boot.webmvc.autoconfigure.error.ErrorViewResolver import org.springframework.http.HttpStatus import org.springframework.web.servlet.ModelAndView diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpageswithoutspringmvc/MyErrorPagesConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpageswithoutspringmvc/MyErrorPagesConfiguration.kt index d6ed45136321..4b5e0fcd76cf 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpageswithoutspringmvc/MyErrorPagesConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/errorpageswithoutspringmvc/MyErrorPagesConfiguration.kt @@ -16,9 +16,9 @@ package org.springframework.boot.docs.web.servlet.springmvc.errorhandling.errorpageswithoutspringmvc -import org.springframework.boot.web.server.ErrorPage -import org.springframework.boot.web.server.ErrorPageRegistrar -import org.springframework.boot.web.server.ErrorPageRegistry +import org.springframework.boot.web.error.ErrorPage +import org.springframework.boot.web.error.ErrorPageRegistrar +import org.springframework.boot.web.error.ErrorPageRegistry import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.http.HttpStatus diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.kt index 261cb590f009..c89e441fb7fd 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.web.servlet.springmvc.messageconverters -import org.springframework.boot.autoconfigure.http.HttpMessageConverters +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.http.converter.HttpMessageConverter diff --git a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MetricsHealthMicrometerExportTests.java b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MetricsHealthMicrometerExportTests.java index 38adf72a9fc6..2566c5dc5a8c 100644 --- a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MetricsHealthMicrometerExportTests.java +++ b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/actuator/maphealthindicatorstometrics/MetricsHealthMicrometerExportTests.java @@ -22,12 +22,13 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -54,7 +55,8 @@ void registryExportsHealth() { @Configuration(proxyBeanMethods = false) @Import(MyHealthMetricsExportConfiguration.class) - @ImportAutoConfiguration(classes = { HealthContributorAutoConfiguration.class, MetricsAutoConfiguration.class, + @ImportAutoConfiguration({ HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, MetricsAutoConfiguration.class, HealthEndpointAutoConfiguration.class }) static class Config { @@ -70,7 +72,7 @@ SimpleMeterRegistry simpleMeterRegistry() { @Bean HealthIndicator outOfService() { - return () -> new Health.Builder().outOfService().build(); + return () -> Health.outOfService().build(); } } diff --git a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/dataaccess/SampleApp.java b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/dataaccess/SampleApp.java index 1f50f032cc0a..e0b6a80d3452 100644 --- a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/dataaccess/SampleApp.java +++ b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/howto/dataaccess/SampleApp.java @@ -20,7 +20,7 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; /** * A sample {@link SpringBootConfiguration @ConfigurationProperties} that only enables the diff --git a/spring-boot-project/spring-boot-elasticsearch/build.gradle b/spring-boot-project/spring-boot-elasticsearch/build.gradle new file mode 100644 index 000000000000..e1b93fd56ca6 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/build.gradle @@ -0,0 +1,66 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Elasticsearch" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.elasticsearch.client:elasticsearch-rest-client") + + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-jsonb")) + optional(project(":spring-boot-project:spring-boot-reactor")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("co.elastic.clients:elasticsearch-java") { + exclude group: "commons-logging", module: "commons-logging" + } + optional("org.elasticsearch.client:elasticsearch-rest-client-sniffer") { + exclude group: "commons-logging", module: "commons-logging" + } + optional("com.fasterxml.jackson.core:jackson-databind") + optional("jakarta.json.bind:jakarta.json.bind-api") + optional("org.springframework.data:spring-data-elasticsearch") { + exclude group: "org.elasticsearch.client", module: "transport" + } + optional("org.testcontainers:elasticsearch") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-jackson")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:elasticsearch") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-jsonb")) + testImplementation("org.springframework:spring-web") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfigurationIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfigurationIntegrationTests.java index ddb8f9e8a80e..283f3768aab7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import java.util.Map; @@ -26,7 +26,7 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfigurationIntegrationTests.java new file mode 100644 index 000000000000..bc9c6364b989 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfigurationIntegrationTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.elasticsearch.autoconfigure; + +import java.util.Map; + +import co.elastic.clients.elasticsearch.core.GetResponse; +import co.elastic.clients.elasticsearch.core.IndexResponse; +import org.junit.jupiter.api.Test; +import org.testcontainers.elasticsearch.ElasticsearchContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link ElasticsearchReactiveClientAutoConfiguration}. + * + * @author Brian Clozel + * @author Andy Wilkinson + */ +@Testcontainers(disabledWithoutDocker = true) +class ElasticsearchReactiveClientAutoConfigurationIntegrationTests { + + @Container + static final ElasticsearchContainer elasticsearch = TestImage.container(ElasticsearchContainer.class); + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, + ElasticsearchRestClientAutoConfiguration.class, ElasticsearchReactiveClientAutoConfiguration.class)); + + @Test + void reactiveClientCanQueryElasticsearchNode() { + this.contextRunner + .withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(), + "spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s") + .run((context) -> { + ReactiveElasticsearchClient client = context.getBean(ReactiveElasticsearchClient.class); + Mono index = client + .index((b) -> b.index("foo").id("1").document(Map.of("a", "alpha", "b", "bravo"))); + index.block(); + Mono> get = client.get((b) -> b.index("foo").id("1"), Object.class); + GetResponse response = get.block(); + assertThat(response).isNotNull(); + assertThat(response.found()).isTrue(); + }); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfigurationIntegrationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfigurationIntegrationTests.java index 8c9039473639..8ab90c041894 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import java.io.InputStream; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 89% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java index 70f90f003c4d..218bd0911d6a 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.elasticsearch; +package org.springframework.boot.elasticsearch.docker.compose; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails.Node; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails.Node.Protocol; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/ElasticsearchContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/testcontainers/ElasticsearchContainerConnectionDetailsFactoryTests.java similarity index 90% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/ElasticsearchContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/testcontainers/ElasticsearchContainerConnectionDetailsFactoryTests.java index 94612bc19fb7..4076b83c7a5a 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/ElasticsearchContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/testcontainers/ElasticsearchContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.elasticsearch; +package org.springframework.boot.elasticsearch.testcontainers; import java.io.IOException; import java.time.Duration; @@ -27,9 +27,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.ElasticsearchContainer9; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/elasticsearch/elasticsearch-bitnami-compose.yaml b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/org/springframework/boot/elasticsearch/docker/compose/elasticsearch-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/elasticsearch/elasticsearch-bitnami-compose.yaml rename to spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/org/springframework/boot/elasticsearch/docker/compose/elasticsearch-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/elasticsearch/elasticsearch-compose.yaml b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/org/springframework/boot/elasticsearch/docker/compose/elasticsearch-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/elasticsearch/elasticsearch-compose.yaml rename to spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/org/springframework/boot/elasticsearch/docker/compose/elasticsearch-compose.yaml diff --git a/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfiguration.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfiguration.java similarity index 78% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfiguration.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfiguration.java index 6d7fb6caf159..ef5762f9d158 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import co.elastic.clients.elasticsearch.ElasticsearchClient; import org.elasticsearch.client.RestClient; @@ -23,19 +23,19 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientConfigurations.ElasticsearchClientConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientConfigurations.ElasticsearchTransportConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientConfigurations.JsonpMapperConfiguration; -import org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientConfigurations.ElasticsearchClientConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientConfigurations.ElasticsearchTransportConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientConfigurations.JsonpMapperConfiguration; import org.springframework.context.annotation.Import; /** * {@link EnableAutoConfiguration Auto-configuration} for Elasticsearch's Java client. * * @author Andy Wilkinson - * @since 3.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { JsonbAutoConfiguration.class, ElasticsearchRestClientAutoConfiguration.class }) +@AutoConfiguration(after = { ElasticsearchRestClientAutoConfiguration.class }, + afterName = { "org.springframework.boot.jsonb.autoconfigure.JsonbAutoConfiguration" }) @ConditionalOnBean(RestClient.class) @ConditionalOnClass(ElasticsearchClient.class) @Import({ JsonpMapperConfiguration.class, ElasticsearchTransportConfiguration.class, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientConfigurations.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientConfigurations.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientConfigurations.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientConfigurations.java index e43e42fd81af..e17a5aeb2406 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientConfigurations.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.json.JsonpMapper; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchConnectionDetails.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchConnectionDetails.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchConnectionDetails.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchConnectionDetails.java index 9a7fee11366c..d679026393f0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchConnectionDetails.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import java.net.URI; import java.net.URISyntaxException; @@ -29,7 +29,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface ElasticsearchConnectionDetails extends ConnectionDetails { @@ -67,7 +67,6 @@ default String getPathPrefix() { /** * SSL bundle to use. * @return the SSL bundle to use - * @since 3.5.0 */ default SslBundle getSslBundle() { return null; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchProperties.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchProperties.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchProperties.java index 3d5d251c474f..286516d4b4b8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchProperties.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -27,7 +27,7 @@ * Configuration properties for Elasticsearch. * * @author Andy Wilkinson - * @since 2.4.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.elasticsearch") public class ElasticsearchProperties { diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfiguration.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfiguration.java new file mode 100644 index 000000000000..07799e4b2859 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfiguration.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.elasticsearch.autoconfigure; + +import co.elastic.clients.transport.ElasticsearchTransport; +import org.elasticsearch.client.RestClient; +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Data Elasticsearch's + * reactive client. + * + * @author Brian Clozel + * @since 4.0.0 + */ +@AutoConfiguration(after = ElasticsearchClientAutoConfiguration.class) +@ConditionalOnBean(RestClient.class) +@ConditionalOnClass({ ReactiveElasticsearchClient.class, ElasticsearchTransport.class, Mono.class }) +@EnableConfigurationProperties(ElasticsearchProperties.class) +@Import({ ElasticsearchClientConfigurations.JsonpMapperConfiguration.class, + ElasticsearchClientConfigurations.ElasticsearchTransportConfiguration.class }) +public class ElasticsearchReactiveClientAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(ElasticsearchTransport.class) + ReactiveElasticsearchClient reactiveElasticsearchClient(ElasticsearchTransport transport) { + return new ReactiveElasticsearchClient(transport); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfiguration.java similarity index 86% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfiguration.java index 3aa58e35c248..4ae7397cfbe9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfiguration.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import org.elasticsearch.client.RestClientBuilder; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientSnifferConfiguration; import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientConfigurations.RestClientConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientConfigurations.RestClientSnifferConfiguration; import org.springframework.context.annotation.Import; /** @@ -33,7 +33,7 @@ * * @author Brian Clozel * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = SslAutoConfiguration.class) @ConditionalOnClass(RestClientBuilder.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientConfigurations.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientConfigurations.java index cf7c27f48ba2..48449f057a6c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import java.net.URI; import java.time.Duration; @@ -42,10 +42,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchProperties.Restclient.Ssl; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails.Node; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails.Node.Protocol; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchProperties.Restclient.Ssl; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; import org.springframework.boot.ssl.SslOptions; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/RestClientBuilderCustomizer.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/RestClientBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/RestClientBuilderCustomizer.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/RestClientBuilderCustomizer.java index 2721af7a2f6f..4e36999f013c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/RestClientBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/RestClientBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig.Builder; @@ -28,7 +28,7 @@ * * @author Brian Clozel * @author Vedran Pavic - * @since 2.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface RestClientBuilderCustomizer { @@ -47,7 +47,6 @@ public interface RestClientBuilderCustomizer { /** * Customize the {@link HttpAsyncClientBuilder}. * @param builder the builder - * @since 2.3.0 */ default void customize(HttpAsyncClientBuilder builder) { } @@ -55,7 +54,6 @@ default void customize(HttpAsyncClientBuilder builder) { /** * Customize the {@link Builder}. * @param builder the builder - * @since 2.3.0 */ default void customize(Builder builder) { } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchRestHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/health/ElasticsearchRestHealthContributorAutoConfiguration.java similarity index 77% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchRestHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/health/ElasticsearchRestHealthContributorAutoConfiguration.java index d541ff9a0490..a98134c8d1d0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchRestHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/health/ElasticsearchRestHealthContributorAutoConfiguration.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure.health; import org.elasticsearch.client.RestClient; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.elasticsearch.health.ElasticsearchRestClientHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; import org.springframework.context.annotation.Bean; /** @@ -36,10 +36,10 @@ * {@link ElasticsearchRestClientHealthIndicator}. * * @author Artsiom Yudovin - * @since 2.1.1 + * @since 4.0.0 */ @AutoConfiguration(after = ElasticsearchRestClientAutoConfiguration.class) -@ConditionalOnClass(RestClient.class) +@ConditionalOnClass({ RestClient.class, ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(RestClient.class) @ConditionalOnEnabledHealthIndicator("elasticsearch") public class ElasticsearchRestHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..2a3fc72583b0 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Elasticsearch health. + */ +package org.springframework.boot.elasticsearch.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/package-info.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/package-info.java new file mode 100644 index 000000000000..3ba06a003fd7 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Elasticsearch client. + */ +package org.springframework.boot.elasticsearch.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactory.java similarity index 92% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactory.java index a01049ce5546..23ed708567ed 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactory.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.elasticsearch; +package org.springframework.boot.elasticsearch.docker.compose; import java.util.List; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails.Node.Protocol; /** * {@link DockerComposeConnectionDetailsFactory} to create diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchEnvironment.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchEnvironment.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchEnvironment.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchEnvironment.java index 63ef9f8381f6..867c0ac946f2 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchEnvironment.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.elasticsearch; +package org.springframework.boot.elasticsearch.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/package-info.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/package-info.java new file mode 100644 index 000000000000..544c4ef8efeb --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Elasticsearch service connections. + */ +package org.springframework.boot.elasticsearch.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/health/ElasticsearchRestClientHealthIndicator.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/health/ElasticsearchRestClientHealthIndicator.java index 5c0a080f4806..534eb58bcd25 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/health/ElasticsearchRestClientHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.elasticsearch; +package org.springframework.boot.elasticsearch.health; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -26,9 +26,10 @@ import org.elasticsearch.client.Response; import org.elasticsearch.client.RestClient; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.json.JsonParser; import org.springframework.boot.json.JsonParserFactory; import org.springframework.util.StreamUtils; @@ -39,7 +40,7 @@ * @author Artsiom Yudovin * @author Brian Clozel * @author Filip Hrisafov - * @since 2.7.0 + * @since 4.0.0 */ public class ElasticsearchRestClientHealthIndicator extends AbstractHealthIndicator { @@ -73,12 +74,7 @@ protected void doHealthCheck(Health.Builder builder) throws Exception { private void doHealthCheck(Health.Builder builder, String json) { Map response = this.jsonParser.parseMap(json); String status = (String) response.get("status"); - if (RED_STATUS.equals(status)) { - builder.outOfService(); - } - else { - builder.up(); - } + builder.status((RED_STATUS.equals(status)) ? Status.OUT_OF_SERVICE : Status.UP); builder.withDetails(response); } diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/health/package-info.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/health/package-info.java new file mode 100644 index 000000000000..0f8ff9cda372 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for Elasticsearch. + */ +package org.springframework.boot.elasticsearch.health; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/ElasticsearchContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/testcontainers/ElasticsearchContainerConnectionDetailsFactory.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/ElasticsearchContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/testcontainers/ElasticsearchContainerConnectionDetailsFactory.java index 3106ec5a1416..6bccfc33a934 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/ElasticsearchContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/testcontainers/ElasticsearchContainerConnectionDetailsFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.elasticsearch; +package org.springframework.boot.elasticsearch.testcontainers; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -28,8 +28,8 @@ import org.testcontainers.elasticsearch.ElasticsearchContainer; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails.Node.Protocol; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslStoreBundle; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/testcontainers/package-info.java b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/testcontainers/package-info.java new file mode 100644 index 000000000000..3da8345dccf0 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Elasticsearch service connections. + */ +package org.springframework.boot.elasticsearch.testcontainers; diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..eb026829f278 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,106 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.health.elasticsearch.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Elasticsearch health check.", + "defaultValue": true + }, + { + "name": "management.health.elasticsearch.indices", + "type": "java.util.List", + "description": "Comma-separated index names.", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.health.elasticsearch.response-timeout", + "type": "java.time.Duration", + "description": "Time to wait for a response from the cluster.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.jest.connection-timeout", + "type": "java.time.Duration", + "description": "Connection timeout.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.jest.multi-threaded", + "type": "java.lang.Boolean", + "description": "Whether to enable connection requests from multiple execution threads.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.jest.password", + "type": "java.lang.String", + "description": "Login password.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.jest.proxy.host", + "type": "java.lang.String", + "description": "Proxy host the HTTP client should use.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.jest.proxy.port", + "type": "java.lang.Integer", + "description": "Proxy port the HTTP client should use.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.jest.read-timeout", + "type": "java.time.Duration", + "description": "Read timeout.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.jest.uris", + "type": "java.util.List", + "description": "Comma-separated list of the Elasticsearch instances to use.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.jest.username", + "type": "java.lang.String", + "description": "Login username.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.elasticsearch.uris", + "defaultValue": [ + "http://localhost:9200" + ] + }, + { + "name": "spring.elasticsearch.webclient.max-in-memory-size", + "type": "org.springframework.util.unit.DataSize", + "description": "Limit on the number of bytes that can be buffered whenever the input stream needs to be aggregated.", + "deprecation": { + "level": "error", + "reason": "Reactive Elasticsearch client no longer uses WebClient." + } + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..af64f695ef98 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.elasticsearch.docker.compose.ElasticsearchDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.elasticsearch.testcontainers.ElasticsearchContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..aa13ff285a20 --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration +org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchReactiveClientAutoConfiguration +org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration +org.springframework.boot.elasticsearch.autoconfigure.health.ElasticsearchRestHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfigurationTests.java index 4ddd81a0c916..03e57ef47efd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchClientAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.json.JsonpMapper; @@ -28,8 +28,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jsonb.autoconfigure.JsonbAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfigurationTests.java new file mode 100644 index 000000000000..5eacedf22a3f --- /dev/null +++ b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchReactiveClientAutoConfigurationTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.elasticsearch.autoconfigure; + +import org.elasticsearch.client.RestClient; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link ElasticsearchReactiveClientAutoConfiguration}. + * + * @author Brian Clozel + * @author Andy Wilkinson + */ +class ElasticsearchReactiveClientAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ElasticsearchReactiveClientAutoConfiguration.class)); + + @Test + void configureWithoutRestClientShouldBackOff() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ReactiveElasticsearchClient.class)); + } + + @Test + void configureWithRestClientShouldCreateTransportAndClient() { + this.contextRunner.withUserConfiguration(RestClientConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchClient.class)); + } + + @Test + void configureWhenCustomClientShouldBackOff() { + this.contextRunner.withUserConfiguration(RestClientConfiguration.class, CustomClientConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchClient.class) + .hasBean("customClient")); + } + + @Configuration(proxyBeanMethods = false) + static class RestClientConfiguration { + + @Bean + RestClient restClient() { + return mock(RestClient.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomClientConfiguration { + + @Bean + ReactiveElasticsearchClient customClient() { + return mock(ReactiveElasticsearchClient.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfigurationTests.java index 8be3c5a9b435..ebdd67afebdd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/ElasticsearchRestClientAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -36,9 +36,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.PropertiesElasticsearchConnectionDetails; import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails.Node.Protocol; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientConfigurations.PropertiesElasticsearchConnectionDetails; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchRestHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/health/ElasticsearchRestHealthContributorAutoConfigurationTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchRestHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/health/ElasticsearchRestHealthContributorAutoConfigurationTests.java index 0f458eaffe65..97439220d506 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchRestHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/autoconfigure/health/ElasticsearchRestHealthContributorAutoConfigurationTests.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.elasticsearch; +package org.springframework.boot.elasticsearch.autoconfigure.health; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.elasticsearch.health.ElasticsearchRestClientHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchEnvironmentTests.java b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchEnvironmentTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchEnvironmentTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchEnvironmentTests.java index 38adfca36b1f..ae051fde293c 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/elasticsearch/ElasticsearchEnvironmentTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.elasticsearch; +package org.springframework.boot.elasticsearch.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/health/ElasticsearchRestClientHealthIndicatorTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java rename to spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/health/ElasticsearchRestClientHealthIndicatorTests.java index 47259a33616d..58df73ffbbe2 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-elasticsearch/src/test/java/org/springframework/boot/elasticsearch/health/ElasticsearchRestClientHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.elasticsearch; +package org.springframework.boot.elasticsearch.health; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -27,8 +27,8 @@ import org.elasticsearch.client.RestClient; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; @@ -59,7 +59,8 @@ void elasticsearchIsUp() throws IOException { given(response.getStatusLine()).willReturn(statusLine); given(response.getEntity()).willReturn(httpEntity); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestClientHealthIndicator.health(); + org.springframework.boot.health.contributor.Health health = this.elasticsearchRestClientHealthIndicator + .health(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "green"); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/elasticsearch/test.jks b/spring-boot-project/spring-boot-elasticsearch/src/test/resources/org/springframework/boot/elasticsearch/autoconfigure/test.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/elasticsearch/test.jks rename to spring-boot-project/spring-boot-elasticsearch/src/test/resources/org/springframework/boot/elasticsearch/autoconfigure/test.jks diff --git a/spring-boot-project/spring-boot-flyway/build.gradle b/spring-boot-project/spring-boot-flyway/build.gradle new file mode 100644 index 000000000000..027f95259294 --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/build.gradle @@ -0,0 +1,63 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Flyway" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-jdbc")) + api("org.flywaydb:flyway-core") + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("org.flywaydb:flyway-database-oracle") + optional("org.flywaydb:flyway-database-postgresql") + optional("org.flywaydb:flyway-sqlserver") + optional("org.testcontainers:jdbc") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:postgresql") + dockerTestRuntimeOnly("org.postgresql:postgresql") + + testImplementation(project(":spring-boot-project:spring-boot-jooq")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("jakarta.persistence:jakarta.persistence-api") + testImplementation("org.hibernate.orm:hibernate-core") + testImplementation("org.hsqldb:hsqldb") + testImplementation("org.postgresql:postgresql") + testImplementation("org.springframework:spring-orm") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") + testRuntimeOnly("org.flywaydb:flyway-database-hsqldb") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/flyway/JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-flyway/src/dockerTest/java/org/springframework/boot/flyway/docker/compose/JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/flyway/JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-flyway/src/dockerTest/java/org/springframework/boot/flyway/docker/compose/JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests.java index e01944e485da..c6b1143d1a6d 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/flyway/JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-flyway/src/dockerTest/java/org/springframework/boot/flyway/docker/compose/JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.flyway; +package org.springframework.boot.flyway.docker.compose; -import org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.flyway.autoconfigure.FlywayConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/flyway/FlywayContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-flyway/src/dockerTest/java/org/springframework/boot/flyway/testcontainers/FlywayContainerConnectionDetailsFactoryTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/flyway/FlywayContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-flyway/src/dockerTest/java/org/springframework/boot/flyway/testcontainers/FlywayContainerConnectionDetailsFactoryTests.java index 99a79b0a00b5..7adf484ce65a 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/flyway/FlywayContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-flyway/src/dockerTest/java/org/springframework/boot/flyway/testcontainers/FlywayContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.flyway; +package org.springframework.boot.flyway.testcontainers; import org.flywaydb.core.Flyway; import org.junit.jupiter.api.Test; @@ -24,8 +24,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-flyway/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-flyway/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/flyway/flyway-compose.yaml b/spring-boot-project/spring-boot-flyway/src/dockerTest/resources/org/springframework/boot/flyway/docker/compose/flyway-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/flyway/flyway-compose.yaml rename to spring-boot-project/spring-boot-flyway/src/dockerTest/resources/org/springframework/boot/flyway/docker/compose/flyway-compose.yaml diff --git a/spring-boot-project/spring-boot-flyway/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-flyway/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/flyway/FlywayDatabaseInitializerDetector.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/FlywayDatabaseInitializerDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/flyway/FlywayDatabaseInitializerDetector.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/FlywayDatabaseInitializerDetector.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfiguration.java index 20a304a26d3a..abca594311d1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.sql.DatabaseMetaData; import java.time.Duration; @@ -50,20 +50,18 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayAutoConfigurationRuntimeHints; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayDataSourceCondition; -import org.springframework.boot.autoconfigure.flyway.FlywayProperties.Oracle; -import org.springframework.boot.autoconfigure.flyway.FlywayProperties.Postgresql; -import org.springframework.boot.autoconfigure.flyway.FlywayProperties.Sqlserver; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration.FlywayAutoConfigurationRuntimeHints; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration.FlywayDataSourceCondition; +import org.springframework.boot.flyway.autoconfigure.FlywayProperties.Oracle; +import org.springframework.boot.flyway.autoconfigure.FlywayProperties.Postgresql; +import org.springframework.boot.flyway.autoconfigure.FlywayProperties.Sqlserver; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -100,10 +98,9 @@ * @author Chris Bono * @author Moritz Halbritter * @author Andy Wilkinson - * @since 1.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, - HibernateJpaAutoConfiguration.class }) +@AutoConfiguration(after = DataSourceAutoConfiguration.class) @ConditionalOnClass(Flyway.class) @Conditional(FlywayDataSourceCondition.class) @ConditionalOnBooleanProperty(name = "spring.flyway.enabled", matchIfMissing = true) @@ -281,8 +278,6 @@ private void configureProperties(FluentConfiguration configuration, FlywayProper map.from(properties.isBaselineOnMigrate()) .to((baselineOnMigrate) -> configuration.baselineOnMigrate(baselineOnMigrate)); map.from(properties.isCleanDisabled()).to((cleanDisabled) -> configuration.cleanDisabled(cleanDisabled)); - map.from(properties.isCleanOnValidationError()) - .to((cleanOnValidationError) -> configuration.cleanOnValidationError(cleanOnValidationError)); map.from(properties.isGroup()).to((group) -> configuration.group(group)); map.from(properties.isMixed()).to((mixed) -> configuration.mixed(mixed)); map.from(properties.isOutOfOrder()).to((outOfOrder) -> configuration.outOfOrder(outOfOrder)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayConfigurationCustomizer.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayConfigurationCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayConfigurationCustomizer.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayConfigurationCustomizer.java index 16af3480ed5d..66bfe9c94e26 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayConfigurationCustomizer.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayConfigurationCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import org.flywaydb.core.api.configuration.FluentConfiguration; @@ -23,7 +23,7 @@ * configuration. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface FlywayConfigurationCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayConnectionDetails.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayConnectionDetails.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayConnectionDetails.java index 121917d5ee64..7fe4e226dd23 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayConnectionDetails.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; import org.springframework.boot.jdbc.DatabaseDriver; @@ -23,7 +23,7 @@ * Details required for Flyway to establish a connection to an SQL service using JDBC. * * @author Andy Wilkinson - * @since 3.1.0 + * @since 4.0.0 */ public interface FlywayConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayDataSource.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayDataSource.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayDataSource.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayDataSource.java index 191a5b6dbf09..4ba46b6d4fef 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayDataSource.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayDataSource.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -29,7 +29,7 @@ * data source, the other (main) one would normally be marked as {@code @Primary}. * * @author Dave Syer - * @since 1.1.0 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationInitializer.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationInitializer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationInitializer.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationInitializer.java index 1b6f9610c568..1e0960719666 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationInitializer.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import org.flywaydb.core.Flyway; @@ -27,7 +27,7 @@ * {@link FlywayMigrationStrategy}. * * @author Phillip Webb - * @since 1.3.0 + * @since 4.0.0 */ public class FlywayMigrationInitializer implements InitializingBean, Ordered { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationInitializerDatabaseInitializerDetector.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationInitializerDatabaseInitializerDetector.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationInitializerDatabaseInitializerDetector.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationInitializerDatabaseInitializerDetector.java index 0ba6c95a3263..48b0d0a094b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationInitializerDatabaseInitializerDetector.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationInitializerDatabaseInitializerDetector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.util.Collections; import java.util.Set; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationStrategy.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationStrategy.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationStrategy.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationStrategy.java index c412b525e68b..894fee5a435c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayMigrationStrategy.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayMigrationStrategy.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import org.flywaydb.core.Flyway; @@ -24,7 +24,7 @@ * * @author Andreas Ahlenstorf * @author Phillip Webb - * @since 1.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface FlywayMigrationStrategy { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java index c4e328888399..e1754f32c636 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywayProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.io.File; import java.nio.charset.Charset; @@ -28,7 +28,6 @@ import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; import org.springframework.boot.convert.DurationUnit; /** @@ -38,7 +37,7 @@ * @author Eddú Meléndez * @author Stephane Nicoll * @author Chris Bono - * @since 1.1.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.flyway") public class FlywayProperties { @@ -211,11 +210,6 @@ public class FlywayProperties { */ private boolean cleanDisabled = true; - /** - * Whether to automatically call clean when a validation error occurs. - */ - private boolean cleanOnValidationError; - /** * Whether to group all pending migrations together in the same transaction when * applying them. @@ -595,17 +589,6 @@ public void setCleanDisabled(boolean cleanDisabled) { this.cleanDisabled = cleanDisabled; } - @Deprecated(since = "3.4.0", forRemoval = true) - @DeprecatedConfigurationProperty(since = "3.4.0", reason = "Deprecated in Flyway 10.18 and removed in Flyway 11.0") - public boolean isCleanOnValidationError() { - return this.cleanOnValidationError; - } - - @Deprecated(since = "3.4.0", forRemoval = true) - public void setCleanOnValidationError(boolean cleanOnValidationError) { - this.cleanOnValidationError = cleanOnValidationError; - } - public boolean isGroup() { return this.group; } @@ -718,39 +701,6 @@ public void setErrorOverrides(String[] errorOverrides) { this.errorOverrides = errorOverrides; } - @DeprecatedConfigurationProperty(replacement = "spring.flyway.oracle.sqlplus", since = "3.2.0") - @Deprecated(since = "3.2.0", forRemoval = true) - public Boolean getOracleSqlplus() { - return getOracle().getSqlplus(); - } - - @Deprecated(since = "3.2.0", forRemoval = true) - public void setOracleSqlplus(Boolean oracleSqlplus) { - getOracle().setSqlplus(oracleSqlplus); - } - - @DeprecatedConfigurationProperty(replacement = "spring.flyway.oracle.sqlplus-warn", since = "3.2.0") - @Deprecated(since = "3.2.0", forRemoval = true) - public Boolean getOracleSqlplusWarn() { - return getOracle().getSqlplusWarn(); - } - - @Deprecated(since = "3.2.0", forRemoval = true) - public void setOracleSqlplusWarn(Boolean oracleSqlplusWarn) { - getOracle().setSqlplusWarn(oracleSqlplusWarn); - } - - @DeprecatedConfigurationProperty(replacement = "spring.flyway.oracle.wallet-location", since = "3.2.0") - @Deprecated(since = "3.2.0", forRemoval = true) - public String getOracleWalletLocation() { - return getOracle().getWalletLocation(); - } - - @Deprecated(since = "3.2.0", forRemoval = true) - public void setOracleWalletLocation(String oracleWalletLocation) { - getOracle().setWalletLocation(oracleWalletLocation); - } - public Boolean getStream() { return this.stream; } @@ -775,17 +725,6 @@ public void setKerberosConfigFile(String kerberosConfigFile) { this.kerberosConfigFile = kerberosConfigFile; } - @DeprecatedConfigurationProperty(replacement = "spring.flyway.oracle.kerberos-cache-file", since = "3.2.0") - @Deprecated(since = "3.2.0", forRemoval = true) - public String getOracleKerberosCacheFile() { - return getOracle().getKerberosCacheFile(); - } - - @Deprecated(since = "3.2.0", forRemoval = true) - public void setOracleKerberosCacheFile(String oracleKerberosCacheFile) { - getOracle().setKerberosCacheFile(oracleKerberosCacheFile); - } - public Boolean getOutputQueryResults() { return this.outputQueryResults; } @@ -794,17 +733,6 @@ public void setOutputQueryResults(Boolean outputQueryResults) { this.outputQueryResults = outputQueryResults; } - @DeprecatedConfigurationProperty(replacement = "spring.flyway.sqlserver.kerberos-login-file") - @Deprecated(since = "3.2.0", forRemoval = true) - public String getSqlServerKerberosLoginFile() { - return getSqlserver().getKerberosLoginFile(); - } - - @Deprecated(since = "3.2.0", forRemoval = true) - public void setSqlServerKerberosLoginFile(String sqlServerKerberosLoginFile) { - getSqlserver().setKerberosLoginFile(sqlServerKerberosLoginFile); - } - public Boolean getSkipExecutingMigrations() { return this.skipExecutingMigrations; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywaySchemaManagementProvider.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywaySchemaManagementProvider.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywaySchemaManagementProvider.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywaySchemaManagementProvider.java index d293a3cc1b5b..1d626c493786 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywaySchemaManagementProvider.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/FlywaySchemaManagementProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.util.stream.StreamSupport; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProvider.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProvider.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProvider.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProvider.java index 7970d9aad671..f6280409ac47 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProvider.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizer.java index c807e813ee6e..d5714ef5a08f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.util.Arrays; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizer.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizer.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizer.java index 7f00ba624013..c6fd6e6a5f32 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizer.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import org.flywaydb.core.api.configuration.FluentConfiguration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizerBeanRegistrationAotProcessor.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizerBeanRegistrationAotProcessor.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizerBeanRegistrationAotProcessor.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizerBeanRegistrationAotProcessor.java index 81bac5a3ac63..1a0d9a39ee2f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizerBeanRegistrationAotProcessor.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizerBeanRegistrationAotProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import javax.lang.model.element.Modifier; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/endpoint/FlywayEndpointAutoConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointAutoConfiguration.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/endpoint/FlywayEndpointAutoConfiguration.java index 537968561878..500219b2eba2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/endpoint/FlywayEndpointAutoConfiguration.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure.endpoint; import org.flywaydb.core.Flyway; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.flyway.FlywayEndpoint; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.flyway.endpoint.FlywayEndpoint; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -33,10 +33,10 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link FlywayEndpoint}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = FlywayAutoConfiguration.class) -@ConditionalOnClass(Flyway.class) +@ConditionalOnClass({ Flyway.class, ConditionalOnAvailableEndpoint.class }) @ConditionalOnAvailableEndpoint(FlywayEndpoint.class) public class FlywayEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/endpoint/package-info.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/endpoint/package-info.java new file mode 100644 index 000000000000..937d14371ad4 --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Flyway endpoint. + */ +package org.springframework.boot.flyway.autoconfigure.endpoint; diff --git a/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/package-info.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/package-info.java new file mode 100644 index 000000000000..f3512564b09d --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Flyway. + */ +package org.springframework.boot.flyway.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/flyway/JdbcAdaptingFlywayConnectionDetailsFactory.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/docker/compose/JdbcAdaptingFlywayConnectionDetailsFactory.java similarity index 88% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/flyway/JdbcAdaptingFlywayConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/docker/compose/JdbcAdaptingFlywayConnectionDetailsFactory.java index 94e897be5567..0025651ee8ea 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/flyway/JdbcAdaptingFlywayConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/docker/compose/JdbcAdaptingFlywayConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.flyway; +package org.springframework.boot.flyway.docker.compose; -import org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory; +import org.springframework.boot.flyway.autoconfigure.FlywayConnectionDetails; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; /** * {@link ConnectionDetailsFactory} that produces {@link FlywayConnectionDetails} by diff --git a/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/docker/compose/package-info.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/docker/compose/package-info.java new file mode 100644 index 000000000000..d60b8a97c727 --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Flyway service connections. + */ +package org.springframework.boot.flyway.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/flyway/FlywayEndpoint.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/endpoint/FlywayEndpoint.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/flyway/FlywayEndpoint.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/endpoint/FlywayEndpoint.java index 918990860e47..1f16e9e18567 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/flyway/FlywayEndpoint.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/endpoint/FlywayEndpoint.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.flyway; +package org.springframework.boot.flyway.endpoint; import java.time.Instant; import java.util.Date; @@ -39,7 +39,7 @@ * @author Phillip Webb * @author Andy Wilkinson * @author Artsiom Yudovin - * @since 2.0.0 + * @since 4.0.0 */ @Endpoint(id = "flyway") public class FlywayEndpoint { diff --git a/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/endpoint/package-info.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/endpoint/package-info.java new file mode 100644 index 000000000000..a013dcbd920a --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator endpoint for Flyway. + */ +package org.springframework.boot.flyway.endpoint; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/flyway/package-info.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/flyway/package-info.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/package-info.java diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/flyway/FlywayContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/testcontainers/FlywayContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/flyway/FlywayContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/testcontainers/FlywayContainerConnectionDetailsFactory.java index 098ceabd0dcd..2237f517d42d 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/flyway/FlywayContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/testcontainers/FlywayContainerConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.flyway; +package org.springframework.boot.flyway.testcontainers; import org.testcontainers.containers.JdbcDatabaseContainer; -import org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails; +import org.springframework.boot.flyway.autoconfigure.FlywayConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/testcontainers/package-info.java b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/testcontainers/package-info.java new file mode 100644 index 000000000000..08d316362ae0 --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/java/org/springframework/boot/flyway/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Flyway service connections. + */ +package org.springframework.boot.flyway.testcontainers; diff --git a/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..04d0915600d8 --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring.factories @@ -0,0 +1,9 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.flyway.docker.compose.JdbcAdaptingFlywayConnectionDetailsFactory,\ +org.springframework.boot.flyway.testcontainers.FlywayContainerConnectionDetailsFactory + +# Database Initializer Detectors +org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\ +org.springframework.boot.flyway.FlywayDatabaseInitializerDetector,\ +org.springframework.boot.flyway.autoconfigure.FlywayMigrationInitializerDatabaseInitializerDetector diff --git a/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..4236408dd9db --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/additional-spring-configuration-metadata.json @@ -0,0 +1,213 @@ +{ + "properties": [ + { + "name": "spring.flyway.baseline-migration-prefix", + "defaultValue": "B", + "description": "Filename prefix for baseline migrations. Requires Flyway Teams.", + "deprecation": { + "level": "error", + "reason": "Removed in Flyway 9.0" + } + }, + { + "name": "spring.flyway.check-location", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.flyway.fail-on-missing-locations", + "level": "error" + } + }, + { + "name": "spring.flyway.cherry-pick", + "description": "Migrations that Flyway should consider when migrating or undoing. When empty all available migrations are considered. Requires Flyway Teams.", + "deprecation": { + "level": "error", + "reason": "Removed in Flyway 10" + } + }, + { + "name": "spring.flyway.clean-on-validation-error", + "type": "java.lang.Boolean", + "description": "Whether to automatically call clean when a validation error occurs.", + "deprecation": { + "level": "error", + "reason": "Deprecated in Flyway 10.18 and removed in Flyway 11.0", + "since": "3.4.0" + } + }, + { + "name": "spring.flyway.community-db-support-enabled", + "defaultValue": false + }, + { + "name": "spring.flyway.dry-run-output", + "type": "java.io.OutputStream", + "deprecation": { + "level": "error", + "reason": "Flyway Teams only." + } + }, + { + "name": "spring.flyway.error-handlers", + "type": "org.flywaydb.core.api.errorhandler.ErrorHandler[]", + "deprecation": { + "level": "error", + "reason": "Flyway Teams only." + } + }, + { + "name": "spring.flyway.ignore-future-migrations", + "type": "java.lang.Boolean", + "description": "Whether to ignore future migrations when reading the schema history table.", + "deprecation": { + "level": "error", + "reason": "Removed in Flyway 9.0", + "replacement": "spring.flyway.ignore-migration-patterns" + } + }, + { + "name": "spring.flyway.ignore-ignored-migrations", + "type": "java.lang.Boolean", + "description": "Whether to ignore ignored migrations when reading the schema history table.", + "deprecation": { + "level": "error", + "reason": "Removed in Flyway 9.0", + "replacement": "spring.flyway.ignore-migration-patterns" + } + }, + { + "name": "spring.flyway.ignore-missing-migrations", + "type": "java.lang.Boolean", + "description": "Whether to ignore missing migrations when reading the schema history table.", + "deprecation": { + "level": "error", + "reason": "Removed in Flyway 9.0", + "replacement": "spring.flyway.ignore-migration-patterns" + } + }, + { + "name": "spring.flyway.ignore-pending-migrations", + "type": "java.lang.Boolean", + "description": "Whether to ignore pending migrations when reading the schema history table.", + "deprecation": { + "level": "error", + "reason": "Removed in Flyway 9.0", + "replacement": "spring.flyway.ignore-migration-patterns" + } + }, + { + "name": "spring.flyway.license-key", + "description": "License key for Flyway Teams.", + "deprecation": { + "level": "error", + "reason": "Removed in Flyway 10" + } + }, + { + "name": "spring.flyway.locations", + "sourceType": "org.springframework.boot.flyway.autoconfigure.FlywayProperties", + "defaultValue": [ + "classpath:db/migration" + ] + }, + { + "name": "spring.flyway.oracle-kerberos-cache-file", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.flyway.oracle.kerberos-cache-file", + "level": "error", + "since": "3.2.0" + } + }, + { + "name": "spring.flyway.oracle-kerberos-config-file", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.flyway.kerberos-config-file", + "level": "error" + } + }, + { + "name": "spring.flyway.oracle-sqlplus", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.flyway.oracle.sqlplus", + "level": "error", + "since": "3.2.0" + } + }, + { + "name": "spring.flyway.oracle-sqlplus-warn", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.flyway.oracle.sqlplus-warn", + "level": "error", + "since": "3.2.0" + } + }, + { + "name": "spring.flyway.oracle-wallet-location", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.flyway.oracle.wallet-location", + "level": "error", + "since": "3.2.0" + } + }, + { + "name": "spring.flyway.sql-migration-suffix", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.flyway.sql-migration-suffixes", + "level": "error" + } + }, + { + "name": "spring.flyway.sql-migration-suffixes", + "sourceType": "org.springframework.boot.flyway.autoconfigure.FlywayProperties", + "defaultValue": [ + ".sql" + ] + }, + { + "name": "spring.flyway.sql-server-kerberos-login-file", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.flyway.sqlserver.kerberos-login-file", + "level": "error" + } + }, + { + "name": "spring.flyway.undo-sql-migration-prefix", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "reason": "Removed in Flyway 10" + } + }, + { + "name": "spring.flyway.vault-secrets", + "type": "java.util.List", + "deprecation": { + "level": "error", + "reason": "Removed in the open source release of Flyway 7.12." + } + }, + { + "name": "spring.flyway.vault-token", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "reason": "Removed in the open source release of Flyway 7.12." + } + }, + { + "name": "spring.flyway.vault-url", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "reason": "Removed in the open source release of Flyway 7.12." + } + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..4f52b20f5682 --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\ +org.springframework.boot.flyway.autoconfigure.ResourceProviderCustomizerBeanRegistrationAotProcessor diff --git a/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..940699ac900f --- /dev/null +++ b/spring-boot-project/spring-boot-flyway/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration +org.springframework.boot.flyway.autoconfigure.endpoint.FlywayEndpointAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway100AutoConfigurationTests.java b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/Flyway100AutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway100AutoConfigurationTests.java rename to spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/Flyway100AutoConfigurationTests.java index 12cbd041e819..d50d795305fd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway100AutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/Flyway100AutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import org.flywaydb.core.Flyway; import org.flywaydb.core.api.Location; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.classpath.ClassPathOverrides; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java rename to spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfigurationTests.java index 106c652d2f75..302a447b7caf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.io.Serializable; import java.lang.annotation.ElementType; @@ -61,20 +61,16 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayAutoConfigurationRuntimeHints; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.OracleFlywayConfigurationCustomizer; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.PostgresqlFlywayConfigurationCustomizer; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.SqlServerFlywayConfigurationCustomizer; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration.FlywayAutoConfigurationRuntimeHints; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration.OracleFlywayConfigurationCustomizer; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration.PostgresqlFlywayConfigurationCustomizer; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration.SqlServerFlywayConfigurationCustomizer; import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; import org.springframework.boot.jdbc.SchemaManagement; -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -492,36 +488,6 @@ void customFlywayWithJpa() { .run((context) -> assertThat(context).hasNotFailed()); } - @Test - @WithMetaInfPersistenceXmlResource - void jpaApplyDdl() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class)) - .run((context) -> { - Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) - .getJpaPropertyMap(); - assertThat(jpaProperties).doesNotContainKey("hibernate.hbm2ddl.auto"); - }); - } - - @Test - @WithMetaInfPersistenceXmlResource - void jpaAndMultipleDataSourcesApplyDdl() { - this.contextRunner.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class)) - .withUserConfiguration(JpaWithMultipleDataSourcesConfiguration.class) - .run((context) -> { - LocalContainerEntityManagerFactoryBean normalEntityManagerFactoryBean = context - .getBean("&normalEntityManagerFactory", LocalContainerEntityManagerFactoryBean.class); - assertThat(normalEntityManagerFactoryBean.getJpaPropertyMap()).containsEntry("configured", "normal") - .containsEntry("hibernate.hbm2ddl.auto", "create-drop"); - LocalContainerEntityManagerFactoryBean flywayEntityManagerFactoryBean = context - .getBean("&flywayEntityManagerFactory", LocalContainerEntityManagerFactoryBean.class); - assertThat(flywayEntityManagerFactoryBean.getJpaPropertyMap()).containsEntry("configured", "flyway") - .doesNotContainKey("hibernate.hbm2ddl.auto"); - }); - } - @Test void customFlywayWithJdbc() { this.contextRunner @@ -677,19 +643,6 @@ void oracleSqlplusIsCorrectlyMapped() { } - @Test - @Deprecated(since = "3.2.0", forRemoval = true) - void oracleSqlplusIsCorrectlyMappedWithDeprecatedProperty() { - this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) - .withPropertyValues("spring.flyway.oracle-sqlplus=true") - .run((context) -> assertThat(context.getBean(Flyway.class) - .getConfiguration() - .getPluginRegister() - .getPlugin(OracleConfigurationExtension.class) - .getSqlplus()).isTrue()); - - } - @Test void oracleSqlplusWarnIsCorrectlyMapped() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) @@ -701,18 +654,6 @@ void oracleSqlplusWarnIsCorrectlyMapped() { .getSqlplusWarn()).isTrue()); } - @Test - @Deprecated(since = "3.2.0", forRemoval = true) - void oracleSqlplusWarnIsCorrectlyMappedWithDeprecatedProperty() { - this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) - .withPropertyValues("spring.flyway.oracle-sqlplus-warn=true") - .run((context) -> assertThat(context.getBean(Flyway.class) - .getConfiguration() - .getPluginRegister() - .getPlugin(OracleConfigurationExtension.class) - .getSqlplusWarn()).isTrue()); - } - @Test void oracleWallerLocationIsCorrectlyMapped() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) @@ -724,18 +665,6 @@ void oracleWallerLocationIsCorrectlyMapped() { .getWalletLocation()).isEqualTo("/tmp/my.wallet")); } - @Test - @Deprecated(since = "3.2.0", forRemoval = true) - void oracleWallerLocationIsCorrectlyMappedWithDeprecatedProperty() { - this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) - .withPropertyValues("spring.flyway.oracle-wallet-location=/tmp/my.wallet") - .run((context) -> assertThat(context.getBean(Flyway.class) - .getConfiguration() - .getPluginRegister() - .getPlugin(OracleConfigurationExtension.class) - .getWalletLocation()).isEqualTo("/tmp/my.wallet")); - } - @Test void oracleKerberosCacheFileIsCorrectlyMapped() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) @@ -747,18 +676,6 @@ void oracleKerberosCacheFileIsCorrectlyMapped() { .getKerberosCacheFile()).isEqualTo("/tmp/cache")); } - @Test - @Deprecated(since = "3.2.0", forRemoval = true) - void oracleKerberosCacheFileIsCorrectlyMappedWithDeprecatedProperty() { - this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) - .withPropertyValues("spring.flyway.oracle-kerberos-cache-file=/tmp/cache") - .run((context) -> assertThat(context.getBean(Flyway.class) - .getConfiguration() - .getPluginRegister() - .getPlugin(OracleConfigurationExtension.class) - .getKerberosCacheFile()).isEqualTo("/tmp/cache")); - } - @Test void streamIsCorrectlyMapped() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) @@ -869,20 +786,6 @@ void sqlServerKerberosLoginFileIsCorrectlyMapped() { .getFile()).isEqualTo("/tmp/config")); } - @Test - @Deprecated(since = "3.2.0", forRemoval = true) - void sqlServerKerberosLoginFileIsCorrectlyMappedWithDeprecatedProperty() { - this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) - .withPropertyValues("spring.flyway.sql-server-kerberos-login-file=/tmp/config") - .run((context) -> assertThat(context.getBean(Flyway.class) - .getConfiguration() - .getPluginRegister() - .getPlugin(SQLServerConfigurationExtension.class) - .getKerberos() - .getLogin() - .getFile()).isEqualTo("/tmp/config")); - } - @Test void skipExecutingMigrationsIsCorrectlyMapped() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) @@ -957,9 +860,9 @@ void loggers() { @Test void overrideLoggers() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) - .withPropertyValues("spring.flyway.loggers=log4j2") + .withPropertyValues("spring.flyway.loggers=apache-commons") .run((context) -> assertThat(context.getBean(Flyway.class).getConfiguration().getLoggers()) - .containsExactly("log4j2")); + .containsExactly("apache-commons")); } @Test @@ -1097,10 +1000,11 @@ FlywayMigrationInitializer customFlywayMigrationInitializer(Flyway flyway) { @Bean LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource) { - return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), (ds) -> configureJpaProperties(), - null) - .dataSource(dataSource) - .build(); + LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); + localContainerEntityManagerFactoryBean.setDataSource(dataSource); + localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + localContainerEntityManagerFactoryBean.setJpaPropertyMap(configureJpaProperties()); + return localContainerEntityManagerFactoryBean; } } @@ -1121,50 +1025,11 @@ Flyway customFlyway() { @Bean LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { - return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), - (datasource) -> configureJpaProperties(), null) - .dataSource(this.dataSource) - .build(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class JpaWithMultipleDataSourcesConfiguration { - - @Bean - @Primary - DataSource normalDataSource() { - return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.HSQLDB.getType()) - .generateUniqueName(true) - .build(); - } - - @Bean - @Primary - LocalContainerEntityManagerFactoryBean normalEntityManagerFactory(EntityManagerFactoryBuilder builder, - DataSource normalDataSource) { - Map properties = new HashMap<>(); - properties.put("configured", "normal"); - properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); - return builder.dataSource(normalDataSource).properties(properties).build(); - } - - @Bean - @FlywayDataSource - DataSource flywayDataSource() { - return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.HSQLDB.getType()) - .generateUniqueName(true) - .build(); - } - - @Bean - LocalContainerEntityManagerFactoryBean flywayEntityManagerFactory(EntityManagerFactoryBuilder builder, - @FlywayDataSource DataSource flywayDataSource) { - Map properties = new HashMap<>(); - properties.put("configured", "flyway"); - properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); - return builder.dataSource(flywayDataSource).properties(properties).build(); + LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); + localContainerEntityManagerFactoryBean.setDataSource(this.dataSource); + localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + localContainerEntityManagerFactoryBean.setJpaPropertyMap(configureJpaProperties()); + return localContainerEntityManagerFactoryBean; } } @@ -1439,7 +1304,7 @@ public String getPassword() { - org.springframework.boot.autoconfigure.flyway.FlywayAutoConfigurationTests$City + org.springframework.boot.flyway.autoconfigure.FlywayAutoConfigurationTests$City true diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayPropertiesTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java rename to spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayPropertiesTests.java index 1ef6fe2f1021..d971a93ce631 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayPropertiesTests.java +++ b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/FlywayPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.beans.PropertyDescriptor; import java.time.Duration; @@ -81,7 +81,6 @@ void defaultValuesAreConsistent() { assertThat(properties.getInitSqls()).isEmpty(); assertThat(properties.isBaselineOnMigrate()).isEqualTo(configuration.isBaselineOnMigrate()); assertThat(properties.isCleanDisabled()).isEqualTo(configuration.isCleanDisabled()); - assertThat(properties.isCleanOnValidationError()).isEqualTo(configuration.isCleanOnValidationError()); assertThat(properties.isGroup()).isEqualTo(configuration.isGroup()); assertThat(properties.isMixed()).isEqualTo(configuration.isMixed()); assertThat(properties.isOutOfOrder()).isEqualTo(configuration.isOutOfOrder()); @@ -111,9 +110,6 @@ void expectedPropertiesAreManaged() { PropertyAccessorFactory.forBeanPropertyAccess(new ClassicConfiguration())); // Properties specific settings ignoreProperties(properties, "url", "driverClassName", "user", "password", "enabled"); - // Deprecated properties - ignoreProperties(properties, "oracleKerberosCacheFile", "oracleSqlplus", "oracleSqlplusWarn", - "oracleWalletLocation", "sqlServerKerberosLoginFile"); // Properties that are managed by specific extensions ignoreProperties(properties, "oracle", "postgresql", "sqlserver"); // Properties that are only used on the command line @@ -127,7 +123,7 @@ void expectedPropertiesAreManaged() { ignoreProperties(configuration, "resolversAsClassNames", "callbacksAsClassNames", "driver", "modernConfig", "currentResolvedEnvironment", "reportFilename", "reportEnabled", "workingDirectory", "cachedDataSources", "cachedResolvedEnvironments", "currentEnvironmentName", "allEnvironments", - "environmentProvisionMode", "provisionMode"); + "environmentProvisionMode", "provisionMode", "cleanOnValidationError"); // Handled by the conversion service ignoreProperties(configuration, "baselineVersionAsString", "encodingAsString", "locationsAsStrings", "targetAsString"); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizerTests.java b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizerTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizerTests.java rename to spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizerTests.java index 083e5b606ad2..e0d0b7c05e65 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizerTests.java +++ b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/NativeImageResourceProviderCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.util.Collection; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizerBeanRegistrationAotProcessorTests.java b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizerBeanRegistrationAotProcessorTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizerBeanRegistrationAotProcessorTests.java rename to spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizerBeanRegistrationAotProcessorTests.java index 68b9b4fe1361..6a9f0cc1ab5e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/ResourceProviderCustomizerBeanRegistrationAotProcessorTests.java +++ b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/ResourceProviderCustomizerBeanRegistrationAotProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure; import java.util.Arrays; import java.util.function.Consumer; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/endpoint/FlywayEndpointAutoConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointAutoConfigurationTests.java rename to spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/endpoint/FlywayEndpointAutoConfigurationTests.java index 4f832787a3b4..020fde5c2e01 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/flyway/FlywayEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/autoconfigure/endpoint/FlywayEndpointAutoConfigurationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.flyway; +package org.springframework.boot.flyway.autoconfigure.endpoint; import org.flywaydb.core.Flyway; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.flyway.FlywayEndpoint; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.flyway.endpoint.FlywayEndpoint; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/flyway/FlywayEndpointTests.java b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/endpoint/FlywayEndpointTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/flyway/FlywayEndpointTests.java rename to spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/endpoint/FlywayEndpointTests.java index f92d54a57e58..b7779d43d318 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/flyway/FlywayEndpointTests.java +++ b/spring-boot-project/spring-boot-flyway/src/test/java/org/springframework/boot/flyway/endpoint/FlywayEndpointTests.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.flyway; +package org.springframework.boot.flyway.endpoint; import java.util.Map; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.flyway.FlywayEndpoint.FlywayDescriptor; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayMigrationStrategy; +import org.springframework.boot.flyway.endpoint.FlywayEndpoint.FlywayDescriptor; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; diff --git a/spring-boot-project/spring-boot-freemarker/build.gradle b/spring-boot-project/spring-boot-freemarker/build.gradle new file mode 100644 index 000000000000..12e5ffd119e0 --- /dev/null +++ b/spring-boot-project/spring-boot-freemarker/build.gradle @@ -0,0 +1,43 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Freemarker" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.freemarker:freemarker") + api("org.springframework:spring-context-support") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("org.springframework:spring-webmvc") + optional("org.springframework:spring-webflux") + optional("jakarta.servlet:jakarta.servlet-api") + + testImplementation(project(":spring-boot-project:spring-boot-servlet")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/AbstractFreeMarkerConfiguration.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/AbstractFreeMarkerConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/AbstractFreeMarkerConfiguration.java rename to spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/AbstractFreeMarkerConfiguration.java index 299303eb8b13..cfb47f20acbb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/AbstractFreeMarkerConfiguration.java +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/AbstractFreeMarkerConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import java.util.HashMap; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java rename to spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfiguration.java index c1dc9eec1906..937c2efc05d9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import java.util.ArrayList; import java.util.List; @@ -37,7 +37,7 @@ * @author Andy Wilkinson * @author Dave Syer * @author Kazuki Shimizu - * @since 1.1.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ freemarker.template.Configuration.class, FreeMarkerConfigurationFactory.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerNonWebConfiguration.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerNonWebConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerNonWebConfiguration.java rename to spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerNonWebConfiguration.java index 9331ffb7c2a5..073b936cbfa1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerNonWebConfiguration.java +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerNonWebConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; diff --git a/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerProperties.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerProperties.java new file mode 100644 index 000000000000..3dc7c27843a0 --- /dev/null +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerProperties.java @@ -0,0 +1,318 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.freemarker.autoconfigure; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.core.Ordered; +import org.springframework.util.Assert; +import org.springframework.util.MimeType; +import org.springframework.web.servlet.view.AbstractTemplateViewResolver; + +/** + * {@link ConfigurationProperties @ConfigurationProperties} for configuring FreeMarker. + * + * @author Dave Syer + * @author Andy Wilkinson + * @since 4.0.0 + */ +@ConfigurationProperties("spring.freemarker") +public class FreeMarkerProperties { + + public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/"; + + public static final String DEFAULT_PREFIX = ""; + + public static final String DEFAULT_SUFFIX = ".ftlh"; + + private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html"); + + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + + /** + * Whether to enable MVC view resolution for this technology. + */ + private boolean enabled = true; + + /** + * Whether to enable template caching. + */ + private boolean cache; + + /** + * Content-Type value. + */ + private MimeType contentType = DEFAULT_CONTENT_TYPE; + + /** + * Template encoding. + */ + private Charset charset = DEFAULT_CHARSET; + + /** + * View names that can be resolved. + */ + private String[] viewNames; + + /** + * Whether to check that the templates location exists. + */ + private boolean checkTemplateLocation = true; + + /** + * Prefix that gets prepended to view names when building a URL. + */ + private String prefix = DEFAULT_PREFIX; + + /** + * Suffix that gets appended to view names when building a URL. + */ + private String suffix = DEFAULT_SUFFIX; + + /** + * Name of the RequestContext attribute for all views. + */ + private String requestContextAttribute; + + /** + * Whether all request attributes should be added to the model prior to merging with + * the template. + */ + private boolean exposeRequestAttributes = false; + + /** + * Whether all HttpSession attributes should be added to the model prior to merging + * with the template. + */ + private boolean exposeSessionAttributes = false; + + /** + * Whether HttpServletRequest attributes are allowed to override (hide) controller + * generated model attributes of the same name. + */ + private boolean allowRequestOverride = false; + + /** + * Whether to expose a RequestContext for use by Spring's macro library, under the + * name "springMacroRequestContext". + */ + private boolean exposeSpringMacroHelpers = true; + + /** + * Whether HttpSession attributes are allowed to override (hide) controller generated + * model attributes of the same name. + */ + private boolean allowSessionOverride = false; + + /** + * Well-known FreeMarker keys which are passed to FreeMarker's Configuration. + */ + private Map settings = new HashMap<>(); + + /** + * List of template paths. + */ + private String[] templateLoaderPath = new String[] { DEFAULT_TEMPLATE_LOADER_PATH }; + + /** + * Whether to prefer file system access for template loading to enable hot detection + * of template changes. When a template path is detected as a directory, templates are + * loaded from the directory only and other matching classpath locations will not be + * considered. + */ + private boolean preferFileSystemAccess; + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isEnabled() { + return this.enabled; + } + + public void setCheckTemplateLocation(boolean checkTemplateLocation) { + this.checkTemplateLocation = checkTemplateLocation; + } + + public boolean isCheckTemplateLocation() { + return this.checkTemplateLocation; + } + + public String[] getViewNames() { + return this.viewNames; + } + + public void setViewNames(String[] viewNames) { + this.viewNames = viewNames; + } + + public boolean isCache() { + return this.cache; + } + + public void setCache(boolean cache) { + this.cache = cache; + } + + public MimeType getContentType() { + if (this.contentType.getCharset() == null) { + Map parameters = new LinkedHashMap<>(); + parameters.put("charset", this.charset.name()); + parameters.putAll(this.contentType.getParameters()); + return new MimeType(this.contentType, parameters); + } + return this.contentType; + } + + public void setContentType(MimeType contentType) { + this.contentType = contentType; + } + + public Charset getCharset() { + return this.charset; + } + + public String getCharsetName() { + return (this.charset != null) ? this.charset.name() : null; + } + + public void setCharset(Charset charset) { + this.charset = charset; + } + + public Map getSettings() { + return this.settings; + } + + public void setSettings(Map settings) { + this.settings = settings; + } + + public String[] getTemplateLoaderPath() { + return this.templateLoaderPath; + } + + public void setTemplateLoaderPath(String... templateLoaderPaths) { + this.templateLoaderPath = templateLoaderPaths; + } + + public boolean isPreferFileSystemAccess() { + return this.preferFileSystemAccess; + } + + public void setPreferFileSystemAccess(boolean preferFileSystemAccess) { + this.preferFileSystemAccess = preferFileSystemAccess; + } + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return this.suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public String getRequestContextAttribute() { + return this.requestContextAttribute; + } + + public void setRequestContextAttribute(String requestContextAttribute) { + this.requestContextAttribute = requestContextAttribute; + } + + public boolean isExposeRequestAttributes() { + return this.exposeRequestAttributes; + } + + public void setExposeRequestAttributes(boolean exposeRequestAttributes) { + this.exposeRequestAttributes = exposeRequestAttributes; + } + + public boolean isExposeSessionAttributes() { + return this.exposeSessionAttributes; + } + + public void setExposeSessionAttributes(boolean exposeSessionAttributes) { + this.exposeSessionAttributes = exposeSessionAttributes; + } + + public boolean isAllowRequestOverride() { + return this.allowRequestOverride; + } + + public void setAllowRequestOverride(boolean allowRequestOverride) { + this.allowRequestOverride = allowRequestOverride; + } + + public boolean isAllowSessionOverride() { + return this.allowSessionOverride; + } + + public void setAllowSessionOverride(boolean allowSessionOverride) { + this.allowSessionOverride = allowSessionOverride; + } + + public boolean isExposeSpringMacroHelpers() { + return this.exposeSpringMacroHelpers; + } + + public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) { + this.exposeSpringMacroHelpers = exposeSpringMacroHelpers; + } + + /** + * Apply the given properties to a {@link AbstractTemplateViewResolver}. Use Object in + * signature to avoid runtime dependency on MVC, which means that the template engine + * can be used in a non-web application. + * @param viewResolver the resolver to apply the properties to. + */ + public void applyToMvcViewResolver(Object viewResolver) { + Assert.isInstanceOf(AbstractTemplateViewResolver.class, viewResolver, + () -> "ViewResolver is not an instance of AbstractTemplateViewResolver :" + viewResolver); + AbstractTemplateViewResolver resolver = (AbstractTemplateViewResolver) viewResolver; + resolver.setPrefix(getPrefix()); + resolver.setSuffix(getSuffix()); + resolver.setCache(isCache()); + if (getContentType() != null) { + resolver.setContentType(getContentType().toString()); + } + resolver.setViewNames(getViewNames()); + resolver.setExposeRequestAttributes(isExposeRequestAttributes()); + resolver.setAllowRequestOverride(isAllowRequestOverride()); + resolver.setAllowSessionOverride(isAllowSessionOverride()); + resolver.setExposeSessionAttributes(isExposeSessionAttributes()); + resolver.setExposeSpringMacroHelpers(isExposeSpringMacroHelpers()); + resolver.setRequestContextAttribute(getRequestContextAttribute()); + // The resolver usually acts as a fallback resolver (e.g. like a + // InternalResourceViewResolver) so it needs to have low precedence + resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerReactiveWebConfiguration.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerReactiveWebConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerReactiveWebConfiguration.java rename to spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerReactiveWebConfiguration.java index acd2358860e4..cf6b77780cb8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerReactiveWebConfiguration.java +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerReactiveWebConfiguration.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.result.view.freemarker.FreeMarkerConfig; @@ -36,7 +36,8 @@ */ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@AutoConfigureAfter(WebFluxAutoConfiguration.class) +@ConditionalOnClass(FreeMarkerConfigurer.class) +@AutoConfigureAfter(name = "org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration") class FreeMarkerReactiveWebConfiguration extends AbstractFreeMarkerConfiguration { FreeMarkerReactiveWebConfiguration(FreeMarkerProperties properties, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerServletWebConfiguration.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerServletWebConfiguration.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerServletWebConfiguration.java rename to spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerServletWebConfiguration.java index 4b7020e48c76..406c09077470 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerServletWebConfiguration.java +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerServletWebConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import jakarta.servlet.DispatcherType; import jakarta.servlet.Servlet; @@ -24,10 +24,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; -import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -45,7 +44,7 @@ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass({ Servlet.class, FreeMarkerConfigurer.class }) -@AutoConfigureAfter(WebMvcAutoConfiguration.class) +@AutoConfigureAfter(name = "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration") class FreeMarkerServletWebConfiguration extends AbstractFreeMarkerConfiguration { protected FreeMarkerServletWebConfiguration(FreeMarkerProperties properties, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerTemplateAvailabilityProvider.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java rename to spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerTemplateAvailabilityProvider.java index fc4172474b14..f6167d5f44b5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProvider.java +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerTemplateAvailabilityProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import java.util.ArrayList; import java.util.Arrays; @@ -32,7 +32,7 @@ * FreeMarker view templates. * * @author Andy Wilkinson - * @since 1.1.0 + * @since 4.0.0 */ public class FreeMarkerTemplateAvailabilityProvider extends PathBasedTemplateAvailabilityProvider { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerVariablesCustomizer.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerVariablesCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerVariablesCustomizer.java rename to spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerVariablesCustomizer.java index 018f12bd9b9c..15661d010f54 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerVariablesCustomizer.java +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerVariablesCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import java.util.Map; @@ -28,7 +28,7 @@ * before it is used by an auto-configured {@link FreeMarkerConfigurationFactory}. * * @author Stephane Nicoll - * @since 3.4.0 + * @since 4.0.0 */ @FunctionalInterface public interface FreeMarkerVariablesCustomizer { diff --git a/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/package-info.java b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/package-info.java new file mode 100644 index 000000000000..0fa1da4d696f --- /dev/null +++ b/spring-boot-project/spring-boot-freemarker/src/main/java/org/springframework/boot/freemarker/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for FreeMarker. + */ +package org.springframework.boot.freemarker.autoconfigure; diff --git a/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..4d823ad88eea --- /dev/null +++ b/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,45 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.freemarker.allow-request-override", + "description": "Whether HttpServletRequest attributes are allowed to override (hide) controller generated model attributes of the same name. Only supported with Spring MVC." + }, + { + "name": "spring.freemarker.allow-session-override", + "description": "Whether HttpSession attributes are allowed to override (hide) controller generated model attributes of the same name. Only supported with Spring MVC." + }, + { + "name": "spring.freemarker.cache", + "description": "Whether to enable template caching. Only supported with Spring MVC." + }, + { + "name": "spring.freemarker.content-type", + "description": "Content-Type value. Only supported with Spring MVC." + }, + { + "name": "spring.freemarker.expose-request-attributes", + "description": "Whether all request attributes should be added to the model prior to merging with the template. Only supported with Spring MVC." + }, + { + "name": "spring.freemarker.expose-session-attributes", + "description": "Whether all HttpSession attributes should be added to the model prior to merging with the template. Only supported with Spring MVC." + }, + { + "name": "spring.freemarker.expose-spring-macro-helpers", + "description": "Whether to expose a RequestContext for use by Spring's macro library, under the name \"springMacroRequestContext\". Only supported with Spring MVC." + }, + { + "name": "spring.freemarker.prefix", + "defaultValue": "" + }, + { + "name": "spring.freemarker.suffix", + "defaultValue": ".ftlh" + } + ], + "hints": [], + "ignored": { + "properties": [] + } +} diff --git a/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..d641c14f0731 --- /dev/null +++ b/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Template Availability Providers +org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ +org.springframework.boot.freemarker.autoconfigure.FreeMarkerTemplateAvailabilityProvider diff --git a/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..59f8b403374a --- /dev/null +++ b/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.freemarker.autoconfigure.FreeMarkerTemplateAvailabilityProvider$FreeMarkerTemplateAvailabilityRuntimeHints diff --git a/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..6a71b86fac28 --- /dev/null +++ b/spring-boot-project/spring-boot-freemarker/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationReactiveIntegrationTests.java b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationReactiveIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationReactiveIntegrationTests.java rename to spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationReactiveIntegrationTests.java index 17188eb5ace6..587f93c1d902 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationReactiveIntegrationTests.java +++ b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationReactiveIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import java.io.StringWriter; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationServletIntegrationTests.java b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationServletIntegrationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationServletIntegrationTests.java rename to spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationServletIntegrationTests.java index 615c4c82f4af..05090abcfa1f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationServletIntegrationTests.java +++ b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationServletIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import java.io.StringWriter; import java.util.EnumSet; @@ -28,11 +28,11 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.servlet.filter.OrderedCharacterEncodingFilter; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationTests.java similarity index 83% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationTests.java index 677b82337e76..d29774f6240f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerAutoConfigurationTests.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; -import java.io.File; import java.io.StringWriter; +import java.nio.file.Path; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.testsupport.BuildOutput; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -46,8 +46,6 @@ @ExtendWith(OutputCaptureExtension.class) class FreeMarkerAutoConfigurationTests { - private final BuildOutput buildOutput = new BuildOutput(getClass()); - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(FreeMarkerAutoConfiguration.class)); @@ -71,20 +69,16 @@ void nonExistentTemplateLocation(CapturedOutput output) { } @Test - void emptyTemplateLocation(CapturedOutput output) { - File emptyDirectory = new File(this.buildOutput.getTestResourcesLocation(), "empty-templates/empty-directory"); - emptyDirectory.mkdirs(); - this.contextRunner - .withPropertyValues("spring.freemarker.templateLoaderPath:classpath:/empty-templates/empty-directory/") + void emptyTemplateLocation(CapturedOutput output, @TempDir Path tempDir) { + this.contextRunner.withPropertyValues("spring.freemarker.templateLoaderPath:file:" + tempDir.toAbsolutePath()) .run((context) -> assertThat(output).doesNotContain("Cannot find template location")); } @Test - void nonExistentLocationAndEmptyLocation(CapturedOutput output) { - new File(this.buildOutput.getTestResourcesLocation(), "empty-templates/empty-directory").mkdirs(); + void nonExistentLocationAndEmptyLocation(CapturedOutput output, @TempDir Path tempDir) { this.contextRunner - .withPropertyValues("spring.freemarker.templateLoaderPath:" - + "classpath:/does-not-exist/,classpath:/empty-templates/empty-directory/") + .withPropertyValues("spring.freemarker.templateLoaderPath:" + "classpath:/does-not-exist/,file:" + + tempDir.toAbsolutePath()) .run((context) -> assertThat(output).doesNotContain("Cannot find template location")); } diff --git a/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerPropertiesTests.java b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerPropertiesTests.java new file mode 100644 index 000000000000..a3ef1240cf92 --- /dev/null +++ b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerPropertiesTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.freemarker.autoconfigure; + +import java.nio.charset.StandardCharsets; + +import org.junit.jupiter.api.Test; + +import org.springframework.util.MimeTypeUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link FreeMarkerProperties}. + * + * @author Stephane Nicoll + */ +class FreeMarkerPropertiesTests { + + @Test + void defaultContentType() { + assertThat(new FreeMarkerProperties().getContentType()).hasToString("text/html;charset=UTF-8"); + } + + @Test + void customContentTypeDefaultCharset() { + FreeMarkerProperties properties = new FreeMarkerProperties(); + properties.setContentType(MimeTypeUtils.parseMimeType("text/plain")); + assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-8"); + } + + @Test + void defaultContentTypeCustomCharset() { + FreeMarkerProperties properties = new FreeMarkerProperties(); + properties.setCharset(StandardCharsets.UTF_16); + assertThat(properties.getContentType()).hasToString("text/html;charset=UTF-16"); + } + + @Test + void customContentTypeCustomCharset() { + FreeMarkerProperties properties = new FreeMarkerProperties(); + properties.setContentType(MimeTypeUtils.parseMimeType("text/plain")); + properties.setCharset(StandardCharsets.UTF_16); + assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16"); + } + + @Test + void customContentTypeWithPropertyAndCustomCharset() { + FreeMarkerProperties properties = new FreeMarkerProperties(); + properties.setContentType(MimeTypeUtils.parseMimeType("text/plain;foo=bar")); + properties.setCharset(StandardCharsets.UTF_16); + assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16;foo=bar"); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerTemplateAvailabilityProviderTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java rename to spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerTemplateAvailabilityProviderTests.java index e310063e5977..9b44029f6e95 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerTemplateAvailabilityProviderTests.java +++ b/spring-boot-project/spring-boot-freemarker/src/test/java/org/springframework/boot/freemarker/autoconfigure/FreeMarkerTemplateAvailabilityProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.freemarker; +package org.springframework.boot.freemarker.autoconfigure; import org.junit.jupiter.api.Test; @@ -22,9 +22,9 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.TypeHint; import org.springframework.beans.factory.aot.AotServices; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityProperties; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityRuntimeHints; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; +import org.springframework.boot.freemarker.autoconfigure.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityProperties; +import org.springframework.boot.freemarker.autoconfigure.FreeMarkerTemplateAvailabilityProvider.FreeMarkerTemplateAvailabilityRuntimeHints; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; diff --git a/spring-boot-project/spring-boot-graphql-test/build.gradle b/spring-boot-project/spring-boot-graphql-test/build.gradle new file mode 100644 index 000000000000..b59e9526a68b --- /dev/null +++ b/spring-boot-project/spring-boot-graphql-test/build.gradle @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot GraphQL Test" + +dependencies { + api("org.springframework.graphql:spring-graphql-test") + + implementation(project(":spring-boot-project:spring-boot-test")) + + optional(project(":spring-boot-project:spring-boot-web-server")) + optional(project(":spring-boot-project:spring-boot-web-server-test")) + optional("jakarta.servlet:jakarta.servlet-api") + optional("org.springframework:spring-web") + + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("org.springframework:spring-webflux") + testImplementation("org.springframework:spring-webmvc") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.fasterxml.jackson.core:jackson-databind") +} + +tasks.named("javadoc") { + enabled = false +} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/HttpGraphQlTesterContextCustomizer.java b/spring-boot-project/spring-boot-graphql-test/src/main/java/org/springframework/boot/test/graphql/tester/HttpGraphQlTesterContextCustomizer.java similarity index 99% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/HttpGraphQlTesterContextCustomizer.java rename to spring-boot-project/spring-boot-graphql-test/src/main/java/org/springframework/boot/test/graphql/tester/HttpGraphQlTesterContextCustomizer.java index 527c21eaf337..17afffb522fc 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/HttpGraphQlTesterContextCustomizer.java +++ b/spring-boot-project/spring-boot-graphql-test/src/main/java/org/springframework/boot/test/graphql/tester/HttpGraphQlTesterContextCustomizer.java @@ -124,7 +124,7 @@ public static class HttpGraphQlTesterFactory implements FactoryBean executionConvention, ObjectProvider dataFetcherConvention, ObjectProvider dataLoaderObservationConvention) { diff --git a/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/observation/package-info.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/observation/package-info.java new file mode 100644 index 000000000000..862c43c6b174 --- /dev/null +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/observation/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring GraphQL observations. + */ +package org.springframework.boot.graphql.autoconfigure.observation; diff --git a/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/package-info.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/package-info.java new file mode 100644 index 000000000000..fa89eb52edd9 --- /dev/null +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring GraphQL. + */ +package org.springframework.boot.graphql.autoconfigure; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/reactive/GraphQlWebFluxAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java rename to spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/reactive/GraphQlWebFluxAutoConfiguration.java index 30ba6a2623c2..008d6e730ae4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/reactive/GraphQlWebFluxAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.reactive; +package org.springframework.boot.graphql.autoconfigure.reactive; import java.util.Collections; @@ -33,10 +33,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlCorsProperties; -import org.springframework.boot.autoconfigure.graphql.GraphQlProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlCorsProperties; +import org.springframework.boot.graphql.autoconfigure.GraphQlProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportRuntimeHints; @@ -73,7 +73,7 @@ * WebFlux. * * @author Brian Clozel - * @since 2.7.0 + * @since 4.0.0 */ @AutoConfiguration(after = GraphQlAutoConfiguration.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) diff --git a/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..aa756381a187 --- /dev/null +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration classes for WebFlux support in Spring GraphQL. + */ +package org.springframework.boot.graphql.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketAutoConfiguration.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketAutoConfiguration.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketAutoConfiguration.java rename to spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketAutoConfiguration.java index ba7da0e5094f..897ccd620d5a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketAutoConfiguration.java +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.rsocket; +package org.springframework.boot.graphql.autoconfigure.rsocket; import com.fasterxml.jackson.databind.ObjectMapper; import graphql.GraphQL; @@ -28,8 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.graphql.ExecutionGraphQlService; import org.springframework.graphql.data.method.annotation.support.AnnotatedControllerConfigurer; @@ -43,9 +42,10 @@ * RSocket. * * @author Brian Clozel - * @since 2.7.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { GraphQlAutoConfiguration.class, RSocketMessagingAutoConfiguration.class }) +@AutoConfiguration(after = GraphQlAutoConfiguration.class, + afterName = "org.springframework.boot.rsocket.autoconfigure.RSocketMessagingAutoConfiguration") @ConditionalOnClass({ GraphQL.class, GraphQlSource.class, RSocketServer.class, HttpServer.class }) @ConditionalOnBean({ RSocketMessageHandler.class, AnnotatedControllerConfigurer.class }) @ConditionalOnProperty("spring.graphql.rsocket.mapping") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketController.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketController.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketController.java rename to spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketController.java index 9038af21d733..1125251099be 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketController.java +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.rsocket; +package org.springframework.boot.graphql.autoconfigure.rsocket; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/RSocketGraphQlClientAutoConfiguration.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/RSocketGraphQlClientAutoConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/RSocketGraphQlClientAutoConfiguration.java rename to spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/RSocketGraphQlClientAutoConfiguration.java index 2ab38fc2a50b..3ac76eaf3ddd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/rsocket/RSocketGraphQlClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/RSocketGraphQlClientAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.rsocket; +package org.springframework.boot.graphql.autoconfigure.rsocket; import graphql.GraphQL; import io.rsocket.RSocket; @@ -25,7 +25,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Scope; import org.springframework.graphql.client.RSocketGraphQlClient; @@ -40,9 +39,9 @@ * not be reused to build client instances with different configurations. * * @author Brian Clozel - * @since 2.7.0 + * @since 4.0.0 */ -@AutoConfiguration(after = RSocketRequesterAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.rsocket.autoconfigure.RSocketRequesterAutoConfiguration") @ConditionalOnClass({ GraphQL.class, RSocketGraphQlClient.class, RSocketRequester.class, RSocket.class, TcpClientTransport.class }) public class RSocketGraphQlClientAutoConfiguration { diff --git a/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/package-info.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/package-info.java new file mode 100644 index 000000000000..6615ff572e3e --- /dev/null +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/rsocket/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration classes for RSocket integration with GraphQL. + */ +package org.springframework.boot.graphql.autoconfigure.rsocket; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebFluxSecurityAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfiguration.java rename to spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebFluxSecurityAutoConfiguration.java index 4d35173a9026..78537108ec9c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebFluxSecurityAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.security; +package org.springframework.boot.graphql.autoconfigure.security; import graphql.GraphQL; @@ -24,7 +24,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.reactive.GraphQlWebFluxAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.graphql.execution.ReactiveSecurityDataFetcherExceptionResolver; import org.springframework.graphql.server.webflux.GraphQlHttpHandler; @@ -35,7 +35,7 @@ * Spring GraphQL with WebFlux. * * @author Brian Clozel - * @since 2.7.0 + * @since 4.0.0 */ @AutoConfiguration(after = GraphQlWebFluxAutoConfiguration.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebMvcSecurityAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfiguration.java rename to spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebMvcSecurityAutoConfiguration.java index c5a674d95849..8edc27546062 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebMvcSecurityAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.security; +package org.springframework.boot.graphql.autoconfigure.security; import graphql.GraphQL; @@ -24,7 +24,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.servlet.GraphQlWebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.graphql.execution.SecurityDataFetcherExceptionResolver; import org.springframework.graphql.server.webmvc.GraphQlHttpHandler; @@ -35,7 +35,7 @@ * Spring GraphQL with MVC. * * @author Brian Clozel - * @since 2.7.0 + * @since 4.0.0 */ @AutoConfiguration(after = GraphQlWebMvcAutoConfiguration.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) diff --git a/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/package-info.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/package-info.java new file mode 100644 index 000000000000..ddc4164edf18 --- /dev/null +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/security/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration classes for Security support in Spring GraphQL. + */ +package org.springframework.boot.graphql.autoconfigure.security; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java rename to spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java index 19033fb216e0..e665a3aff20c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.servlet; +package org.springframework.boot.graphql.autoconfigure.servlet; import java.util.Collections; import java.util.Map; @@ -34,11 +34,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlCorsProperties; -import org.springframework.boot.autoconfigure.graphql.GraphQlProperties; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlCorsProperties; +import org.springframework.boot.graphql.autoconfigure.GraphQlProperties; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportRuntimeHints; @@ -77,7 +77,7 @@ * Spring MVC. * * @author Brian Clozel - * @since 2.7.0 + * @since 4.0.0 */ @AutoConfiguration(after = GraphQlAutoConfiguration.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @@ -172,7 +172,7 @@ public void addCorsMappings(CorsRegistry registry) { } @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ ServerContainer.class, WebSocketHandler.class }) + @ConditionalOnClass({ HttpMessageConverters.class, ServerContainer.class, WebSocketHandler.class }) @ConditionalOnProperty("spring.graphql.websocket.path") public static class WebSocketConfiguration { diff --git a/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..7df67719b110 --- /dev/null +++ b/spring-boot-project/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration classes for MVC support in Spring GraphQL. + */ +package org.springframework.boot.graphql.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot-graphql/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-graphql/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..ac88283fccf7 --- /dev/null +++ b/spring-boot-project/spring-boot-graphql/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,100 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.metrics.graphql.autotime.enabled", + "description": "Whether to automatically time web client requests.", + "defaultValue": true, + "deprecation": { + "level": "error", + "reason": "Requests are timed automatically." + } + }, + { + "name": "management.metrics.graphql.autotime.percentiles", + "description": "Computed non-aggregable percentiles to publish.", + "deprecation": { + "level": "error", + "reason": "Should be configured globally via management.metrics.distribution.percentiles." + } + }, + { + "name": "management.metrics.graphql.autotime.percentiles-histogram", + "description": "Whether percentile histograms should be published.", + "defaultValue": false, + "deprecation": { + "level": "error", + "reason": "Should be configured globally via management.metrics.distribution.percentiles-histogram." + } + }, + { + "name": "spring.graphql.path", + "type": "java.lang.String", + "deprecated": true, + "deprecation": { + "level": "error", + "replacement": "spring.graphql.http.path", + "since": "3.5.0" + } + }, + { + "name": "spring.graphql.schema.file-extensions", + "defaultValue": ".graphqls,.gqls" + }, + { + "name": "spring.graphql.schema.locations", + "defaultValue": "classpath:graphql/**/" + }, + { + "name": "spring.graphql.sse.timeout", + "type": "java.time.Duration", + "deprecated": true, + "deprecation": { + "level": "error", + "replacement": "spring.graphql.http.sse.timeout", + "since": "3.5.0" + } + } + ], + "hints": [ + { + "name": "spring.graphql.cors.allowed-headers", + "values": [ + { + "value": "*" + } + ], + "providers": [ + { + "name": "any" + } + ] + }, + { + "name": "spring.graphql.cors.allowed-methods", + "values": [ + { + "value": "*" + } + ], + "providers": [ + { + "name": "any" + } + ] + }, + { + "name": "spring.graphql.cors.allowed-origins", + "values": [ + { + "value": "*" + } + ], + "providers": [ + { + "name": "any" + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-graphql/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-graphql/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..79e251a5bf51 --- /dev/null +++ b/spring-boot-project/spring-boot-graphql/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,12 @@ +org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration +org.springframework.boot.graphql.autoconfigure.data.GraphQlQueryByExampleAutoConfiguration +org.springframework.boot.graphql.autoconfigure.data.GraphQlQuerydslAutoConfiguration +org.springframework.boot.graphql.autoconfigure.data.GraphQlReactiveQueryByExampleAutoConfiguration +org.springframework.boot.graphql.autoconfigure.data.GraphQlReactiveQuerydslAutoConfiguration +org.springframework.boot.graphql.autoconfigure.observation.GraphQlObservationAutoConfiguration +org.springframework.boot.graphql.autoconfigure.reactive.GraphQlWebFluxAutoConfiguration +org.springframework.boot.graphql.autoconfigure.rsocket.GraphQlRSocketAutoConfiguration +org.springframework.boot.graphql.autoconfigure.rsocket.RSocketGraphQlClientAutoConfiguration +org.springframework.boot.graphql.autoconfigure.security.GraphQlWebFluxSecurityAutoConfiguration +org.springframework.boot.graphql.autoconfigure.security.GraphQlWebMvcSecurityAutoConfiguration +org.springframework.boot.graphql.autoconfigure.servlet.GraphQlWebMvcAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/Book.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/Book.java index 52f75652caf5..3648005fe8b0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/Book.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql; +package org.springframework.boot.graphql.autoconfigure; import org.springframework.data.annotation.Id; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/DefaultGraphQlSchemaConditionTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/DefaultGraphQlSchemaConditionTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/DefaultGraphQlSchemaConditionTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/DefaultGraphQlSchemaConditionTests.java index b7d54c2bee03..3dd6ebb780eb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/DefaultGraphQlSchemaConditionTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/DefaultGraphQlSchemaConditionTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql; +package org.springframework.boot.graphql.autoconfigure; import java.util.Collection; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/GraphQlAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/GraphQlAutoConfigurationTests.java index 0fbba549f8c6..aba9d4bad4bf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/GraphQlAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql; +package org.springframework.boot.graphql.autoconfigure; import java.nio.charset.StandardCharsets; import java.util.concurrent.Executor; @@ -34,8 +34,8 @@ import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration.GraphQlResourcesRuntimeHints; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration.GraphQlResourcesRuntimeHints; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlTestDataFetchers.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/GraphQlTestDataFetchers.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlTestDataFetchers.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/GraphQlTestDataFetchers.java index bf637be15548..9dd190d00c21 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlTestDataFetchers.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/GraphQlTestDataFetchers.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql; +package org.springframework.boot.graphql.autoconfigure; import java.util.Arrays; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/QBook.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/QBook.java index ab910621fc40..c8ed0c39cce6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/QBook.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql; +package org.springframework.boot.graphql.autoconfigure; import com.querydsl.core.types.Path; import com.querydsl.core.types.PathMetadata; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlQueryByExampleAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlQueryByExampleAutoConfigurationTests.java index 21feb901f6a6..5cd9c4592929 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlQueryByExampleAutoConfigurationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.data; +package org.springframework.boot.graphql.autoconfigure.data; import java.util.Optional; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.Book; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlQuerydslAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlQuerydslAutoConfigurationTests.java index 225d5b8ae9ba..6c66df4128bd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlQuerydslAutoConfigurationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.data; +package org.springframework.boot.graphql.autoconfigure.data; import java.util.Optional; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.Book; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java index 8074dd9507e0..bfebbda4b7c9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.data; +package org.springframework.boot.graphql.autoconfigure.data; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.Book; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlReactiveQuerydslAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlReactiveQuerydslAutoConfigurationTests.java index 342b947d2845..9a7512530a56 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/data/GraphQlReactiveQuerydslAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.data; +package org.springframework.boot.graphql.autoconfigure.data; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.Book; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/GraphQlObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/observation/GraphQlObservationAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/GraphQlObservationAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/observation/GraphQlObservationAutoConfigurationTests.java index 8c51e8d0716a..734cd6be53c6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/graphql/GraphQlObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/observation/GraphQlObservationAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation.graphql; +package org.springframework.boot.graphql.autoconfigure.observation; import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.tck.TestObservationRegistry; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/reactive/GraphQlWebFluxAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/reactive/GraphQlWebFluxAutoConfigurationTests.java index ea1f8551462d..7b5bdb0b7fa7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/reactive/GraphQlWebFluxAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.reactive; +package org.springframework.boot.graphql.autoconfigure.reactive; import java.time.Duration; import java.util.Collections; @@ -28,14 +28,14 @@ import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlTestDataFetchers; +import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketAutoConfigurationTests.java similarity index 86% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketAutoConfigurationTests.java index b5250cb2b010..9c1d18740b1d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/rsocket/GraphQlRSocketAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/rsocket/GraphQlRSocketAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.rsocket; +package org.springframework.boot.graphql.autoconfigure.rsocket; import java.net.URI; import java.time.Duration; @@ -25,22 +25,22 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlTestDataFetchers; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.reactor.netty.NettyRouteProvider; +import org.springframework.boot.rsocket.autoconfigure.RSocketMessagingAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketServerAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketStrategiesAutoConfiguration; import org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.netty.NettyRouteProvider; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.error.ErrorWebFluxAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.graphql.client.RSocketGraphQlClient; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/rsocket/RSocketGraphQlClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/rsocket/RSocketGraphQlClientAutoConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/rsocket/RSocketGraphQlClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/rsocket/RSocketGraphQlClientAutoConfigurationTests.java index 5fb1b3ad06b1..9ef12ed453c8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/rsocket/RSocketGraphQlClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/rsocket/RSocketGraphQlClientAutoConfigurationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.rsocket; +package org.springframework.boot.graphql.autoconfigure.rsocket; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketRequesterAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketStrategiesAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebFluxSecurityAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebFluxSecurityAutoConfigurationTests.java index 7acaec255c5b..0798c29af953 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebFluxSecurityAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.security; +package org.springframework.boot.graphql.autoconfigure.security; import java.util.Collections; import java.util.function.Consumer; @@ -25,17 +25,17 @@ import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.Book; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlTestDataFetchers; +import org.springframework.boot.graphql.autoconfigure.reactive.GraphQlWebFluxAutoConfiguration; +import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.graphql.execution.ErrorType; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebMvcSecurityAutoConfigurationTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebMvcSecurityAutoConfigurationTests.java index 6a76a936801f..458c9e16441d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebMvcSecurityAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.security; +package org.springframework.boot.graphql.autoconfigure.security; import graphql.schema.idl.TypeRuntimeWiring; import org.assertj.core.api.ThrowingConsumer; @@ -22,17 +22,17 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.Book; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlTestDataFetchers; +import org.springframework.boot.graphql.autoconfigure.servlet.GraphQlWebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.graphql.execution.ErrorType; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfigurationTests.java rename to spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfigurationTests.java index 6aa4b49c6e7a..04273fb4fefc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.graphql.servlet; +package org.springframework.boot.graphql.autoconfigure.servlet; import java.time.Duration; import java.util.Map; @@ -27,14 +27,14 @@ import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlTestDataFetchers; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; diff --git a/spring-boot-project/spring-boot-groovy-templates/build.gradle b/spring-boot-project/spring-boot-groovy-templates/build.gradle new file mode 100644 index 000000000000..10c2aa747f9b --- /dev/null +++ b/spring-boot-project/spring-boot-groovy-templates/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Groovy Templates" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.apache.groovy:groovy-templates") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("org.springframework:spring-webmvc") + optional("jakarta.servlet:jakarta.servlet-api") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java b/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java rename to spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAutoConfiguration.java index 23ff2793c353..abeb1316a9c9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfiguration.java +++ b/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.groovy.template; +package org.springframework.boot.groovy.template.autoconfigure; import java.security.CodeSource; import java.security.ProtectionDomain; @@ -32,7 +32,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.template.TemplateLocation; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.context.properties.bind.Bindable; @@ -57,9 +56,9 @@ * @author Dave Syer * @author Andy Wilkinson * @author Brian Clozel - * @since 1.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = WebMvcAutoConfiguration.class) +@AutoConfiguration @ConditionalOnClass(MarkupTemplateEngine.class) @EnableConfigurationProperties(GroovyTemplateProperties.class) public class GroovyTemplateAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java b/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAvailabilityProvider.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java rename to spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAvailabilityProvider.java index 4db461d77652..6ed52c2b1b2d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProvider.java +++ b/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAvailabilityProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.groovy.template; +package org.springframework.boot.groovy.template.autoconfigure; import java.util.ArrayList; import java.util.Arrays; @@ -32,7 +32,7 @@ * view templates. * * @author Dave Syer - * @since 1.1.0 + * @since 4.0.0 */ public class GroovyTemplateAvailabilityProvider extends PathBasedTemplateAvailabilityProvider { diff --git a/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateProperties.java b/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateProperties.java new file mode 100644 index 000000000000..1ff9cd055734 --- /dev/null +++ b/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateProperties.java @@ -0,0 +1,425 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.groovy.template.autoconfigure; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + +import groovy.text.markup.BaseTemplate; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.core.Ordered; +import org.springframework.util.Assert; +import org.springframework.util.MimeType; +import org.springframework.web.servlet.view.AbstractTemplateViewResolver; + +/** + * {@link ConfigurationProperties @ConfigurationProperties} for configuring Groovy + * templates. + * + * @author Dave Syer + * @author Marten Deinum + * @since 4.0.0 + */ +@ConfigurationProperties("spring.groovy.template") +public class GroovyTemplateProperties { + + public static final String DEFAULT_RESOURCE_LOADER_PATH = "classpath:/templates/"; + + public static final String DEFAULT_PREFIX = ""; + + public static final String DEFAULT_SUFFIX = ".tpl"; + + public static final String DEFAULT_REQUEST_CONTEXT_ATTRIBUTE = "spring"; + + private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html"); + + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + + /** + * Whether to enable MVC view resolution for this technology. + */ + private boolean enabled = true; + + /** + * Whether to enable template caching. + */ + private boolean cache; + + /** + * Content-Type value. + */ + private MimeType contentType = DEFAULT_CONTENT_TYPE; + + /** + * Template encoding. + */ + private Charset charset = DEFAULT_CHARSET; + + /** + * View names that can be resolved. + */ + private String[] viewNames; + + /** + * Whether to check that the templates location exists. + */ + private boolean checkTemplateLocation = true; + + /** + * Prefix that gets prepended to view names when building a URL. + */ + private String prefix = DEFAULT_PREFIX; + + /** + * Suffix that gets appended to view names when building a URL. + */ + private String suffix = DEFAULT_SUFFIX; + + /** + * Name of the RequestContext attribute for all views. + */ + private String requestContextAttribute = DEFAULT_REQUEST_CONTEXT_ATTRIBUTE; + + /** + * Whether all request attributes should be added to the model prior to merging with + * the template. + */ + private boolean exposeRequestAttributes = false; + + /** + * Whether all HttpSession attributes should be added to the model prior to merging + * with the template. + */ + private boolean exposeSessionAttributes = false; + + /** + * Whether HttpServletRequest attributes are allowed to override (hide) controller + * generated model attributes of the same name. + */ + private boolean allowRequestOverride = false; + + /** + * Whether to expose a RequestContext for use by Spring's macro library, under the + * name "springMacroRequestContext". + */ + private boolean exposeSpringMacroHelpers = true; + + /** + * Whether HttpSession attributes are allowed to override (hide) controller generated + * model attributes of the same name. + */ + private boolean allowSessionOverride = false; + + /** + * Whether models that are assignable to CharSequence are escaped automatically. + */ + private boolean autoEscape; + + /** + * Whether indents are rendered automatically. + */ + private boolean autoIndent; + + /** + * String used for auto-indents. + */ + private String autoIndentString; + + /** + * Whether new lines are rendered automatically. + */ + private boolean autoNewLine; + + /** + * Template base class. + */ + private Class baseTemplateClass = BaseTemplate.class; + + /** + * Encoding used to write the declaration heading. + */ + private String declarationEncoding; + + /** + * Whether elements without a body should be written expanded (<br></br>) + * or not (<br/>). + */ + private boolean expandEmptyElements; + + /** + * Default locale for template resolution. + */ + private Locale locale; + + /** + * String used to write a new line. Defaults to the system's line separator. + */ + private String newLineString; + + /** + * Template path. + */ + private String resourceLoaderPath = DEFAULT_RESOURCE_LOADER_PATH; + + /** + * Whether attributes should use double quotes. + */ + private boolean useDoubleQuotes; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isCheckTemplateLocation() { + return this.checkTemplateLocation; + } + + public void setCheckTemplateLocation(boolean checkTemplateLocation) { + this.checkTemplateLocation = checkTemplateLocation; + } + + public String[] getViewNames() { + return this.viewNames; + } + + public void setViewNames(String[] viewNames) { + this.viewNames = viewNames; + } + + public boolean isCache() { + return this.cache; + } + + public void setCache(boolean cache) { + this.cache = cache; + } + + public MimeType getContentType() { + if (this.contentType.getCharset() == null) { + Map parameters = new LinkedHashMap<>(); + parameters.put("charset", this.charset.name()); + parameters.putAll(this.contentType.getParameters()); + return new MimeType(this.contentType, parameters); + } + return this.contentType; + } + + public void setContentType(MimeType contentType) { + this.contentType = contentType; + } + + public Charset getCharset() { + return this.charset; + } + + public String getCharsetName() { + return (this.charset != null) ? this.charset.name() : null; + } + + public void setCharset(Charset charset) { + this.charset = charset; + } + + public boolean isAutoEscape() { + return this.autoEscape; + } + + public void setAutoEscape(boolean autoEscape) { + this.autoEscape = autoEscape; + } + + public boolean isAutoIndent() { + return this.autoIndent; + } + + public void setAutoIndent(boolean autoIndent) { + this.autoIndent = autoIndent; + } + + public String getAutoIndentString() { + return this.autoIndentString; + } + + public void setAutoIndentString(String autoIndentString) { + this.autoIndentString = autoIndentString; + } + + public boolean isAutoNewLine() { + return this.autoNewLine; + } + + public void setAutoNewLine(boolean autoNewLine) { + this.autoNewLine = autoNewLine; + } + + public Class getBaseTemplateClass() { + return this.baseTemplateClass; + } + + public void setBaseTemplateClass(Class baseTemplateClass) { + this.baseTemplateClass = baseTemplateClass; + } + + public String getDeclarationEncoding() { + return this.declarationEncoding; + } + + public void setDeclarationEncoding(String declarationEncoding) { + this.declarationEncoding = declarationEncoding; + } + + public boolean isExpandEmptyElements() { + return this.expandEmptyElements; + } + + public void setExpandEmptyElements(boolean expandEmptyElements) { + this.expandEmptyElements = expandEmptyElements; + } + + public Locale getLocale() { + return this.locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + public String getNewLineString() { + return this.newLineString; + } + + public void setNewLineString(String newLineString) { + this.newLineString = newLineString; + } + + public String getResourceLoaderPath() { + return this.resourceLoaderPath; + } + + public void setResourceLoaderPath(String resourceLoaderPath) { + this.resourceLoaderPath = resourceLoaderPath; + } + + public boolean isUseDoubleQuotes() { + return this.useDoubleQuotes; + } + + public void setUseDoubleQuotes(boolean useDoubleQuotes) { + this.useDoubleQuotes = useDoubleQuotes; + } + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return this.suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public String getRequestContextAttribute() { + return this.requestContextAttribute; + } + + public void setRequestContextAttribute(String requestContextAttribute) { + this.requestContextAttribute = requestContextAttribute; + } + + public boolean isExposeRequestAttributes() { + return this.exposeRequestAttributes; + } + + public void setExposeRequestAttributes(boolean exposeRequestAttributes) { + this.exposeRequestAttributes = exposeRequestAttributes; + } + + public boolean isExposeSessionAttributes() { + return this.exposeSessionAttributes; + } + + public void setExposeSessionAttributes(boolean exposeSessionAttributes) { + this.exposeSessionAttributes = exposeSessionAttributes; + } + + public boolean isAllowRequestOverride() { + return this.allowRequestOverride; + } + + public void setAllowRequestOverride(boolean allowRequestOverride) { + this.allowRequestOverride = allowRequestOverride; + } + + public boolean isAllowSessionOverride() { + return this.allowSessionOverride; + } + + public void setAllowSessionOverride(boolean allowSessionOverride) { + this.allowSessionOverride = allowSessionOverride; + } + + public boolean isExposeSpringMacroHelpers() { + return this.exposeSpringMacroHelpers; + } + + public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) { + this.exposeSpringMacroHelpers = exposeSpringMacroHelpers; + } + + /** + * Apply the given properties to a {@link AbstractTemplateViewResolver}. Use Object in + * signature to avoid runtime dependency on MVC, which means that the template engine + * can be used in a non-web application. + * @param viewResolver the resolver to apply the properties to. + */ + public void applyToMvcViewResolver(Object viewResolver) { + Assert.isInstanceOf(AbstractTemplateViewResolver.class, viewResolver, + () -> "ViewResolver is not an instance of AbstractTemplateViewResolver :" + viewResolver); + AbstractTemplateViewResolver resolver = (AbstractTemplateViewResolver) viewResolver; + resolver.setPrefix(getPrefix()); + resolver.setSuffix(getSuffix()); + resolver.setCache(isCache()); + if (getContentType() != null) { + resolver.setContentType(getContentType().toString()); + } + resolver.setViewNames(getViewNames()); + resolver.setExposeRequestAttributes(isExposeRequestAttributes()); + resolver.setAllowRequestOverride(isAllowRequestOverride()); + resolver.setAllowSessionOverride(isAllowSessionOverride()); + resolver.setExposeSessionAttributes(isExposeSessionAttributes()); + resolver.setExposeSpringMacroHelpers(isExposeSpringMacroHelpers()); + resolver.setRequestContextAttribute(getRequestContextAttribute()); + // The resolver usually acts as a fallback resolver (e.g. like a + // InternalResourceViewResolver) so it needs to have low precedence + resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5); + } + +} diff --git a/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/package-info.java b/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/package-info.java new file mode 100644 index 000000000000..ad65a8e623b7 --- /dev/null +++ b/spring-boot-project/spring-boot-groovy-templates/src/main/java/org/springframework/boot/groovy/template/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Groovy templates. + */ +package org.springframework.boot.groovy.template.autoconfigure; diff --git a/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..8941721d7bea --- /dev/null +++ b/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,108 @@ +{ + "properties": [ + { + "name": "spring.groovy.template.configuration.auto-escape", + "deprecation": { + "replacement": "spring.groovy.template.auto-escape", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.auto-indent", + "deprecation": { + "replacement": "spring.groovy.template.auto-indent", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.auto-indent-string", + "deprecation": { + "replacement": "spring.groovy.template.auto-indent-string", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.auto-new-line", + "deprecation": { + "replacement": "spring.groovy.template.auto-new-line", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.base-template-class", + "deprecation": { + "replacement": "spring.groovy.template.base-template-class", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.cache-templates", + "deprecation": { + "replacement": "spring.groovy.template.cache", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.declaration-encoding", + "deprecation": { + "replacement": "spring.groovy.template.declaration-encoding", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.expand-empty-elements", + "deprecation": { + "replacement": "spring.groovy.template.expand-empty-elements", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.locale", + "deprecation": { + "replacement": "spring.groovy.template.locale", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.new-line-string", + "deprecation": { + "replacement": "spring.groovy.template.new-line-string", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.resource-loader-path", + "deprecation": { + "replacement": "spring.groovy.template.resource-loader-path", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.configuration.use-double-quotes", + "deprecation": { + "replacement": "spring.groovy.template.use-double-quotes", + "level": "warning", + "since": "3.5.0" + } + }, + { + "name": "spring.groovy.template.prefix", + "defaultValue": "" + }, + { + "name": "spring.groovy.template.suffix", + "defaultValue": ".tpl" + } + ] +} diff --git a/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..27bc1e17f876 --- /dev/null +++ b/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Template Availability Providers +org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ +org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAvailabilityProvider diff --git a/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..70997c536cfc --- /dev/null +++ b/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAvailabilityProvider$GroovyTemplateAvailabilityRuntimeHints diff --git a/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..ec807a494e25 --- /dev/null +++ b/spring-boot-project/spring-boot-groovy-templates/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfigurationTests.java b/spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfigurationTests.java rename to spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAutoConfigurationTests.java index 159161a008a4..d49ead10108c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.groovy.template; +package org.springframework.boot.groovy.template.autoconfigure; import java.io.File; import java.io.StringWriter; @@ -35,7 +35,7 @@ import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.testsupport.BuildOutput; import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.io.ClassPathResource; import org.springframework.mock.web.MockHttpServletRequest; @@ -187,13 +187,6 @@ void renderTemplate() throws Exception { assertThat(writer.toString()).contains("Hello World"); } - @Test - @Deprecated(since = "3.5.0", forRemoval = true) - void customConfiguration() { - registerAndRefreshContext("spring.groovy.template.configuration.auto-indent:true"); - assertThat(this.context.getBean(GroovyMarkupConfigurer.class).isAutoIndent()).isTrue(); - } - @Test void enableAutoEscape() { registerAndRefreshContext("spring.groovy.template.auto-escape:true"); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java b/spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAvailabilityProviderTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java rename to spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAvailabilityProviderTests.java index 751c63e1b7ea..33e912e78bee 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/groovy/template/GroovyTemplateAvailabilityProviderTests.java +++ b/spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplateAvailabilityProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.groovy.template; +package org.springframework.boot.groovy.template.autoconfigure; import org.junit.jupiter.api.Test; @@ -22,9 +22,9 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.TypeHint; import org.springframework.beans.factory.aot.AotServices; -import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityProperties; -import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityRuntimeHints; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; +import org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityProperties; +import org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAvailabilityProvider.GroovyTemplateAvailabilityRuntimeHints; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; diff --git a/spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplatePropertiesTests.java b/spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplatePropertiesTests.java new file mode 100644 index 000000000000..841b3f4e2072 --- /dev/null +++ b/spring-boot-project/spring-boot-groovy-templates/src/test/java/org/springframework/boot/groovy/template/autoconfigure/GroovyTemplatePropertiesTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.groovy.template.autoconfigure; + +import java.nio.charset.StandardCharsets; + +import org.junit.jupiter.api.Test; + +import org.springframework.util.MimeTypeUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link GroovyTemplateProperties}. + * + * @author Stephane Nicoll + */ +class GroovyTemplatePropertiesTests { + + @Test + void defaultContentType() { + assertThat(new GroovyTemplateProperties().getContentType()).hasToString("text/html;charset=UTF-8"); + } + + @Test + void customContentTypeDefaultCharset() { + GroovyTemplateProperties properties = new GroovyTemplateProperties(); + properties.setContentType(MimeTypeUtils.parseMimeType("text/plain")); + assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-8"); + } + + @Test + void defaultContentTypeCustomCharset() { + GroovyTemplateProperties properties = new GroovyTemplateProperties(); + properties.setCharset(StandardCharsets.UTF_16); + assertThat(properties.getContentType()).hasToString("text/html;charset=UTF-16"); + } + + @Test + void customContentTypeCustomCharset() { + GroovyTemplateProperties properties = new GroovyTemplateProperties(); + properties.setContentType(MimeTypeUtils.parseMimeType("text/plain")); + properties.setCharset(StandardCharsets.UTF_16); + assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16"); + } + + @Test + void customContentTypeWithPropertyAndCustomCharset() { + GroovyTemplateProperties properties = new GroovyTemplateProperties(); + properties.setContentType(MimeTypeUtils.parseMimeType("text/plain;foo=bar")); + properties.setCharset(StandardCharsets.UTF_16); + assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16;foo=bar"); + } + +} diff --git a/spring-boot-project/spring-boot-gson/build.gradle b/spring-boot-project/spring-boot-gson/build.gradle new file mode 100644 index 000000000000..591a833aaa4a --- /dev/null +++ b/spring-boot-project/spring-boot-gson/build.gradle @@ -0,0 +1,38 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot GSON" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("com.google.code.gson:gson") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfiguration.java b/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonAutoConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfiguration.java rename to spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonAutoConfiguration.java index 55571ab6c390..da57ff143b6c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfiguration.java +++ b/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.gson; +package org.springframework.boot.gson.autoconfigure; import java.util.List; import java.util.function.Consumer; @@ -38,7 +38,7 @@ * * @author David Liu * @author Ivan Golovko - * @since 1.2.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(Gson.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonBuilderCustomizer.java b/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonBuilderCustomizer.java rename to spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonBuilderCustomizer.java index 8ed3075329f8..8d141f7158c4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.gson; +package org.springframework.boot.gson.autoconfigure; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -24,7 +24,7 @@ * {@link Gson} through {@link GsonBuilder} retaining its default auto-configuration. * * @author Ivan Golovko - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface GsonBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonProperties.java b/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonProperties.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonProperties.java rename to spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonProperties.java index aeb0c6cdb912..b8d073144da4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/gson/GsonProperties.java +++ b/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/GsonProperties.java @@ -14,20 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.gson; +package org.springframework.boot.gson.autoconfigure; import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.LongSerializationPolicy; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; /** * Configuration properties to configure {@link Gson}. * * @author Ivan Golovko - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.gson") public class GsonProperties { @@ -163,12 +162,6 @@ public void setStrictness(Strictness strictness) { this.strictness = strictness; } - @Deprecated(since = "3.4.0", forRemoval = true) - @DeprecatedConfigurationProperty(replacement = "spring.gson.strictness", since = "3.4.0") - public Boolean getLenient() { - return (this.strictness != null) && (this.strictness == Strictness.LENIENT); - } - public void setLenient(Boolean lenient) { setStrictness((lenient != null && lenient) ? Strictness.LENIENT : Strictness.STRICT); } @@ -193,8 +186,6 @@ public void setDateFormat(String dateFormat) { * Enumeration of levels of strictness. Values are the same as those on * {@link com.google.gson.Strictness} that was introduced in Gson 2.11. To maximize * backwards compatibility, the Gson enum is not used directly. - * - * @since 3.4.2 */ public enum Strictness { diff --git a/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/package-info.java b/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/package-info.java new file mode 100644 index 000000000000..0097b1fe5df0 --- /dev/null +++ b/spring-boot-project/spring-boot-gson/src/main/java/org/springframework/boot/gson/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for GSON. + */ +package org.springframework.boot.gson.autoconfigure; diff --git a/spring-boot-project/spring-boot-gson/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-gson/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..c199343e46ca --- /dev/null +++ b/spring-boot-project/spring-boot-gson/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,13 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.gson.lenient", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.gson.strictness", + "since": "3.4.0" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-gson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-gson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..4a29fa16875c --- /dev/null +++ b/spring-boot-project/spring-boot-gson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.gson.autoconfigure.GsonAutoConfiguration diff --git a/spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/Gson210AutoConfigurationTests.java b/spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/Gson210AutoConfigurationTests.java new file mode 100644 index 000000000000..dc71a89ece25 --- /dev/null +++ b/spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/Gson210AutoConfigurationTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.gson.autoconfigure; + +import com.google.gson.Gson; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.classpath.ClassPathExclusions; +import org.springframework.boot.testsupport.classpath.ClassPathOverrides; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link GsonAutoConfiguration} with Gson 2.10. + * + * @author Andy Wilkinson + */ +@ClassPathExclusions("gson-*.jar") +@ClassPathOverrides("com.google.code.gson:gson:2.10") +class Gson210AutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(GsonAutoConfiguration.class)); + + @Test + void gsonRegistration() { + this.contextRunner.run((context) -> { + Gson gson = context.getBean(Gson.class); + assertThat(gson.toJson(new DataObject())).isEqualTo("{\"data\":1}"); + }); + } + + public class DataObject { + + @SuppressWarnings("unused") + private Long data = 1L; + + @SuppressWarnings("unused") + private final String owner = null; + + public void setData(Long data) { + this.data = data; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java b/spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/GsonAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java rename to spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/GsonAutoConfigurationTests.java index 97ee163aca70..5018853726d6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/GsonAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.gson; +package org.springframework.boot.gson.autoconfigure; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -209,33 +209,6 @@ void withPrettyPrintingFalse() { }); } - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void withoutLenient() { - this.contextRunner.run((context) -> { - Gson gson = context.getBean(Gson.class); - assertThat(gson).hasFieldOrPropertyWithValue("strictness", null); - }); - } - - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void withLenientTrue() { - this.contextRunner.withPropertyValues("spring.gson.lenient:true").run((context) -> { - Gson gson = context.getBean(Gson.class); - assertThat(gson).hasFieldOrPropertyWithValue("strictness", Strictness.LENIENT); - }); - } - - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void withLenientFalse() { - this.contextRunner.withPropertyValues("spring.gson.lenient:false").run((context) -> { - Gson gson = context.getBean(Gson.class); - assertThat(gson).hasFieldOrPropertyWithValue("strictness", Strictness.STRICT); - }); - } - @Test void withoutStrictness() { this.contextRunner.run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonPropertiesTests.java b/spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/GsonPropertiesTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonPropertiesTests.java rename to spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/GsonPropertiesTests.java index 5f4f9709804a..6397f5ced850 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonPropertiesTests.java +++ b/spring-boot-project/spring-boot-gson/src/test/java/org/springframework/boot/gson/autoconfigure/GsonPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.gson; +package org.springframework.boot.gson.autoconfigure; import java.util.List; import java.util.stream.Stream; diff --git a/spring-boot-project/spring-boot-h2console/build.gradle b/spring-boot-project/spring-boot-h2console/build.gradle new file mode 100644 index 000000000000..bb3510d62657 --- /dev/null +++ b/spring-boot-project/spring-boot-h2console/build.gradle @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot H2" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("jakarta.servlet:jakarta.servlet-api") + api("com.h2database:h2") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-jdbc")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation("org.springframework:spring-web") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.java b/spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.java rename to spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleAutoConfiguration.java index b4c2e719b867..77b19d6f6abd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.java +++ b/spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.h2; +package org.springframework.boot.h2console.autoconfigure; import java.sql.Connection; import java.util.List; @@ -33,9 +33,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.h2.H2ConsoleProperties.Settings; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.h2console.autoconfigure.H2ConsoleProperties.Settings; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.core.log.LogMessage; @@ -47,9 +46,9 @@ * @author Marten Deinum * @author Stephane Nicoll * @author Phillip Webb - * @since 1.3.0 + * @since 4.0.0 */ -@AutoConfiguration(after = DataSourceAutoConfiguration.class) +@AutoConfiguration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass(JakartaWebServlet.class) @ConditionalOnBooleanProperty("spring.h2.console.enabled") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleProperties.java b/spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleProperties.java rename to spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleProperties.java index c8e76d37b2db..5244a2a5b2c2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleProperties.java +++ b/spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.h2; +package org.springframework.boot.h2console.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.Assert; @@ -25,7 +25,7 @@ * @author Andy Wilkinson * @author Marten Deinum * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.h2.console") public class H2ConsoleProperties { diff --git a/spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/package-info.java b/spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/package-info.java new file mode 100644 index 000000000000..2b77c897be1f --- /dev/null +++ b/spring-boot-project/spring-boot-h2console/src/main/java/org/springframework/boot/h2console/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for H2's Console. + */ +package org.springframework.boot.h2console.autoconfigure; diff --git a/spring-boot-project/spring-boot-h2console/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-h2console/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..9856b070c6f9 --- /dev/null +++ b/spring-boot-project/spring-boot-h2console/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.h2console.autoconfigure.H2ConsoleAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfigurationTests.java b/spring-boot-project/spring-boot-h2console/src/test/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfigurationTests.java rename to spring-boot-project/spring-boot-h2console/src/test/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleAutoConfigurationTests.java index bc57d71e01d0..01cf538ef2f4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-h2console/src/test/java/org/springframework/boot/h2console/autoconfigure/H2ConsoleAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.h2; +package org.springframework.boot.h2console.autoconfigure; import java.net.URL; import java.net.URLClassLoader; @@ -29,15 +29,15 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationPropertiesBindException; import org.springframework.boot.context.properties.bind.BindException; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -185,7 +185,7 @@ void h2ConsoleShouldNotFailIfDatabaseConnectionFails() { void dataSourceIsNotInitializedEarly(CapturedOutput output) { new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(H2ConsoleAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + TomcatServletWebServerAutoConfiguration.class)) .withUserConfiguration(EarlyInitializationConfiguration.class) .withPropertyValues("spring.h2.console.enabled=true", "server.port=0") .run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/h2/H2ConsolePropertiesTests.java b/spring-boot-project/spring-boot-h2console/src/test/java/org/springframework/boot/h2console/autoconfigure/H2ConsolePropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/h2/H2ConsolePropertiesTests.java rename to spring-boot-project/spring-boot-h2console/src/test/java/org/springframework/boot/h2console/autoconfigure/H2ConsolePropertiesTests.java index c3a350b57017..ae204e914ba9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/h2/H2ConsolePropertiesTests.java +++ b/spring-boot-project/spring-boot-h2console/src/test/java/org/springframework/boot/h2console/autoconfigure/H2ConsolePropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.h2; +package org.springframework.boot.h2console.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-hateoas/build.gradle b/spring-boot-project/spring-boot-hateoas/build.gradle new file mode 100644 index 000000000000..b83237f92ceb --- /dev/null +++ b/spring-boot-project/spring-boot-hateoas/build.gradle @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Hateoas" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.hateoas:spring-hateoas") + + implementation("com.fasterxml.jackson.core:jackson-databind") + implementation("org.springframework:spring-webmvc") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("jakarta.servlet:jakarta.servlet-api") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HateoasProperties.java b/spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/HateoasProperties.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HateoasProperties.java rename to spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/HateoasProperties.java index 8a0caf12d844..8a29736bdcf1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HateoasProperties.java +++ b/spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/HateoasProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hateoas; +package org.springframework.boot.hateoas.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -23,7 +23,7 @@ * * @author Phillip Webb * @author Andy Wilkinson - * @since 1.2.1 + * @since 4.0.0 */ @ConfigurationProperties("spring.hateoas") public class HateoasProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java b/spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfiguration.java similarity index 77% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java rename to spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfiguration.java index 9d46cf34d9be..f177d2dcf771 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hateoas; +package org.springframework.boot.hateoas.autoconfigure; import com.fasterxml.jackson.databind.ObjectMapper; @@ -24,10 +24,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -48,18 +44,17 @@ * @author Roy Clarkson * @author Oliver Gierke * @author Andy Wilkinson - * @since 1.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { WebMvcAutoConfiguration.class, JacksonAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class }) -@ConditionalOnClass({ EntityModel.class, RequestMapping.class, RequestMappingHandlerAdapter.class, Plugin.class }) +@AutoConfiguration +@ConditionalOnClass({ EntityModel.class, RequestMapping.class, RequestMappingHandlerAdapter.class, Plugin.class, + ObjectMapper.class }) @ConditionalOnWebApplication @EnableConfigurationProperties(HateoasProperties.class) public class HypermediaAutoConfiguration { @Bean @ConditionalOnMissingBean - @ConditionalOnClass(name = "com.fasterxml.jackson.databind.ObjectMapper") @ConditionalOnBooleanProperty(name = "spring.hateoas.use-hal-as-default-json-media-type", matchIfMissing = true) HalConfiguration applicationJsonHalConfiguration() { return new HalConfiguration().withMediaType(MediaType.APPLICATION_JSON); @@ -67,9 +62,8 @@ HalConfiguration applicationJsonHalConfiguration() { @Configuration(proxyBeanMethods = false) @ConditionalOnMissingBean(LinkDiscoverers.class) - @ConditionalOnClass(ObjectMapper.class) @EnableHypermediaSupport(type = HypermediaType.HAL) - protected static class HypermediaConfiguration { + static class HypermediaConfiguration { } diff --git a/spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/package-info.java b/spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/package-info.java new file mode 100644 index 000000000000..01569069b04d --- /dev/null +++ b/spring-boot-project/spring-boot-hateoas/src/main/java/org/springframework/boot/hateoas/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring HATEOAS. + */ +package org.springframework.boot.hateoas.autoconfigure; diff --git a/spring-boot-project/spring-boot-hateoas/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-hateoas/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-hateoas/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-hateoas/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-hateoas/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..71e83fadd8fc --- /dev/null +++ b/spring-boot-project/spring-boot-hateoas/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.hateoas.autoconfigure.HypermediaAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java b/spring-boot-project/spring-boot-hateoas/src/test/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfigurationTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java rename to spring-boot-project/spring-boot-hateoas/src/test/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfigurationTests.java index 06e198e87241..ca69fa93fc83 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-hateoas/src/test/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfigurationTests.java @@ -14,17 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hateoas; +package org.springframework.boot.hateoas.autoconfigure; import java.util.Optional; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration.HypermediaConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.hateoas.autoconfigure.HypermediaAutoConfiguration.HypermediaConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Configuration; @@ -38,6 +35,7 @@ import org.springframework.hateoas.server.EntityLinks; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import static org.assertj.core.api.Assertions.assertThat; @@ -117,8 +115,8 @@ void whenHalIsNotTheDefaultJsonMediaTypeThenMappingJacksonConverterCannotWriteHa }); } - @ImportAutoConfiguration({ HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class, - JacksonAutoConfiguration.class, HypermediaAutoConfiguration.class }) + @EnableWebMvc + @ImportAutoConfiguration(HypermediaAutoConfiguration.class) static class BaseConfig { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationWithoutJacksonTests.java b/spring-boot-project/spring-boot-hateoas/src/test/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfigurationWithoutJacksonTests.java similarity index 77% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationWithoutJacksonTests.java rename to spring-boot-project/spring-boot-hateoas/src/test/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfigurationWithoutJacksonTests.java index 5aa342c57cf9..dd31f23e3247 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationWithoutJacksonTests.java +++ b/spring-boot-project/spring-boot-hateoas/src/test/java/org/springframework/boot/hateoas/autoconfigure/HypermediaAutoConfigurationWithoutJacksonTests.java @@ -14,15 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hateoas; +package org.springframework.boot.hateoas.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.mock.web.MockServletContext; /** @@ -43,8 +41,7 @@ void jacksonRelatedConfigurationBacksOff() { this.context.refresh(); } - @ImportAutoConfiguration({ HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class, - HypermediaAutoConfiguration.class }) + @ImportAutoConfiguration(HypermediaAutoConfiguration.class) static class BaseConfig { } diff --git a/spring-boot-project/spring-boot-hazelcast/build.gradle b/spring-boot-project/spring-boot-hazelcast/build.gradle new file mode 100644 index 000000000000..1253e79c43fc --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/build.gradle @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Hazelcast" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("com.hazelcast:hazelcast") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-hibernate")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("com.hazelcast:hazelcast-spring") + optional("org.slf4j:slf4j-api") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-hibernate")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-testcontainers"))) + + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/docker/compose/HazelcastDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/docker/compose/HazelcastDockerComposeConnectionDetailsFactoryIntegrationTests.java index 5e8796e33a17..6f1b26be8b54 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/docker/compose/HazelcastDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.hazelcast; +package org.springframework.boot.hazelcast.docker.compose; import java.util.UUID; @@ -24,8 +24,8 @@ import com.hazelcast.core.HazelcastInstance; import com.hazelcast.map.IMap; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/hazelcast/CustomClusterNameHazelcastContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/testcontainers/CustomClusterNameHazelcastContainerConnectionDetailsFactoryIntegrationTests.java similarity index 93% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/hazelcast/CustomClusterNameHazelcastContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/testcontainers/CustomClusterNameHazelcastContainerConnectionDetailsFactoryIntegrationTests.java index 39db9b25a718..373fba1f3651 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/hazelcast/CustomClusterNameHazelcastContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/testcontainers/CustomClusterNameHazelcastContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.hazelcast; +package org.springframework.boot.hazelcast.testcontainers; import java.util.UUID; import java.util.function.Consumer; @@ -29,8 +29,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.HazelcastContainer; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactoryIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactoryIntegrationTests.java index cd3dcdd2ffd0..202bff956963 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.hazelcast; +package org.springframework.boot.hazelcast.testcontainers; import java.util.UUID; @@ -26,8 +26,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.HazelcastContainer; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/hazelcast/hazelcast-cluster-name-compose.yaml b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/org/springframework/boot/hazelcast/docker/compose/hazelcast-cluster-name-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/hazelcast/hazelcast-cluster-name-compose.yaml rename to spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/org/springframework/boot/hazelcast/docker/compose/hazelcast-cluster-name-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/hazelcast/hazelcast-compose.yaml b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/org/springframework/boot/hazelcast/docker/compose/hazelcast-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/hazelcast/hazelcast-compose.yaml rename to spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/org/springframework/boot/hazelcast/docker/compose/hazelcast-compose.yaml diff --git a/spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfiguration.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfiguration.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfiguration.java index 56e54ece11bc..4477ee2c467b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfiguration.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import com.hazelcast.core.HazelcastInstance; @@ -31,7 +31,7 @@ * * @author Stephane Nicoll * @author Vedran Pavic - * @since 1.3.0 + * @since 4.0.0 * @see HazelcastConfigResourceCondition */ @AutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfigAvailableCondition.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfigAvailableCondition.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfigAvailableCondition.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfigAvailableCondition.java index f91b5aeb79ae..6f3ca62e7e30 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfigAvailableCondition.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfigAvailableCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import java.io.IOException; import java.io.InputStream; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfiguration.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfiguration.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfiguration.java index 5afd2c13a9ba..ef27d2642e59 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfiguration.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import com.hazelcast.client.HazelcastClient; import com.hazelcast.core.HazelcastInstance; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientInstanceConfiguration.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientInstanceConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientInstanceConfiguration.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientInstanceConfiguration.java index 814c36f2c39c..7c58ff9a2a3c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientInstanceConfiguration.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientInstanceConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import com.hazelcast.client.HazelcastClient; import com.hazelcast.client.config.ClientConfig; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConfigCustomizer.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConfigCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConfigCustomizer.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConfigCustomizer.java index ecfbb7d6e967..7b0b2ab6c5c1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConfigCustomizer.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConfigCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import com.hazelcast.config.Config; @@ -24,7 +24,7 @@ * * @author Jaromir Hamala * @author Stephane Nicoll - * @since 2.7.0 + * @since 4.0.0 */ @FunctionalInterface public interface HazelcastConfigCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConfigResourceCondition.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConfigResourceCondition.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConfigResourceCondition.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConfigResourceCondition.java index 2b8a09c3d1bd..8ffc22fad295 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConfigResourceCondition.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConfigResourceCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.ResourceCondition; @@ -31,7 +31,7 @@ * @author Stephane Nicoll * @author Madhura Bhave * @author Vedran Pavic - * @since 1.3.0 + * @since 4.0.0 */ public abstract class HazelcastConfigResourceCondition extends ResourceCondition { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConnectionDetails.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConnectionDetails.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConnectionDetails.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConnectionDetails.java index b18e7d147270..200e7a2ee3fb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConnectionDetails.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import com.hazelcast.client.config.ClientConfig; @@ -24,7 +24,7 @@ * Details required to establish a client connection to a Hazelcast instance. * * @author Dmytro Nosan - * @since 3.4.0 + * @since 4.0.0 */ public interface HazelcastConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConnectionDetailsConfiguration.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConnectionDetailsConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConnectionDetailsConfiguration.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConnectionDetailsConfiguration.java index ed7654e56510..05bcdf1bf8b8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastConnectionDetailsConfiguration.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastConnectionDetailsConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import com.hazelcast.client.config.ClientConfig; diff --git a/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastJpaDependencyAutoConfiguration.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastJpaDependencyAutoConfiguration.java new file mode 100644 index 000000000000..2b49cd82876e --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastJpaDependencyAutoConfiguration.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.hazelcast.autoconfigure; + +import com.hazelcast.core.HazelcastInstance; +import jakarta.persistence.EntityManagerFactory; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.AllNestedConditions; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastJpaDependencyAutoConfiguration.HazelcastInstanceEntityManagerFactoryDependsOnConfiguration; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryDependsOnPostProcessor; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; + +/** + * Additional configuration to ensure that {@link EntityManagerFactory} beans depend on + * the {@code hazelcastInstance} bean. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration(after = HazelcastAutoConfiguration.class, + afterName = "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration") +@ConditionalOnClass({ HazelcastInstance.class, LocalContainerEntityManagerFactoryBean.class }) +@Import(HazelcastInstanceEntityManagerFactoryDependsOnConfiguration.class) +public class HazelcastJpaDependencyAutoConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(EntityManagerFactoryDependsOnPostProcessor.class) + @Conditional(OnHazelcastAndJpaCondition.class) + @Import(HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor.class) + static class HazelcastInstanceEntityManagerFactoryDependsOnConfiguration { + + } + + static class HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor + extends EntityManagerFactoryDependsOnPostProcessor { + + HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor() { + super("hazelcastInstance"); + } + + } + + static class OnHazelcastAndJpaCondition extends AllNestedConditions { + + OnHazelcastAndJpaCondition() { + super(ConfigurationPhase.REGISTER_BEAN); + } + + @ConditionalOnBean(name = "hazelcastInstance") + static class HasHazelcastInstance { + + } + + @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) + static class HasJpa { + + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastProperties.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastProperties.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastProperties.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastProperties.java index 208de1fc7d14..f84e2d78ac4f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastProperties.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.io.Resource; @@ -24,7 +24,7 @@ * Configuration properties for the hazelcast integration. * * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.hazelcast") public class HazelcastProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastServerConfiguration.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastServerConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastServerConfiguration.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastServerConfiguration.java index e1fc883ce6aa..94e01d155af7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastServerConfiguration.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastServerConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import java.io.IOException; import java.io.InputStream; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/PropertiesHazelcastConnectionDetails.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/PropertiesHazelcastConnectionDetails.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/PropertiesHazelcastConnectionDetails.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/PropertiesHazelcastConnectionDetails.java index 133c472075c7..6c4c23a144c6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/PropertiesHazelcastConnectionDetails.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/PropertiesHazelcastConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfiguration.java similarity index 77% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfiguration.java index 7441b498bc07..705a51706dad 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfiguration.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure.health; import com.hazelcast.core.HazelcastInstance; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.hazelcast.HazelcastHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.health.HazelcastHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; import org.springframework.context.annotation.Bean; /** @@ -36,10 +36,10 @@ * {@link HazelcastHealthIndicator}. * * @author Dmytro Nosan - * @since 2.2.0 + * @since 4.0.0 */ @AutoConfiguration(after = HazelcastAutoConfiguration.class) -@ConditionalOnClass(HazelcastInstance.class) +@ConditionalOnClass({ HazelcastInstance.class, ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(HazelcastInstance.class) @ConditionalOnEnabledHealthIndicator("hazelcast") public class HazelcastHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..3394f8ece1d9 --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Hazelcast health. + */ +package org.springframework.boot.hazelcast.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/package-info.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/package-info.java new file mode 100644 index 000000000000..115a4bd8a7e1 --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Hazelcast. + */ +package org.springframework.boot.hazelcast.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/HazelcastDockerComposeConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/HazelcastDockerComposeConnectionDetailsFactory.java index 5f7df5c7d5a3..2197f747ba90 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/HazelcastDockerComposeConnectionDetailsFactory.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.hazelcast; +package org.springframework.boot.hazelcast.docker.compose; import com.hazelcast.client.config.ClientConfig; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastEnvironment.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/HazelcastEnvironment.java similarity index 92% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastEnvironment.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/HazelcastEnvironment.java index 7d48fdb017f4..c4b8de9d8a46 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastEnvironment.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/HazelcastEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.hazelcast; +package org.springframework.boot.hazelcast.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/package-info.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/package-info.java new file mode 100644 index 000000000000..56ac991268bf --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Hazelcast service connections. + */ +package org.springframework.boot.hazelcast.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/health/HazelcastHealthIndicator.java similarity index 84% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/health/HazelcastHealthIndicator.java index 4cc113df4f8c..a415259cafa1 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/health/HazelcastHealthIndicator.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.hazelcast; +package org.springframework.boot.hazelcast.health; import com.hazelcast.core.HazelcastInstance; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.util.Assert; /** @@ -28,7 +28,7 @@ * * @author Dmytro Nosan * @author Stephane Nicoll - * @since 2.2.0 + * @since 4.0.0 */ public class HazelcastHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/health/package-info.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/health/package-info.java new file mode 100644 index 000000000000..c53637913d94 --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for Hazelcast. + */ +package org.springframework.boot.hazelcast.health; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactory.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactory.java index 811db195865c..33e43c38df4c 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.hazelcast; +package org.springframework.boot.hazelcast.testcontainers; import java.util.Map; @@ -22,7 +22,7 @@ import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastConnectionDetails; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/testcontainers/package-info.java b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/testcontainers/package-info.java new file mode 100644 index 000000000000..ce4dd1610333 --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/main/java/org/springframework/boot/hazelcast/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Hazelcast service connections. + */ +package org.springframework.boot.hazelcast.testcontainers; diff --git a/spring-boot-project/spring-boot-hazelcast/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-hazelcast/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..ead7e6d5961b --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.hazelcast.docker.compose.HazelcastDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.hazelcast.testcontainers.HazelcastContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-hazelcast/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-hazelcast/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..2397606790ce --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration +org.springframework.boot.hazelcast.autoconfigure.HazelcastJpaDependencyAutoConfiguration +org.springframework.boot.hazelcast.autoconfigure.health.HazelcastHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationClientTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationClientTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationClientTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationClientTests.java index 8ff66a3b18d7..f9c6331f0da2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationClientTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationClientTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import java.io.File; import java.io.FileReader; @@ -87,7 +87,7 @@ static void close() { @Test void systemPropertyWithXml() { File config = prepareConfiguration("src/test/resources/org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-client-specific.xml"); + + "boot/hazelcast/autoconfigure/hazelcast-client-specific.xml"); this.contextRunner .withSystemProperties(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY + "=" + config.getAbsolutePath()) .run(assertSpecificHazelcastClient("explicit-xml")); @@ -96,7 +96,7 @@ void systemPropertyWithXml() { @Test void systemPropertyWithYaml() { File config = prepareConfiguration("src/test/resources/org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-client-specific.yaml"); + + "boot/hazelcast/autoconfigure/hazelcast-client-specific.yaml"); this.contextRunner .withSystemProperties(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY + "=" + config.getAbsolutePath()) .run(assertSpecificHazelcastClient("explicit-yaml")); @@ -105,7 +105,7 @@ void systemPropertyWithYaml() { @Test void systemPropertyWithYml() { File config = prepareConfiguration("src/test/resources/org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-client-specific.yml"); + + "boot/hazelcast/autoconfigure/hazelcast-client-specific.yml"); this.contextRunner .withSystemProperties(HazelcastClientConfiguration.CONFIG_SYSTEM_PROPERTY + "=" + config.getAbsolutePath()) .run(assertSpecificHazelcastClient("explicit-yml")); @@ -114,7 +114,7 @@ void systemPropertyWithYml() { @Test void explicitConfigUrlWithXml() throws MalformedURLException { File config = prepareConfiguration("src/test/resources/org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-client-specific.xml"); + + "boot/hazelcast/autoconfigure/hazelcast-client-specific.xml"); this.contextRunner.withPropertyValues("spring.hazelcast.config=" + config.toURI().toURL()) .run(assertSpecificHazelcastClient("explicit-xml")); } @@ -122,7 +122,7 @@ void explicitConfigUrlWithXml() throws MalformedURLException { @Test void explicitConfigUrlWithYaml() throws MalformedURLException { File config = prepareConfiguration("src/test/resources/org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-client-specific.yaml"); + + "boot/hazelcast/autoconfigure/hazelcast-client-specific.yaml"); this.contextRunner.withPropertyValues("spring.hazelcast.config=" + config.toURI().toURL()) .run(assertSpecificHazelcastClient("explicit-yaml")); } @@ -130,7 +130,7 @@ void explicitConfigUrlWithYaml() throws MalformedURLException { @Test void explicitConfigUrlWithYml() throws MalformedURLException { File config = prepareConfiguration("src/test/resources/org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-client-specific.yml"); + + "boot/hazelcast/autoconfigure/hazelcast-client-specific.yml"); this.contextRunner.withPropertyValues("spring.hazelcast.config=" + config.toURI().toURL()) .run(assertSpecificHazelcastClient("explicit-yml")); } @@ -170,7 +170,7 @@ void connectionDetailsTakesPrecedenceOverUserDefinedClientConfig() { void clientConfigWithInstanceNameCreatesClientIfNecessary() throws MalformedURLException { assertThat(HazelcastClient.getHazelcastClientByName("spring-boot")).isNull(); File config = prepareConfiguration("src/test/resources/org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-client-instance.xml"); + + "boot/hazelcast/autoconfigure/hazelcast-client-instance.xml"); this.contextRunner.withPropertyValues("spring.hazelcast.config=" + config.toURI().toURL()) .run((context) -> assertThat(context).getBean(HazelcastInstance.class) .extracting(HazelcastInstance::getName) @@ -180,7 +180,7 @@ void clientConfigWithInstanceNameCreatesClientIfNecessary() throws MalformedURLE @Test void autoConfiguredClientConfigUsesApplicationClassLoader() throws MalformedURLException { File config = prepareConfiguration("src/test/resources/org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-client-specific.xml"); + + "boot/hazelcast/autoconfigure/hazelcast-client-specific.xml"); this.contextRunner.withPropertyValues("spring.hazelcast.config=" + config.toURI().toURL()).run((context) -> { HazelcastInstance hazelcast = context.getBean(HazelcastInstance.class); assertThat(hazelcast).isInstanceOf(HazelcastClientProxy.class); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationServerTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationServerTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationServerTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationServerTests.java index f171949bd3d4..baf7d8fc8179 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationServerTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationServerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -73,7 +73,7 @@ void defaultConfigFile() { void systemPropertyWithXml() { this.contextRunner .withSystemProperties(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY - + "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml") + + "=classpath:org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.xml") .run((context) -> { Config config = context.getBean(HazelcastInstance.class).getConfig(); assertThat(config.getMapConfigs().keySet()).containsOnly("foobar"); @@ -84,7 +84,7 @@ void systemPropertyWithXml() { void systemPropertyWithYaml() { this.contextRunner .withSystemProperties(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY - + "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml") + + "=classpath:org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yaml") .run((context) -> { Config config = context.getBean(HazelcastInstance.class).getConfig(); assertThat(config.getMapConfigs().keySet()).containsOnly("foobar"); @@ -95,7 +95,7 @@ void systemPropertyWithYaml() { void systemPropertyWithYml() { this.contextRunner .withSystemProperties(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY - + "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yml") + + "=classpath:org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yml") .run((context) -> { Config config = context.getBean(HazelcastInstance.class).getConfig(); assertThat(config.getMapConfigs().keySet()).containsOnly("foobar"); @@ -105,55 +105,55 @@ void systemPropertyWithYml() { @Test void explicitConfigFileWithXml() { this.contextRunner - .withPropertyValues("spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/" + .withPropertyValues("spring.hazelcast.config=org/springframework/boot/hazelcast/autoconfigure/" + "hazelcast-specific.xml") .run(assertSpecificHazelcastServer( - "org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml")); + "org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.xml")); } @Test void explicitConfigFileWithYaml() { this.contextRunner - .withPropertyValues("spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/" + .withPropertyValues("spring.hazelcast.config=org/springframework/boot/hazelcast/autoconfigure/" + "hazelcast-specific.yaml") .run(assertSpecificHazelcastServer( - "org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml")); + "org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yaml")); } @Test void explicitConfigFileWithYml() { this.contextRunner - .withPropertyValues("spring.hazelcast.config=org/springframework/boot/autoconfigure/hazelcast/" + .withPropertyValues("spring.hazelcast.config=org/springframework/boot/hazelcast/autoconfigure/" + "hazelcast-specific.yml") .run(assertSpecificHazelcastServer( - "org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yml")); + "org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yml")); } @Test void explicitConfigUrlWithXml() { this.contextRunner .withPropertyValues("spring.hazelcast.config=classpath:org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-specific.xml") + + "boot/hazelcast/autoconfigure/hazelcast-specific.xml") .run(assertSpecificHazelcastServer( - "org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml")); + "org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.xml")); } @Test void explicitConfigUrlWithYaml() { this.contextRunner .withPropertyValues("spring.hazelcast.config=classpath:org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-specific.yaml") + + "boot/hazelcast/autoconfigure/hazelcast-specific.yaml") .run(assertSpecificHazelcastServer( - "org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml")); + "org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yaml")); } @Test void explicitConfigUrlWithYml() { this.contextRunner .withPropertyValues("spring.hazelcast.config=classpath:org/springframework/" - + "boot/autoconfigure/hazelcast/hazelcast-specific.yml") + + "boot/hazelcast/autoconfigure/hazelcast-specific.yml") .run(assertSpecificHazelcastServer( - "org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yml")); + "org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yml")); } private ContextConsumer assertSpecificHazelcastServer(String location) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationTests.java index 6c2ecb967016..9248b5f04336 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import com.hazelcast.config.Config; import com.hazelcast.core.HazelcastInstance; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfigAvailableConditionTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfigAvailableConditionTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfigAvailableConditionTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfigAvailableConditionTests.java index a97148a2c095..ecf965b7b70a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastClientConfigAvailableConditionTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastClientConfigAvailableConditionTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import org.junit.jupiter.api.Test; @@ -41,7 +41,7 @@ class HazelcastClientConfigAvailableConditionTests { @Test void explicitConfigurationWithClientConfigMatches() { ConditionOutcome outcome = getMatchOutcome(new MockEnvironment().withProperty("spring.hazelcast.config", - "classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-specific.xml")); + "classpath:org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-specific.xml")); assertThat(outcome.isMatch()).isTrue(); assertThat(outcome.getMessage()).contains("Hazelcast client configuration detected"); } @@ -49,7 +49,7 @@ void explicitConfigurationWithClientConfigMatches() { @Test void explicitConfigurationWithServerConfigDoesNotMatch() { ConditionOutcome outcome = getMatchOutcome(new MockEnvironment().withProperty("spring.hazelcast.config", - "classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.xml")); + "classpath:org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.xml")); assertThat(outcome.isMatch()).isFalse(); assertThat(outcome.getMessage()).contains("Hazelcast server configuration detected"); } @@ -57,7 +57,7 @@ void explicitConfigurationWithServerConfigDoesNotMatch() { @Test void explicitConfigurationWithMissingConfigDoesNotMatch() { ConditionOutcome outcome = getMatchOutcome(new MockEnvironment().withProperty("spring.hazelcast.config", - "classpath:org/springframework/boot/autoconfigure/hazelcast/test-config-does-not-exist.xml")); + "classpath:org/springframework/boot/hazelcast/autoconfigure/test-config-does-not-exist.xml")); assertThat(outcome.isMatch()).isFalse(); assertThat(outcome.getMessage()).contains("Hazelcast configuration does not exist"); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastJpaDependencyAutoConfigurationTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastJpaDependencyAutoConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastJpaDependencyAutoConfigurationTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastJpaDependencyAutoConfigurationTests.java index 92ff4b5e89e2..99093c41214b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastJpaDependencyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/HazelcastJpaDependencyAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure; import java.util.Arrays; import java.util.Collections; @@ -26,10 +26,10 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration.HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastJpaDependencyAutoConfiguration.HazelcastInstanceEntityManagerFactoryDependsOnPostProcessor; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryDependsOnPostProcessor; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfigurationIntegrationTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfigurationIntegrationTests.java index 38decd0efcdd..46eb627d99e8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfigurationIntegrationTests.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure.health; import com.hazelcast.core.HazelcastInstance; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.hazelcast.HazelcastHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.health.HazelcastHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfigurationTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfigurationTests.java index 01015a5d3b1e..2cc1ffd4bead 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/autoconfigure/health/HazelcastHealthContributorAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.hazelcast; +package org.springframework.boot.hazelcast.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.hazelcast.HazelcastHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.health.HazelcastHealthIndicator; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastEnvironmentTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/docker/compose/HazelcastEnvironmentTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastEnvironmentTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/docker/compose/HazelcastEnvironmentTests.java index 6e9977942ba5..ff57bc54433d 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/hazelcast/HazelcastEnvironmentTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/docker/compose/HazelcastEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.hazelcast; +package org.springframework.boot.hazelcast.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/health/HazelcastHealthIndicatorTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/health/HazelcastHealthIndicatorTests.java index e41e0cd09f4a..5e370f0c1f0d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/health/HazelcastHealthIndicatorTests.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.actuate.hazelcast; +package org.springframework.boot.hazelcast.health; import com.hazelcast.core.HazelcastException; import com.hazelcast.core.HazelcastInstance; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactoryTests.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactoryTests.java index 7379bc843a23..474f92c43d37 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/hazelcast/HazelcastContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-hazelcast/src/test/java/org/springframework/boot/hazelcast/testcontainers/HazelcastContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.hazelcast; +package org.springframework.boot.hazelcast.testcontainers; import com.hazelcast.client.config.ClientConfig; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-instance.xml b/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-instance.xml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-instance.xml rename to spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-instance.xml diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-specific.xml b/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-specific.xml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-specific.xml rename to spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-specific.xml diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-specific.yaml b/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-specific.yaml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-specific.yaml rename to spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-specific.yaml diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-specific.yml b/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-specific.yml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-client-specific.yml rename to spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-client-specific.yml diff --git a/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.xml b/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.xml new file mode 100644 index 000000000000..f5a30301dca4 --- /dev/null +++ b/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.xml @@ -0,0 +1,19 @@ + + + + + + 3600 + 600 + + + + + + + + + + diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml b/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yaml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml rename to spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yaml diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yml b/spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yml rename to spring-boot-project/spring-boot-hazelcast/src/test/resources/org/springframework/boot/hazelcast/autoconfigure/hazelcast-specific.yml diff --git a/spring-boot-project/spring-boot-health/build.gradle b/spring-boot-project/spring-boot-health/build.gradle new file mode 100644 index 000000000000..5cb612f27169 --- /dev/null +++ b/spring-boot-project/spring-boot-health/build.gradle @@ -0,0 +1,39 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Health" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("io.projectreactor:reactor-core") + optional("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("io.projectreactor:reactor-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfiguration.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/AbstractCompositeHealthContributorConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfiguration.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/AbstractCompositeHealthContributorConfiguration.java index a8601b5136ae..a4d15f2186d2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfiguration.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/AbstractCompositeHealthContributorConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.health; +package org.springframework.boot.health.autoconfigure.contributor; import java.util.Map; import java.util.function.Function; @@ -32,9 +32,8 @@ * @param the bean type * @author Stephane Nicoll * @author Phillip Webb - * @since 2.2.0 */ -public abstract class AbstractCompositeHealthContributorConfiguration { +abstract class AbstractCompositeHealthContributorConfiguration { private final Function indicatorFactory; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfiguration.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/CompositeHealthContributorConfiguration.java similarity index 84% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfiguration.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/CompositeHealthContributorConfiguration.java index c882062a1324..507e8a96a686 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthContributorConfiguration.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/CompositeHealthContributorConfiguration.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.health; +package org.springframework.boot.health.autoconfigure.contributor; import java.util.Map; import java.util.function.Function; -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthIndicator; /** * Base class for health contributor configurations that can combine source beans into a @@ -31,7 +31,7 @@ * @param the bean type * @author Stephane Nicoll * @author Phillip Webb - * @since 2.2.0 + * @since 4.0.0 */ public abstract class CompositeHealthContributorConfiguration extends AbstractCompositeHealthContributorConfiguration { @@ -40,7 +40,6 @@ public abstract class CompositeHealthContributorConfiguration indicatorFactory) { super(indicatorFactory); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfiguration.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/CompositeReactiveHealthContributorConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfiguration.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/CompositeReactiveHealthContributorConfiguration.java index 8fe8c025bdf4..3271137137f5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeReactiveHealthContributorConfiguration.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/CompositeReactiveHealthContributorConfiguration.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.health; +package org.springframework.boot.health.autoconfigure.contributor; import java.util.Map; import java.util.function.Function; -import org.springframework.boot.actuate.health.CompositeReactiveHealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.CompositeReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; /** * Base class for health contributor configurations that can combine source beans into a @@ -31,7 +31,7 @@ * @param the bean type * @author Stephane Nicoll * @author Phillip Webb - * @since 2.2.0 + * @since 4.0.0 */ public abstract class CompositeReactiveHealthContributorConfiguration extends AbstractCompositeHealthContributorConfiguration { @@ -40,7 +40,6 @@ public abstract class CompositeReactiveHealthContributorConfiguration indicatorFactory) { super(indicatorFactory); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/ConditionalOnEnabledHealthIndicator.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/ConditionalOnEnabledHealthIndicator.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/ConditionalOnEnabledHealthIndicator.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/ConditionalOnEnabledHealthIndicator.java index 815093c7f6f0..84d35dd4dd9b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/ConditionalOnEnabledHealthIndicator.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/ConditionalOnEnabledHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.health; +package org.springframework.boot.health.autoconfigure.contributor; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,7 +32,7 @@ * configured. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/HealthContributorAutoConfiguration.java similarity index 75% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/HealthContributorAutoConfiguration.java index 4531d0efbd04..a86e406c0d26 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/HealthContributorAutoConfiguration.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.health; +package org.springframework.boot.health.autoconfigure.contributor; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.PingHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.PingHealthIndicator; import org.springframework.context.annotation.Bean; /** - * {@link EnableAutoConfiguration Auto-configuration} for {@link HealthContributor health - * contributors}. + * {@link EnableAutoConfiguration Auto-configuration} for default {@link HealthContributor + * health contributors}. * * @author Phillip Webb - * @since 2.2.0 + * @since 4.0.0 */ @AutoConfiguration public class HealthContributorAutoConfiguration { diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/OnEnabledHealthIndicatorCondition.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/OnEnabledHealthIndicatorCondition.java new file mode 100644 index 000000000000..561e7062da5d --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/OnEnabledHealthIndicatorCondition.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.autoconfigure.contributor; + +import org.springframework.boot.autoconfigure.condition.ConditionMessage; +import org.springframework.boot.autoconfigure.condition.ConditionOutcome; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.env.Environment; +import org.springframework.core.type.AnnotatedTypeMetadata; + +/** + * {@link Condition} that checks if a health indicator is enabled. + * + * @author Stephane Nicoll + * @author Madhura Bhave + * @author Phillip Webb + */ +class OnEnabledHealthIndicatorCondition extends SpringBootCondition { + + private static final String DEFAULTS_PROPERTY_NAME = "management.health.defaults.enabled"; + + @Override + public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { + MergedAnnotation annotation = metadata.getAnnotations().get(ConditionalOnEnabledHealthIndicator.class); + String name = annotation.getString(MergedAnnotation.VALUE); + Environment environment = context.getEnvironment(); + ConditionMessage.Builder message = ConditionMessage.forCondition(ConditionalOnEnabledHealthIndicator.class); + String propertyName = "management.health." + name + ".enabled"; + if (environment.containsProperty(propertyName)) { + boolean match = environment.getProperty(propertyName, Boolean.class, true); + return new ConditionOutcome(match, message.because(propertyName + " is " + match)); + } + boolean match = Boolean.parseBoolean(context.getEnvironment().getProperty(DEFAULTS_PROPERTY_NAME, "true")); + return new ConditionOutcome(match, message.because(DEFAULTS_PROPERTY_NAME + " is considered " + match)); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/package-info.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/package-info.java new file mode 100644 index 000000000000..8c27a5d22015 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/contributor/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for health contributors. + */ +package org.springframework.boot.health.autoconfigure.contributor; diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorNameGenerator.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorNameGenerator.java new file mode 100644 index 000000000000..95083d073456 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorNameGenerator.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.autoconfigure.registry; + +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + +/** + * Strategy used to create health contributor names from bean names. + * + * @author Phillip Webb + * @since 4.0.0 + */ +@FunctionalInterface +public interface HealthContributorNameGenerator { + + /** + * Generate the health contributor name for the given bean name. + * @param beanName the bean name + * @return the health contributor name + */ + String generateContributorName(String beanName); + + /** + * Apply the name generator to a bean map. + * @param the bean type + * @param beans the map of beans + * @return a new map with the generated names + */ + default Map apply(Map beans) { + Map result = new LinkedHashMap<>(); + beans.forEach((beanName, bean) -> result.put(generateContributorName(beanName), bean)); + return result; + } + + /** + * Return a {@link HealthContributorNameGenerator} that removes standard suffixes. + * @return a new {@link HealthContributorNameGenerator} instance + */ + static HealthContributorNameGenerator withoutStandardSuffixes() { + return withoutSuffixes("healthindicator", "healthcontributor"); + } + + /** + * Return a {@link HealthContributorNameGenerator} that removes the given suffixes. + * @param suffixes the suffixes to remove (not case sensitive) + * @return a new {@link HealthContributorNameGenerator} instance + */ + static HealthContributorNameGenerator withoutSuffixes(String... suffixes) { + return (beanName) -> { + for (String suffix : suffixes) { + if (beanName != null && beanName.toLowerCase(Locale.ENGLISH).endsWith(suffix)) { + return beanName.substring(0, beanName.length() - suffix.length()); + } + } + return beanName; + }; + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorRegistryAutoConfiguration.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorRegistryAutoConfiguration.java new file mode 100644 index 000000000000..db5d6b2aec67 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorRegistryAutoConfiguration.java @@ -0,0 +1,103 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.autoconfigure.registry; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.registry.DefaultHealthContributorRegistry; +import org.springframework.boot.health.registry.DefaultReactiveHealthContributorRegistry; +import org.springframework.boot.health.registry.HealthContributorNameValidator; +import org.springframework.boot.health.registry.HealthContributorRegistry; +import org.springframework.boot.health.registry.ReactiveHealthContributorRegistry; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.util.ClassUtils; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link HealthContributorRegistry} and {@link ReactiveHealthContributorRegistry}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +@AutoConfiguration +public class HealthContributorRegistryAutoConfiguration { + + HealthContributorRegistryAutoConfiguration() { + } + + @Bean + @ConditionalOnMissingBean(HealthContributorRegistry.class) + DefaultHealthContributorRegistry healthContributorRegistry(ApplicationContext applicationContext, + Map contributorBeans, + Map reactiveContributorBeans, + ObjectProvider nameGeneratorProvider, + List nameValidators) { + HealthContributorNameGenerator nameGenerator = nameGeneratorProvider + .getIfAvailable(HealthContributorNameGenerator::withoutStandardSuffixes); + Map contributors = new LinkedHashMap<>(); + contributorBeans.forEach((beanName, bean) -> { + String contributorName = nameGenerator.generateContributorName(beanName); + contributors.put(contributorName, bean); + }); + if (ClassUtils.isPresent("reactor.core.publisher.Flux", applicationContext.getClassLoader())) { + reactiveContributorBeans.forEach((beanName, bean) -> { + String contributorName = nameGenerator.generateContributorName(beanName); + contributors.put(contributorName, bean.asHealthContributor()); + }); + } + return new DefaultHealthContributorRegistry(contributors, nameValidators); + } + + static class ReactiveHealthContributorRegistryConfiguration { + + @Bean + @ConditionalOnMissingBean(ReactiveHealthContributorRegistry.class) + DefaultReactiveHealthContributorRegistry reactiveHealthContributorRegistry( + Map reactiveContributorBeans, + Map contributorBeans, + ObjectProvider nameGeneratorProvider, + List nameValidators) { + HealthContributorNameGenerator nameGenerator = nameGeneratorProvider + .getIfAvailable(HealthContributorNameGenerator::withoutStandardSuffixes); + Map contributors = new LinkedHashMap<>(); + reactiveContributorBeans.forEach((beanName, bean) -> { + String contributorName = nameGenerator.generateContributorName(beanName); + contributors.put(contributorName, bean); + }); + reactiveContributorBeans.forEach((beanName, bean) -> { + String contributorName = nameGenerator.generateContributorName(beanName); + contributors.put(contributorName, bean); + }); + contributorBeans.forEach((beanName, bean) -> { + String contributorName = nameGenerator.generateContributorName(beanName); + contributors.computeIfAbsent(contributorName, (key) -> ReactiveHealthContributor.adapt(bean)); + }); + return new DefaultReactiveHealthContributorRegistry(contributors, nameValidators); + } + + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/package-info.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/package-info.java new file mode 100644 index 000000000000..f554b0192619 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/registry/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for health registries. + */ +package org.springframework.boot.health.autoconfigure.registry; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/AbstractHealthIndicator.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractHealthIndicator.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/AbstractHealthIndicator.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractHealthIndicator.java index cbc032e5e2ab..b2fb7e203c4e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/AbstractHealthIndicator.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractHealthIndicator.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.function.Function; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.boot.actuate.health.Health.Builder; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -30,11 +29,11 @@ * {@link Health} instance and error handling. *

* This implementation is only suitable if an {@link Exception} raised from - * {@link #doHealthCheck(org.springframework.boot.actuate.health.Health.Builder)} should - * create a {@link Status#DOWN} health status. + * {@link #doHealthCheck(Health.Builder)} should create a {@link Status#DOWN} health + * status. * * @author Christian Dupuis - * @since 1.1.0 + * @since 4.0.0 */ public abstract class AbstractHealthIndicator implements HealthIndicator { @@ -58,7 +57,6 @@ protected AbstractHealthIndicator() { * Create a new {@link AbstractHealthIndicator} instance with a specific message to * log when the health check fails. * @param healthCheckFailedMessage the message to log on health check failure - * @since 2.0.0 */ protected AbstractHealthIndicator(String healthCheckFailedMessage) { this.healthCheckFailedMessage = (ex) -> healthCheckFailedMessage; @@ -68,7 +66,6 @@ protected AbstractHealthIndicator(String healthCheckFailedMessage) { * Create a new {@link AbstractHealthIndicator} instance with a specific message to * log when the health check fails. * @param healthCheckFailedMessage the message to log on health check failure - * @since 2.0.0 */ protected AbstractHealthIndicator(Function healthCheckFailedMessage) { Assert.notNull(healthCheckFailedMessage, "'healthCheckFailedMessage' must not be null"); @@ -97,7 +94,7 @@ private void logExceptionIfPresent(Throwable throwable) { /** * Actual health check logic. - * @param builder the {@link Builder} to report health status and details + * @param builder the {@link Health.Builder} to report health status and details * @throws Exception any {@link Exception} that should create a {@link Status#DOWN} * system status. */ diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractMapAdapter.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractMapAdapter.java new file mode 100644 index 000000000000..03048cfe239f --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractMapAdapter.java @@ -0,0 +1,78 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; + +import org.springframework.util.Assert; + +/** + * Internal base class for contributors backed by a map with values adapted as necessary. + * + * @param the value type + * @param the contributor type + * @param the entry + * @author Phillip Webb + * @author Guirong Hu + */ +abstract class AbstractMapAdapter { + + private final Map map; + + private final BiFunction entryAdapter; + + AbstractMapAdapter(Map map, Function valueAdapter, + BiFunction entryAdapter) { + Assert.notNull(map, "'map' must not be null"); + Assert.notNull(valueAdapter, "'valueAdapter' must not be null"); + map.keySet().forEach(this::validateMapKey); + this.map = Collections.unmodifiableMap(map.entrySet().stream().collect(LinkedHashMap::new, (result, entry) -> { + String key = entry.getKey(); + C value = adaptMapValue(entry.getValue(), valueAdapter); + result.put(key, value); + }, Map::putAll)); + this.entryAdapter = entryAdapter; + } + + private void validateMapKey(String value) { + Assert.notNull(value, "'map' must not contain null keys"); + Assert.isTrue(!value.contains("/"), "'map' keys must not contain a '/'"); + } + + private C adaptMapValue(V value, Function valueAdapter) { + C contributor = (value != null) ? valueAdapter.apply(value) : null; + Assert.notNull(contributor, "'map' must not contain null values"); + return contributor; + } + + C getContributor(String name) { + return this.map.get(name); + } + + Iterator iterator() { + return this.map.entrySet() + .stream() + .map((entry) -> this.entryAdapter.apply(entry.getKey(), entry.getValue())) + .iterator(); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/AbstractReactiveHealthIndicator.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractReactiveHealthIndicator.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/AbstractReactiveHealthIndicator.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractReactiveHealthIndicator.java index a2dca84f503f..a214294b29d0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/AbstractReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/AbstractReactiveHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.function.Function; @@ -32,7 +32,7 @@ * @author Stephane Nicoll * @author Nikolay Rybak * @author Moritz Halbritter - * @since 2.0.0 + * @since 4.0.0 */ public abstract class AbstractReactiveHealthIndicator implements ReactiveHealthIndicator { @@ -47,7 +47,6 @@ public abstract class AbstractReactiveHealthIndicator implements ReactiveHealthI /** * Create a new {@link AbstractReactiveHealthIndicator} instance with a default * {@code healthCheckFailedMessage}. - * @since 2.1.7 */ protected AbstractReactiveHealthIndicator() { this(NO_MESSAGE); @@ -57,7 +56,6 @@ protected AbstractReactiveHealthIndicator() { * Create a new {@link AbstractReactiveHealthIndicator} instance with a specific * message to log when the health check fails. * @param healthCheckFailedMessage the message to log on health check failure - * @since 2.1.7 */ protected AbstractReactiveHealthIndicator(String healthCheckFailedMessage) { this.healthCheckFailedMessage = (ex) -> healthCheckFailedMessage; @@ -67,7 +65,6 @@ protected AbstractReactiveHealthIndicator(String healthCheckFailedMessage) { * Create a new {@link AbstractReactiveHealthIndicator} instance with a specific * message to log when the health check fails. * @param healthCheckFailedMessage the message to log on health check failure - * @since 2.1.7 */ protected AbstractReactiveHealthIndicator(Function healthCheckFailedMessage) { Assert.notNull(healthCheckFailedMessage, "'healthCheckFailedMessage' must not be null"); diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealth.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealth.java new file mode 100644 index 000000000000..6c7459c73d3c --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealth.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Map; +import java.util.TreeMap; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +import org.springframework.util.Assert; + +/** + * A {@link ContributedHealth} that is composed of other {@link ContributedHealth} + * instances. Used to provide a unified view of related components. For example, a + * database health indicator may be a composite containing the {@link Health} of each + * datasource connection. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public non-sealed class CompositeHealth extends ContributedHealth { + + private final Status status; + + private final Map components; + + public CompositeHealth(Status status, Map components) { + Assert.notNull(status, "'status' must not be null"); + this.status = status; + this.components = (components != null) ? new TreeMap<>(components) : components; + } + + @Override + public Status getStatus() { + return this.status; + } + + @JsonInclude(Include.NON_EMPTY) + public Map getComponents() { + return this.components; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributor.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributor.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributor.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributor.java index 414a97ca41c4..7705aa1bb464 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthContributor.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.Map; import java.util.function.Function; @@ -24,11 +24,12 @@ * instances. * * @author Phillip Webb - * @since 2.2.0 + * @author Guirong Hu + * @since 4.0.0 * @see CompositeHealth * @see CompositeReactiveHealthContributor */ -public interface CompositeHealthContributor extends HealthContributor, NamedContributors { +public non-sealed interface CompositeHealthContributor extends HealthContributor, HealthContributors { /** * Factory method that will create a {@link CompositeHealthContributor} from the diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributorMapAdapter.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributorMapAdapter.java new file mode 100644 index 000000000000..b2552fb7bec7 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributorMapAdapter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Iterator; +import java.util.Map; +import java.util.function.Function; + +/** + * {@link CompositeHealthContributor} backed by a map with values adapted as necessary. + * + * @param the value type + * @author Phillip Webb + */ +class CompositeHealthContributorMapAdapter extends AbstractMapAdapter + implements CompositeHealthContributor { + + CompositeHealthContributorMapAdapter(Map map, Function valueAdapter) { + super(map, valueAdapter, HealthContributors.Entry::new); + } + + @Override + public HealthContributor getContributor(String name) { + return super.getContributor(name); + } + + @Override + public Iterator iterator() { + return super.iterator(); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributorReactiveAdapter.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributorReactiveAdapter.java new file mode 100644 index 000000000000..aeaf465a7350 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeHealthContributorReactiveAdapter.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Iterator; + +import org.springframework.util.Assert; + +/** + * Adapts a {@link CompositeHealthContributor} to a + * {@link CompositeReactiveHealthContributor} so that it can be safely invoked in a + * reactive environment. + * + * @author Phillip Webb + * @see ReactiveHealthContributor#adapt(HealthContributor) + */ +class CompositeHealthContributorReactiveAdapter implements CompositeReactiveHealthContributor { + + private final CompositeHealthContributor delegate; + + CompositeHealthContributorReactiveAdapter(CompositeHealthContributor delegate) { + Assert.notNull(delegate, "'delegate' must not be null"); + this.delegate = delegate; + } + + @Override + public Iterator iterator() { + return this.delegate.stream() + .map((entry) -> new ReactiveHealthContributors.Entry(entry.name(), + ReactiveHealthContributor.adapt(entry.contributor()))) + .iterator(); + } + + @Override + public ReactiveHealthContributor getContributor(String name) { + HealthContributor contributor = this.delegate.getContributor(name); + return (contributor != null) ? ReactiveHealthContributor.adapt(contributor) : null; + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributor.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributor.java new file mode 100644 index 000000000000..5d896b393514 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributor.java @@ -0,0 +1,78 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Iterator; +import java.util.Map; +import java.util.function.Function; + +/** + * A {@link ReactiveHealthContributor} that is composed of other + * {@link ReactiveHealthContributor} instances. + * + * @author Phillip Webb + * @since 4.0.0 + * @see CompositeHealth + * @see CompositeHealthContributor + */ +public non-sealed interface CompositeReactiveHealthContributor + extends ReactiveHealthContributor, ReactiveHealthContributors { + + @Override + default CompositeHealthContributor asHealthContributor() { + return new CompositeHealthContributor() { + + @Override + public Iterator iterator() { + return CompositeReactiveHealthContributor.this.stream() + .map((entry) -> new HealthContributors.Entry(entry.name(), + entry.contributor().asHealthContributor())) + .iterator(); + } + + @Override + public HealthContributor getContributor(String name) { + return CompositeReactiveHealthContributor.this.getContributor(name).asHealthContributor(); + } + + }; + } + + /** + * Factory method that will create a {@link CompositeReactiveHealthContributor} from + * the specified map. + * @param map the source map + * @return a composite health contributor instance + */ + static CompositeReactiveHealthContributor fromMap(Map map) { + return fromMap(map, Function.identity()); + } + + /** + * Factory method that will create a {@link CompositeReactiveHealthContributor} from + * the specified map. + * @param the value type + * @param map the source map + * @param valueAdapter function used to adapt the map value + * @return a composite health contributor instance + */ + static CompositeReactiveHealthContributor fromMap(Map map, + Function valueAdapter) { + return new CompositeReactiveHealthContributorMapAdapter<>(map, valueAdapter); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributorMapAdapter.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributorMapAdapter.java new file mode 100644 index 000000000000..a55ef2c726c0 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributorMapAdapter.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Iterator; +import java.util.Map; +import java.util.function.Function; + +/** + * {@link CompositeHealthContributor} backed by a map with values adapted as necessary. + * + * @param the value type + * @author Phillip Webb + */ +class CompositeReactiveHealthContributorMapAdapter + extends AbstractMapAdapter + implements CompositeReactiveHealthContributor { + + CompositeReactiveHealthContributorMapAdapter(Map map, + Function valueAdapter) { + super(map, valueAdapter, ReactiveHealthContributors.Entry::new); + } + + @Override + public ReactiveHealthContributor getContributor(String name) { + return super.getContributor(name); + } + + @Override + public Iterator iterator() { + return super.iterator(); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ContributedHealth.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ContributedHealth.java new file mode 100644 index 000000000000..b9745cd1b437 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ContributedHealth.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import com.fasterxml.jackson.annotation.JsonUnwrapped; + +/** + * A component that contributes a health {@link Status} as well as any additional + * contextual details. Subclasses should expect to be serialized and presented to the + * user, typically as JSON. + * + * @author Phillip Webb + * @since 4.0.0 + * @see Health + */ +public abstract sealed class ContributedHealth permits Health, CompositeHealth { + + ContributedHealth() { + } + + /** + * Return the status of the component. + * @return the component status + */ + @JsonUnwrapped + public abstract Status getStatus(); + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/Health.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/Health.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/Health.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/Health.java index 6b60cce8883a..8817c3ca58d0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/Health.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/Health.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.Collections; import java.util.LinkedHashMap; @@ -27,7 +27,7 @@ /** * Carries information about the health of a component or subsystem. Extends - * {@link HealthComponent} so that additional contextual details about the system can be + * {@link ContributedHealth} so that additional contextual details about the system can be * returned along with the {@link Status}. *

* {@link Health} instances can be created by using {@link Builder}'s fluent API. Typical @@ -46,10 +46,10 @@ * @author Christian Dupuis * @author Phillip Webb * @author Michael Pratt - * @since 1.1.0 + * @since 4.0.0 */ @JsonInclude(Include.NON_EMPTY) -public final class Health extends HealthComponent { +public final class Health extends ContributedHealth { private final Status status; @@ -88,17 +88,8 @@ public Map getDetails() { return this.details; } - /** - * Return a new instance of this {@link Health} with all {@link #getDetails() details} - * removed. - * @return a new instance without details - * @since 2.2.0 - */ Health withoutDetails() { - if (this.details.isEmpty()) { - return this; - } - return status(getStatus()).build(); + return (this.details.isEmpty()) ? this : status(getStatus()).build(); } @Override @@ -254,7 +245,6 @@ public Builder withDetail(String key, Object value) { * replace any existing keys if there are duplicates. * @param details map of details * @return this {@link Builder} instance - * @since 2.1.0 */ public Builder withDetails(Map details) { Assert.notNull(details, "'details' must not be null"); diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthContributor.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthContributor.java new file mode 100644 index 000000000000..d72c71e8f087 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthContributor.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +/** + * Contribute to {@link ContributedHealth health components}. A contributor must be either + * a {@link HealthIndicator} or a {@link CompositeHealthContributor}. + * + * @author Phillip Webb + * @since 4.0.0 + * @see HealthIndicator + * @see CompositeHealthContributor + */ +public sealed interface HealthContributor permits HealthIndicator, CompositeHealthContributor { + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthContributors.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthContributors.java new file mode 100644 index 000000000000..e9b0f070a485 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthContributors.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.springframework.util.Assert; + +/** + * A collection of named {@link HealthContributor health contributors}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public interface HealthContributors extends Iterable { + + /** + * Return the contributor with the given name. + * @param name the name of the contributor + * @return a contributor instance or {@code null} + */ + HealthContributor getContributor(String name); + + /** + * Return a stream of the contributor entries. + * @return the stream of named contributors + */ + default Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + /** + * A health contributor entry. + * + * @param name the name of the contributor + * @param contributor the contributor + */ + record Entry(String name, HealthContributor contributor) { + + public Entry { + Assert.hasText(name, "'name' must not be empty"); + Assert.notNull(contributor, "'contributor' must not be null"); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthIndicator.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthIndicator.java similarity index 80% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthIndicator.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthIndicator.java index d44b85b6d3b1..920b26cee7ad 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthIndicator.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthIndicator.java @@ -14,24 +14,22 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; /** - * Strategy interface used to contribute {@link Health} to the results returned from the - * {@link HealthEndpoint}. + * Contributes {@link Health} information for specific component or subsystem. * * @author Dave Syer * @author Phillip Webb - * @since 1.0.0 + * @since 4.0.0 */ @FunctionalInterface -public interface HealthIndicator extends HealthContributor { +public non-sealed interface HealthIndicator extends HealthContributor { /** * Return an indication of health. * @param includeDetails if details should be included or removed * @return the health - * @since 2.2.0 */ default Health getHealth(boolean includeDetails) { Health health = health(); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthIndicatorReactiveAdapter.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthIndicatorReactiveAdapter.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthIndicatorReactiveAdapter.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthIndicatorReactiveAdapter.java index b9e9aeb0252f..c92a43b0f177 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthIndicatorReactiveAdapter.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/HealthIndicatorReactiveAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/PingHealthIndicator.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/PingHealthIndicator.java similarity index 86% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/PingHealthIndicator.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/PingHealthIndicator.java index ba3c19a9a4f0..17143460fbe8 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/PingHealthIndicator.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/PingHealthIndicator.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; /** - * Default implementation of {@link HealthIndicator} that returns {@link Status#UP}. + * Auto-configured {@link HealthIndicator} that always returns {@link Status#UP}. * * @author Dave Syer * @author Christian Dupuis diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthContributor.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthContributor.java new file mode 100644 index 000000000000..f6139aa21116 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthContributor.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import reactor.core.scheduler.Schedulers; + +import org.springframework.util.Assert; + +/** + * Tagging interface for classes that contribute to {@link ContributedHealth health + * components}. A contributor must be either a {@link ReactiveHealthIndicator} or a + * {@link CompositeReactiveHealthContributor}. + * + * @author Phillip Webb + * @author Stephane Nicoll + * @since 4.0.0 + * @see ReactiveHealthIndicator + * @see CompositeReactiveHealthContributor + */ +public sealed interface ReactiveHealthContributor permits ReactiveHealthIndicator, CompositeReactiveHealthContributor { + + /** + * Return this reactive contributor as a standard blocking {@link HealthContributor}. + * @return a blocking health contributor + */ + HealthContributor asHealthContributor(); + + /** + * Adapts the given {@link HealthContributor} into a {@link ReactiveHealthContributor} + * by scheduling blocking calls to {@link Schedulers#boundedElastic()}. + * @param healthContributor the contributor to adapt + * @return the adapted contributor + */ + static ReactiveHealthContributor adapt(HealthContributor healthContributor) { + Assert.notNull(healthContributor, "'healthContributor' must not be null"); + if (healthContributor instanceof HealthIndicator healthIndicator) { + return new HealthIndicatorReactiveAdapter(healthIndicator); + } + if (healthContributor instanceof CompositeHealthContributor compositeHealthContributor) { + return new CompositeHealthContributorReactiveAdapter(compositeHealthContributor); + } + throw new IllegalStateException("Unknown HealthContributor type"); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthContributors.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthContributors.java new file mode 100644 index 000000000000..1039d2cd36e2 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthContributors.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.springframework.util.Assert; + +/** + * A collection of named {@link ReactiveHealthContributor reactive health contributors}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public interface ReactiveHealthContributors extends Iterable { + + /** + * Return the contributor with the given name. + * @param name the name of the contributor + * @return a contributor instance or {@code null} + */ + ReactiveHealthContributor getContributor(String name); + + /** + * Return a stream of the contributor entries. + * @return the stream of named contributors + */ + default Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + /** + * A reactive health contributor entry. + * + * @param name the name of the contributor + * @param contributor the contributor + */ + record Entry(String name, ReactiveHealthContributor contributor) { + + public Entry { + Assert.hasText(name, "'name' must not be empty"); + Assert.notNull(contributor, "'contributor' must not be null"); + } + + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthIndicator.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthIndicator.java new file mode 100644 index 000000000000..75d1f4d269a3 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/ReactiveHealthIndicator.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import reactor.core.publisher.Mono; + +/** + * Contributes {@link Health} information for specific reactive component or subsystem. + *

+ * This is non-blocking contract that is meant to be used in a reactive application. See + * {@link HealthIndicator} for the traditional contract. + * + * @author Stephane Nicoll + * @since 4.0.0 + * @see HealthIndicator + */ +@FunctionalInterface +public non-sealed interface ReactiveHealthIndicator extends ReactiveHealthContributor { + + @Override + default HealthIndicator asHealthContributor() { + return new HealthIndicator() { + + @Override + public Health getHealth(boolean includeDetails) { + return ReactiveHealthIndicator.this.getHealth(includeDetails).block(); + } + + @Override + public Health health() { + return ReactiveHealthIndicator.this.health().block(); + } + + }; + } + + /** + * Provide the indicator of health. + * @param includeDetails if details should be included or removed + * @return a {@link Mono} that provides the {@link Health} + */ + default Mono getHealth(boolean includeDetails) { + Mono health = health(); + return includeDetails ? health : health.map(Health::withoutDetails); + } + + /** + * Provide the indicator of health. + * @return a {@link Mono} that provides the {@link Health} + */ + Mono health(); + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/Status.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/Status.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/Status.java rename to spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/Status.java index 2d43d84a517d..07fbfefd78da 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/Status.java +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/Status.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -32,7 +32,7 @@ * Custom states can also be created and used throughout the Spring Boot Health subsystem. * * @author Christian Dupuis - * @since 1.1.0 + * @since 4.0.0 */ @JsonInclude(Include.NON_EMPTY) public final class Status { diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/package-info.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/package-info.java new file mode 100644 index 000000000000..7a853a5ac87b --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/contributor/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to contributing health information about an application. + */ +package org.springframework.boot.health.contributor; diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/AbstractHealthContributorRegistry.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/AbstractHealthContributorRegistry.java new file mode 100644 index 000000000000..c6ba7626b0d5 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/AbstractHealthContributorRegistry.java @@ -0,0 +1,114 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; + +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +/** + * Internal base class for health contributor registries. + * + * @param the contributor type + * @param the entry type + * @author Phillip Webb + */ +abstract class AbstractHealthContributorRegistry { + + private final Collection nameValidators; + + private final BiFunction entryAdapter; + + private volatile Map contributors; + + private final Object monitor = new Object(); + + AbstractHealthContributorRegistry(Map contributors, + Collection nameValidators, + BiFunction entryAdapter) { + this.nameValidators = List.copyOf(nameValidators); + this.entryAdapter = entryAdapter; + Assert.notNull(contributors, "'contributors' must not be null"); + contributors.entrySet().forEach((entry) -> this.verifyName(entry.getKey(), entry.getValue())); + this.contributors = Collections.unmodifiableMap(new LinkedHashMap<>(contributors)); + } + + void registerContributor(String name, C contributor) { + Assert.hasText(name, "'name' must not be empty"); + Assert.notNull(contributor, "'contributor' must not be null"); + verifyName(name, contributor); + synchronized (this.monitor) { + Assert.state(!this.contributors.containsKey(name), + () -> "A contributor named \"" + name + "\" has already been registered"); + Map contributors = new LinkedHashMap<>(this.contributors); + contributors.put(name, contributor); + this.contributors = Collections.unmodifiableMap(contributors); + } + } + + C unregisterContributor(String name) { + Assert.notNull(name, "'name' must not be null"); + synchronized (this.monitor) { + C unregistered = this.contributors.get(name); + if (unregistered != null) { + Map contributors = new LinkedHashMap<>(this.contributors); + contributors.remove(name); + this.contributors = Collections.unmodifiableMap(contributors); + } + return unregistered; + } + } + + C getContributor(String name) { + return this.contributors.get(name); + } + + Iterator iterator() { + Iterator> iterator = this.contributors.entrySet().iterator(); + return new Iterator<>() { + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public E next() { + Map.Entry entry = iterator.next(); + return AbstractHealthContributorRegistry.this.entryAdapter.apply(entry.getKey(), entry.getValue()); + } + + }; + } + + private void verifyName(String name, C contributor) { + Assert.state(StringUtils.hasText(name), + () -> "Name for contributor '%s' must not be empty".formatted(contributor)); + if (!CollectionUtils.isEmpty(this.nameValidators)) { + this.nameValidators.forEach((nameValidator) -> nameValidator.validate(name)); + } + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/DefaultHealthContributorRegistry.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/DefaultHealthContributorRegistry.java new file mode 100644 index 000000000000..717f59eba195 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/DefaultHealthContributorRegistry.java @@ -0,0 +1,74 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthContributors; + +/** + * Default {@link HealthContributorRegistry} implementation. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public class DefaultHealthContributorRegistry + extends AbstractHealthContributorRegistry + implements HealthContributorRegistry { + + /** + * Create a new empty {@link DefaultHealthContributorRegistry} instance. + */ + public DefaultHealthContributorRegistry() { + this(Collections.emptyMap(), Collections.emptyList()); + } + + /** + * Create a new {@link DefaultHealthContributorRegistry} instance. + * @param contributors the initial set of health contributors + * @param nameValidators the name validators to apply + */ + public DefaultHealthContributorRegistry(Map contributors, + Collection nameValidators) { + super(contributors, nameValidators, HealthContributors.Entry::new); + } + + @Override + public HealthContributor getContributor(String name) { + return super.getContributor(name); + } + + @Override + public Iterator iterator() { + return super.iterator(); + } + + @Override + public void registerContributor(String name, HealthContributor contributor) { + super.registerContributor(name, contributor); + } + + @Override + public HealthContributor unregisterContributor(String name) { + return super.unregisterContributor(name); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/DefaultReactiveHealthContributorRegistry.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/DefaultReactiveHealthContributorRegistry.java new file mode 100644 index 000000000000..d1611722695d --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/DefaultReactiveHealthContributorRegistry.java @@ -0,0 +1,74 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributors; + +/** + * Default {@link ReactiveHealthContributorRegistry} implementation. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public class DefaultReactiveHealthContributorRegistry + extends AbstractHealthContributorRegistry + implements ReactiveHealthContributorRegistry { + + /** + * Create a new empty {@link DefaultReactiveHealthContributorRegistry} instance. + */ + public DefaultReactiveHealthContributorRegistry() { + this(Collections.emptyMap(), Collections.emptyList()); + } + + /** + * Create a new {@link DefaultReactiveHealthContributorRegistry} instance. + * @param contributors the initial set of health contributors + * @param nameValidators the name validators to apply + */ + public DefaultReactiveHealthContributorRegistry(Map contributors, + Collection nameValidators) { + super(contributors, nameValidators, ReactiveHealthContributors.Entry::new); + } + + @Override + public ReactiveHealthContributor getContributor(String name) { + return super.getContributor(name); + } + + @Override + public Iterator iterator() { + return super.iterator(); + } + + @Override + public void registerContributor(String name, ReactiveHealthContributor contributor) { + super.registerContributor(name, contributor); + } + + @Override + public ReactiveHealthContributor unregisterContributor(String name) { + return super.unregisterContributor(name); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/HealthContributorNameValidator.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/HealthContributorNameValidator.java new file mode 100644 index 000000000000..2ce0bfd460f2 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/HealthContributorNameValidator.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +/** + * Interface that can be used to validate names before they are added to a health + * contributor registry. + * + * @author Phillip Webb + * @since 4.0.0 + */ +@FunctionalInterface +public interface HealthContributorNameValidator { + + /** + * Validate the contributor name. + * @param name the name to validate + * @throws IllegalStateException on an invalid name + */ + void validate(String name) throws IllegalStateException; + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/HealthContributorRegistry.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/HealthContributorRegistry.java new file mode 100644 index 000000000000..e78dbb584b82 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/HealthContributorRegistry.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthContributors; + +/** + * A mutable registry of {@link HealthContributor health contributors}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public interface HealthContributorRegistry extends HealthContributors { + + /** + * Register a contributor with the given {@code name}. + * @param name the name of the contributor + * @param contributor the contributor to register + * @throws IllegalStateException if the contributor cannot be registered with the + * given {@code name}. + */ + void registerContributor(String name, HealthContributor contributor); + + /** + * Unregister a previously registered contributor. + * @param name the name of the contributor to unregister + * @return the unregistered indicator, or {@code null} if no indicator was found in + * the registry for the given {@code name}. + */ + HealthContributor unregisterContributor(String name); + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/ReactiveHealthContributorRegistry.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/ReactiveHealthContributorRegistry.java new file mode 100644 index 000000000000..b34f66e23d17 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/ReactiveHealthContributorRegistry.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributors; + +/** + * A mutable registry of {@link ReactiveHealthContributor reactive health contributors}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public interface ReactiveHealthContributorRegistry extends ReactiveHealthContributors { + + /** + * Register a contributor with the given {@code name}. + * @param name the name of the contributor + * @param contributor the contributor to register + * @throws IllegalStateException if the contributor cannot be registered with the + * given {@code name}. + */ + void registerContributor(String name, ReactiveHealthContributor contributor); + + /** + * Unregister a previously registered contributor. + * @param name the name of the contributor to unregister + * @return the unregistered indicator, or {@code null} if no indicator was found in + * the registry for the given {@code name}. + */ + ReactiveHealthContributor unregisterContributor(String name); + +} diff --git a/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/package-info.java b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/package-info.java new file mode 100644 index 000000000000..ca2b7d73ae62 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/java/org/springframework/boot/health/registry/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health registry support. + */ +package org.springframework.boot.health.registry; diff --git a/spring-boot-project/spring-boot-health/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-health/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..7346e1595a19 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration +org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfigurationTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/AbstractCompositeHealthContributorConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfigurationTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/AbstractCompositeHealthContributorConfigurationTests.java index c2a59b33c191..5188ba477a9f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfigurationTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/AbstractCompositeHealthContributorConfigurationTests.java @@ -14,16 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.health; +package org.springframework.boot.health.autoconfigure.contributor; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.NamedContributor; -import org.springframework.boot.actuate.health.NamedContributors; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -101,13 +100,14 @@ void createContributorWhenBeanFactoryHasMultipleBeansCreatesComposite() { C contributor = newComposite().createContributor(context.getBeanFactory(), TestBean.class); assertThat(contributor).isNotInstanceOf(this.indicatorType); assertThat(ClassUtils.getShortName(contributor.getClass())).startsWith("Composite"); - assertThat(((NamedContributors) contributor).stream().map(NamedContributor::getName)) - .containsExactlyInAnyOrder("standard", "nonDefault"); + assertThat(allNamesFromComposite(contributor)).containsExactlyInAnyOrder("standard", "nonDefault"); } } protected abstract AbstractCompositeHealthContributorConfiguration newComposite(); + protected abstract Stream allNamesFromComposite(C composite); + static class TestBean { } diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/CompositeHealthContributorConfigurationTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/CompositeHealthContributorConfigurationTests.java new file mode 100644 index 000000000000..487181ec142e --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/CompositeHealthContributorConfigurationTests.java @@ -0,0 +1,66 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.autoconfigure.contributor; + +import java.util.stream.Stream; + +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfigurationTests.TestHealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthContributors; + +/** + * Tests for {@link CompositeHealthContributorConfiguration}. + * + * @author Phillip Webb + */ +class CompositeHealthContributorConfigurationTests + extends AbstractCompositeHealthContributorConfigurationTests { + + @Override + protected AbstractCompositeHealthContributorConfiguration newComposite() { + return new TestCompositeHealthContributorConfiguration(); + } + + @Override + protected Stream allNamesFromComposite(HealthContributor composite) { + return ((HealthContributors) composite).stream().map(HealthContributors.Entry::name); + } + + static class TestCompositeHealthContributorConfiguration + extends CompositeHealthContributorConfiguration { + + TestCompositeHealthContributorConfiguration() { + super(TestHealthIndicator::new); + } + + } + + static class TestHealthIndicator extends AbstractHealthIndicator { + + TestHealthIndicator(TestBean testBean) { + } + + @Override + protected void doHealthCheck(Health.Builder builder) throws Exception { + builder.up(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/CompositeReactiveHealthContributorConfigurationTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/CompositeReactiveHealthContributorConfigurationTests.java new file mode 100644 index 000000000000..80266172850d --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/CompositeReactiveHealthContributorConfigurationTests.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.autoconfigure.contributor; + +import java.util.stream.Stream; + +import reactor.core.publisher.Mono; + +import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfigurationTests.TestReactiveHealthIndicator; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributors; + +/** + * Tests for {@link CompositeReactiveHealthContributorConfiguration}. + * + * @author Phillip Webb + */ +class CompositeReactiveHealthContributorConfigurationTests extends + AbstractCompositeHealthContributorConfigurationTests { + + @Override + protected AbstractCompositeHealthContributorConfiguration newComposite() { + return new TestCompositeReactiveHealthContributorConfiguration(); + } + + @Override + protected Stream allNamesFromComposite(ReactiveHealthContributor composite) { + return ((ReactiveHealthContributors) composite).stream().map(ReactiveHealthContributors.Entry::name); + } + + static class TestCompositeReactiveHealthContributorConfiguration + extends CompositeReactiveHealthContributorConfiguration { + + TestCompositeReactiveHealthContributorConfiguration() { + super(TestReactiveHealthIndicator::new); + } + + } + + static class TestReactiveHealthIndicator extends AbstractReactiveHealthIndicator { + + TestReactiveHealthIndicator(TestBean testBean) { + } + + @Override + protected Mono doHealthCheck(Health.Builder builder) { + return Mono.just(builder.up().build()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/ConditionalOnEnabledHealthIndicatorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/ConditionalOnEnabledHealthIndicatorTests.java new file mode 100644 index 000000000000..1ca977c67281 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/ConditionalOnEnabledHealthIndicatorTests.java @@ -0,0 +1,93 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.autoconfigure.contributor; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.PingHealthIndicator; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ConditionalOnEnabledHealthIndicator}. + * + * @author Phillip Webb + */ +class ConditionalOnEnabledHealthIndicatorTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withUserConfiguration(CustomHealthIndicatorConfiguration.class); + + @Test + void whenNoPropertyCreatesBean() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(HealthIndicator.class)); + } + + @Test + void whenIndicatorPropertyTrueCreatesBean() { + this.contextRunner.withPropertyValues("management.health.custom.enabled=true") + .run((context) -> assertThat(context).hasSingleBean(HealthIndicator.class)); + } + + @Test + void whenIndicatorPropertyFalseDoesNotCreateBean() { + this.contextRunner.withPropertyValues("management.health.custom.enabled=false") + .run((context) -> assertThat(context).doesNotHaveBean(HealthIndicator.class)); + } + + @Test + void whenDefaultsPropertyTrueCreatesBean() { + this.contextRunner.withPropertyValues("management.health.defaults.enabled=true") + .run((context) -> assertThat(context).hasSingleBean(HealthIndicator.class)); + } + + @Test + void whenDefaultsPropertyFalseDoesNotCreateBean() { + this.contextRunner.withPropertyValues("management.health.defaults.enabled=false") + .run((context) -> assertThat(context).doesNotHaveBean(HealthIndicator.class)); + } + + @Test + void whenIndicatorPropertyTrueAndDefaultsPropertyFalseCreatesBean() { + this.contextRunner + .withPropertyValues("management.health.custom.enabled=true", "management.health.defaults.enabled=false") + .run((context) -> assertThat(context).hasSingleBean(HealthIndicator.class)); + } + + @Test + void whenIndicatorPropertyFalseAndDefaultsPropertyTrueDoesNotCreateBean() { + this.contextRunner + .withPropertyValues("management.health.custom.enabled=false", "management.health.defaults.enabled=true") + .run((context) -> assertThat(context).doesNotHaveBean(HealthIndicator.class)); + } + + @Configuration(proxyBeanMethods = false) + static class CustomHealthIndicatorConfiguration { + + @Bean + @ConditionalOnEnabledHealthIndicator("custom") + PingHealthIndicator customHealthIndicator() { + return new PingHealthIndicator(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/HealthContributorAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/HealthContributorAutoConfigurationTests.java index 7516fa02d349..3e828f208cbc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/contributor/HealthContributorAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.health; +package org.springframework.boot.health.autoconfigure.contributor; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.PingHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.PingHealthIndicator; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -57,7 +57,6 @@ void runWhenHasDefaultsDisabledDoesNotCreatePingHealthIndicator() { this.contextRunner.withUserConfiguration(CustomHealthIndicatorConfiguration.class) .withPropertyValues("management.health.defaults.enabled:false") .run((context) -> assertThat(context).doesNotHaveBean(HealthIndicator.class)); - } @Test @@ -65,7 +64,6 @@ void runWhenHasDefaultsDisabledAndPingIndicatorEnabledCreatesPingHealthIndicator this.contextRunner.withUserConfiguration(CustomHealthIndicatorConfiguration.class) .withPropertyValues("management.health.defaults.enabled:false", "management.health.ping.enabled:true") .run((context) -> assertThat(context).hasSingleBean(PingHealthIndicator.class)); - } @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorNameGeneratorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorNameGeneratorTests.java new file mode 100644 index 000000000000..aa0e1767cdf8 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorNameGeneratorTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.autoconfigure.registry; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link HealthContributorNameGenerator}. + * + * @author Phillip Webb + */ +class HealthContributorNameGeneratorTests { + + @Test + void withoutStandardSuffixesWhenNameDoesNotEndWithSuffixReturnsName() { + assertThat(HealthContributorNameGenerator.withoutStandardSuffixes().generateContributorName("test")) + .isEqualTo("test"); + } + + @Test + void withoutStandardSuffixesWhenNameEndsWithSuffixReturnsNewName() { + assertThat( + HealthContributorNameGenerator.withoutStandardSuffixes().generateContributorName("testHealthIndicator")) + .isEqualTo("test"); + assertThat(HealthContributorNameGenerator.withoutStandardSuffixes() + .generateContributorName("testHealthContributor")).isEqualTo("test"); + } + + @Test + void withoutStandardSuffixesWhenNameEndsWithSuffixInDifferentReturnsNewName() { + assertThat( + HealthContributorNameGenerator.withoutStandardSuffixes().generateContributorName("testHEALTHindicator")) + .isEqualTo("test"); + assertThat(HealthContributorNameGenerator.withoutStandardSuffixes() + .generateContributorName("testHEALTHcontributor")).isEqualTo("test"); + } + + @Test + void withoutStandardSuffixesWhenNameContainsSuffixReturnsName() { + assertThat(HealthContributorNameGenerator.withoutStandardSuffixes() + .generateContributorName("testHealthIndicatorTest")).isEqualTo("testHealthIndicatorTest"); + assertThat(HealthContributorNameGenerator.withoutStandardSuffixes() + .generateContributorName("testHealthContributorTest")).isEqualTo("testHealthContributorTest"); + } + + @Test + void withoutSuffixesStripsSuffix() { + HealthContributorNameGenerator generator = HealthContributorNameGenerator.withoutSuffixes("spring", "boot"); + assertThat(generator.generateContributorName("testspring")).isEqualTo("test"); + assertThat(generator.generateContributorName("tEsTsPrInG")).isEqualTo("tEsT"); + assertThat(generator.generateContributorName("springboot")).isEqualTo("spring"); + assertThat(generator.generateContributorName("springspring")).isEqualTo("spring"); + assertThat(generator.generateContributorName("test")).isEqualTo("test"); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorRegistryAutoConfigurationTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorRegistryAutoConfigurationTests.java new file mode 100644 index 000000000000..6278ac341258 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/registry/HealthContributorRegistryAutoConfigurationTests.java @@ -0,0 +1,157 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.autoconfigure.registry; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributors; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributors; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; +import org.springframework.boot.health.registry.DefaultHealthContributorRegistry; +import org.springframework.boot.health.registry.DefaultReactiveHealthContributorRegistry; +import org.springframework.boot.health.registry.HealthContributorRegistry; +import org.springframework.boot.health.registry.ReactiveHealthContributorRegistry; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link HealthContributorRegistryAutoConfiguration}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Stephane Nicoll + * @author Scott Frederick + */ +class HealthContributorRegistryAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withUserConfiguration(HealthIndicatorsConfiguration.class) + .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class)); + + @Test + void runCreatesHealthContributorRegistryContainingHealthBeans() { + this.contextRunner.run((context) -> { + HealthContributorRegistry registry = context.getBean(HealthContributorRegistry.class); + Object[] names = registry.stream().map(HealthContributors.Entry::name).toArray(); + assertThat(names).containsExactlyInAnyOrder("simple", "additional", "ping", "reactive"); + }); + } + + @Test + void runWhenNoReactorCreatesHealthContributorRegistryContainingHealthBeans() { + ClassLoader classLoader = new FilteredClassLoader(Mono.class, Flux.class); + this.contextRunner.withClassLoader(classLoader).run((context) -> { + HealthContributorRegistry registry = context.getBean(HealthContributorRegistry.class); + Object[] names = registry.stream().map(HealthContributors.Entry::name).toArray(); + assertThat(names).containsExactlyInAnyOrder("simple", "additional", "ping"); + }); + } + + @Test + void runWhenHasHealthContributorRegistryBeanDoesNotCreateAdditionalRegistry() { + this.contextRunner.withUserConfiguration(HealthContributorRegistryConfiguration.class).run((context) -> { + HealthContributorRegistry registry = context.getBean(HealthContributorRegistry.class); + Object[] names = registry.stream().map(HealthContributors.Entry::name).toArray(); + assertThat(names).isEmpty(); + }); + } + + @Test + void runCreatesReactiveHealthContributorRegistryContainingAdaptedBeans() { + this.contextRunner.run((context) -> { + ReactiveHealthContributorRegistry registry = context.getBean(ReactiveHealthContributorRegistry.class); + Object[] names = registry.stream().map(ReactiveHealthContributors.Entry::name).toArray(); + assertThat(names).containsExactlyInAnyOrder("simple", "additional", "reactive", "ping"); + }); + } + + @Test + void runWhenHasReactiveHealthContributorRegistryBeanDoesNotCreateAdditionalReactiveHealthContributorRegistry() { + this.contextRunner.withUserConfiguration(ReactiveHealthContributorRegistryConfiguration.class) + .run((context) -> { + ReactiveHealthContributorRegistry registry = context.getBean(ReactiveHealthContributorRegistry.class); + Object[] names = registry.stream().map(ReactiveHealthContributors.Entry::name).toArray(); + assertThat(names).isEmpty(); + }); + } + + @Test + void runWithIndicatorsInParentContextFindsIndicators() { + new ApplicationContextRunner().withUserConfiguration(HealthIndicatorsConfiguration.class) + .run((parent) -> new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class)) + .withParent(parent) + .run((context) -> { + HealthContributorRegistry registry = context.getBean(HealthContributorRegistry.class); + Object[] names = registry.stream().map(HealthContributors.Entry::name).toArray(); + assertThat(names).containsExactlyInAnyOrder("simple", "additional", "reactive", "ping"); + })); + } + + @Configuration(proxyBeanMethods = false) + static class HealthIndicatorsConfiguration { + + @Bean + HealthIndicator simpleHealthIndicator() { + return () -> Health.up().withDetail("counter", 42).build(); + } + + @Bean + HealthIndicator additionalHealthIndicator() { + return () -> Health.up().build(); + } + + @Bean + ReactiveHealthIndicator reactiveHealthIndicator() { + return () -> Mono.just(Health.up().build()); + } + + } + + @Configuration(proxyBeanMethods = false) + static class HealthContributorRegistryConfiguration { + + @Bean + HealthContributorRegistry healthContributorRegistry() { + return new DefaultHealthContributorRegistry(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ReactiveHealthContributorRegistryConfiguration { + + @Bean + ReactiveHealthContributorRegistry reactiveHealthContributorRegistry() { + return new DefaultReactiveHealthContributorRegistry(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/AbstractHealthIndicatorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractHealthIndicatorTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/AbstractHealthIndicatorTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractHealthIndicatorTests.java index 23c72da517d3..6cf814488efb 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/AbstractHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractHealthIndicatorTests.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.function.Consumer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.actuate.health.Health.Builder; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; @@ -38,7 +37,7 @@ class AbstractHealthIndicatorTests { @Test void healthCheckWhenUpDoesNotLogHealthCheckFailedMessage(CapturedOutput output) { - TestHealthIndicator indicator = new TestHealthIndicator("Test message", Builder::up); + TestHealthIndicator indicator = new TestHealthIndicator("Test message", Health.Builder::up); Health heath = indicator.health(); assertThat(heath.getStatus()).isEqualTo(Status.UP); assertThat(output).doesNotContain("Test message"); @@ -95,19 +94,19 @@ void healthCheckWhenDownWithErrorLogsDefaultMessage(CapturedOutput output) { static class TestHealthIndicator extends AbstractHealthIndicator { - private final Consumer action; + private final Consumer action; - TestHealthIndicator(String message, Consumer action) { + TestHealthIndicator(String message, Consumer action) { super(message); this.action = action; } - TestHealthIndicator(Consumer action) { + TestHealthIndicator(Consumer action) { this.action = action; } @Override - protected void doHealthCheck(Builder builder) throws Exception { + protected void doHealthCheck(Health.Builder builder) throws Exception { this.action.accept(builder); } diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractMapAdapterTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractMapAdapterTests.java new file mode 100644 index 000000000000..28b30bc53fa1 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractMapAdapterTests.java @@ -0,0 +1,143 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +/** + * Tests for {@link AbstractMapAdapter}. + * + * @author Phillip Webb + * @author Guirong Hu + */ +class AbstractMapAdapterTests { + + @Test + void createWhenMapIsNullThrowsException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(null, Function.identity())) + .withMessage("'map' must not be null"); + } + + @Test + void createWhenValueAdapterIsNullThrowsException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(Collections.emptyMap(), null)) + .withMessage("'valueAdapter' must not be null"); + } + + @Test + void createWhenMapContainsNullValueThrowsException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(Collections.singletonMap("test", null), + Function.identity())) + .withMessage("'map' must not contain null values"); + } + + @Test + void createWhenMapContainsNullKeyThrowsException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(Collections.singletonMap(null, "test"), + Function.identity())) + .withMessage("'map' must not contain null keys"); + } + + @Test + void createWhenMapContainsKeyWithSlashThrowsException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new TestNamedContributorsMapAdapter<>(Collections.singletonMap("test/key", "test"), + Function.identity())) + .withMessage("'map' keys must not contain a '/'"); + } + + @Test + void iterateReturnsAdaptedEntries() { + TestNamedContributorsMapAdapter adapter = createAdapter(); + Iterator> iterator = adapter.iterator(); + Map.Entry one = iterator.next(); + Map.Entry two = iterator.next(); + assertThat(iterator.hasNext()).isFalse(); + assertThat(one.getKey()).isEqualTo("one"); + assertThat(one.getValue()).isEqualTo("eno"); + assertThat(two.getKey()).isEqualTo("two"); + assertThat(two.getValue()).isEqualTo("owt"); + } + + @Test + void getContributorReturnsAdaptedEntry() { + TestNamedContributorsMapAdapter adapter = createAdapter(); + assertThat(adapter.getContributor("one")).isEqualTo("eno"); + assertThat(adapter.getContributor("two")).isEqualTo("owt"); + } + + @Test + void getContributorCallsAdaptersOnlyOnce() { + Map map = new LinkedHashMap<>(); + map.put("one", "one"); + map.put("two", "two"); + int callCount = map.size(); + AtomicInteger counter = new AtomicInteger(0); + TestNamedContributorsMapAdapter adapter = new TestNamedContributorsMapAdapter<>(map, + (name) -> count(name, counter)); + assertThat(adapter.getContributor("one")).isEqualTo("eno"); + assertThat(counter.get()).isEqualTo(callCount); + assertThat(adapter.getContributor("two")).isEqualTo("owt"); + assertThat(counter.get()).isEqualTo(callCount); + } + + @Test + void getContributorWhenNotInMapReturnsNull() { + TestNamedContributorsMapAdapter adapter = createAdapter(); + assertThat(adapter.getContributor("missing")).isNull(); + } + + private TestNamedContributorsMapAdapter createAdapter() { + Map map = new LinkedHashMap<>(); + map.put("one", "one"); + map.put("two", "two"); + TestNamedContributorsMapAdapter adapter = new TestNamedContributorsMapAdapter<>(map, this::reverse); + return adapter; + } + + private String count(CharSequence charSequence, AtomicInteger counter) { + counter.incrementAndGet(); + return reverse(charSequence); + } + + private String reverse(CharSequence charSequence) { + return new StringBuilder(charSequence).reverse().toString(); + } + + static class TestNamedContributorsMapAdapter extends AbstractMapAdapter> { + + TestNamedContributorsMapAdapter(Map map, Function valueAdapter) { + super(map, valueAdapter, Map::entry); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/AbstractReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractReactiveHealthIndicatorTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/AbstractReactiveHealthIndicatorTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractReactiveHealthIndicatorTests.java index 06ef82317f34..cdaf13decbb7 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/AbstractReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/AbstractReactiveHealthIndicatorTests.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.health.Health.Builder; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; @@ -30,6 +29,8 @@ * Tests for {@link AbstractReactiveHealthIndicator}. * * @author Moritz Halbritter + * @author Dmytro Nosan + * @author Stephane Nicoll */ @ExtendWith(OutputCaptureExtension.class) class AbstractReactiveHealthIndicatorTests { @@ -37,8 +38,9 @@ class AbstractReactiveHealthIndicatorTests { @Test void healthCheckWhenUpDoesNotLogHealthCheckFailedMessage(CapturedOutput output) { Health health = new AbstractReactiveHealthIndicator("Test message") { + @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { return Mono.just(builder.up().build()); } @@ -51,10 +53,12 @@ protected Mono doHealthCheck(Builder builder) { @Test void healthCheckWhenDownWithExceptionThrownLogsHealthCheckFailedMessage(CapturedOutput output) { Health health = new AbstractReactiveHealthIndicator("Test message") { + @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { throw new IllegalStateException("Test exception"); } + }.health().block(); assertThat(health).isNotNull(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); @@ -64,10 +68,12 @@ protected Mono doHealthCheck(Builder builder) { @Test void healthCheckWhenDownWithExceptionConfiguredLogsHealthCheckFailedMessage(CapturedOutput output) { Health health = new AbstractReactiveHealthIndicator("Test message") { + @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { return Mono.just(builder.down().withException(new IllegalStateException("Test exception")).build()); } + }.health().block(); assertThat(health).isNotNull(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); @@ -77,12 +83,14 @@ protected Mono doHealthCheck(Builder builder) { @Test void healthCheckWhenDownWithExceptionConfiguredDoesNotLogHealthCheckFailedMessageTwice(CapturedOutput output) { Health health = new AbstractReactiveHealthIndicator("Test message") { + @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { IllegalStateException ex = new IllegalStateException("Test exception"); builder.down().withException(ex); throw ex; } + }.health().block(); assertThat(health).isNotNull(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); @@ -92,10 +100,12 @@ protected Mono doHealthCheck(Builder builder) { @Test void healthCheckWhenDownWithExceptionAndNoFailureMessageLogsDefaultMessage(CapturedOutput output) { Health health = new AbstractReactiveHealthIndicator() { + @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { return Mono.just(builder.down().withException(new IllegalStateException("Test exception")).build()); } + }.health().block(); assertThat(health).isNotNull(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); @@ -105,10 +115,12 @@ protected Mono doHealthCheck(Builder builder) { @Test void healthCheckWhenDownWithErrorLogsDefaultMessage(CapturedOutput output) { Health health = new AbstractReactiveHealthIndicator("Test Message") { + @Override - protected Mono doHealthCheck(Builder builder) { + protected Mono doHealthCheck(Health.Builder builder) { return Mono.just(builder.down().withException(new Error("Test error")).build()); } + }.health().block(); assertThat(health).isNotNull(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthContributorReactiveAdapterTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthContributorReactiveAdapterTests.java similarity index 80% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthContributorReactiveAdapterTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthContributorReactiveAdapterTests.java index c6a5257678af..87853e4e837a 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthContributorReactiveAdapterTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthContributorReactiveAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.Collections; import java.util.Iterator; @@ -43,12 +43,12 @@ void iteratorWhenDelegateContainsHealthIndicatorAdaptsDelegate() { CompositeHealthContributor delegate = CompositeHealthContributor .fromMap(Collections.singletonMap("test", indicator)); CompositeHealthContributorReactiveAdapter adapter = new CompositeHealthContributorReactiveAdapter(delegate); - Iterator> iterator = adapter.iterator(); + Iterator iterator = adapter.iterator(); assertThat(iterator.hasNext()).isTrue(); - NamedContributor adapted = iterator.next(); - assertThat(adapted.getName()).isEqualTo("test"); - assertThat(adapted.getContributor()).isInstanceOf(ReactiveHealthIndicator.class); - Health health = ((ReactiveHealthIndicator) adapted.getContributor()).getHealth(true).block(); + ReactiveHealthContributors.Entry adapted = iterator.next(); + assertThat(adapted.name()).isEqualTo("test"); + assertThat(adapted.contributor()).isInstanceOf(ReactiveHealthIndicator.class); + Health health = ((ReactiveHealthIndicator) adapted.contributor()).getHealth(true).block(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getDetails()).containsEntry("spring", "boot"); } @@ -61,12 +61,12 @@ void iteratorWhenDelegateContainsCompositeHealthContributorAdaptsDelegate() { CompositeHealthContributor delegate = CompositeHealthContributor .fromMap(Collections.singletonMap("test2", composite)); CompositeHealthContributorReactiveAdapter adapter = new CompositeHealthContributorReactiveAdapter(delegate); - Iterator> iterator = adapter.iterator(); + Iterator iterator = adapter.iterator(); assertThat(iterator.hasNext()).isTrue(); - NamedContributor adapted = iterator.next(); - assertThat(adapted.getName()).isEqualTo("test2"); - assertThat(adapted.getContributor()).isInstanceOf(CompositeReactiveHealthContributor.class); - ReactiveHealthContributor nested = ((CompositeReactiveHealthContributor) adapted.getContributor()) + ReactiveHealthContributors.Entry adapted = iterator.next(); + assertThat(adapted.name()).isEqualTo("test2"); + assertThat(adapted.contributor()).isInstanceOf(CompositeReactiveHealthContributor.class); + ReactiveHealthContributor nested = ((CompositeReactiveHealthContributor) adapted.contributor()) .getContributor("test1"); Health health = ((ReactiveHealthIndicator) nested).getHealth(true).block(); assertThat(health.getStatus()).isEqualTo(Status.UP); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthContributorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthContributorTests.java similarity index 78% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthContributorTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthContributorTests.java index 401ef576c48a..a2266d2330b2 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/CompositeHealthContributorTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthContributorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.LinkedHashMap; import java.util.Map; @@ -27,6 +27,7 @@ * Tests for {@link CompositeHealthContributor}. * * @author Phillip Webb + * @author Guirong Hu */ class CompositeHealthContributorTests { @@ -37,9 +38,9 @@ void fromMapReturnsCompositeHealthContributorMapAdapter() { map.put("test", indicator); CompositeHealthContributor composite = CompositeHealthContributor.fromMap(map); assertThat(composite).isInstanceOf(CompositeHealthContributorMapAdapter.class); - NamedContributor namedContributor = composite.iterator().next(); - assertThat(namedContributor.getName()).isEqualTo("test"); - assertThat(namedContributor.getContributor()).isSameAs(indicator); + HealthContributors.Entry entry = composite.iterator().next(); + assertThat(entry.name()).isEqualTo("test"); + assertThat(entry.contributor()).isSameAs(indicator); } @Test @@ -50,9 +51,9 @@ void fromMapWithAdapterReturnsCompositeHealthContributorMapAdapter() { map.put("test", downIndicator); CompositeHealthContributor composite = CompositeHealthContributor.fromMap(map, (value) -> upIndicator); assertThat(composite).isInstanceOf(CompositeHealthContributorMapAdapter.class); - NamedContributor namedContributor = composite.iterator().next(); - assertThat(namedContributor.getName()).isEqualTo("test"); - assertThat(namedContributor.getContributor()).isSameAs(upIndicator); + HealthContributors.Entry entry = composite.iterator().next(); + assertThat(entry.name()).isEqualTo("test"); + assertThat(entry.contributor()).isSameAs(upIndicator); } } diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthTests.java new file mode 100644 index 000000000000..fca2e7ebd8ff --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeHealthTests.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +/** + * Test for {@link CompositeHealth}. + * + * @author Phillip Webb + */ +class CompositeHealthTests { + + @Test + void createWhenStatusIsNullThrowsException() { + assertThatIllegalArgumentException().isThrownBy(() -> new CompositeHealth(null, Collections.emptyMap())) + .withMessage("'status' must not be null"); + } + + @Test + void getStatusReturnsStatus() { + CompositeHealth health = new CompositeHealth(Status.UP, Collections.emptyMap()); + assertThat(health.getStatus()).isEqualTo(Status.UP); + } + + @Test + void getComponentReturnsComponents() { + Map components = new LinkedHashMap<>(); + components.put("a", Health.up().build()); + CompositeHealth health = new CompositeHealth(Status.UP, components); + assertThat(health.getComponents()).isEqualTo(components); + } + + @Test + void serializeWithJacksonReturnsValidJson() throws Exception { + Map components = new LinkedHashMap<>(); + components.put("db1", Health.up().build()); + components.put("db2", Health.down().withDetail("a", "b").build()); + CompositeHealth health = new CompositeHealth(Status.UP, components); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(health); + assertThat(json).isEqualTo("{\"status\":\"UP\",\"components\":{\"db1\":{\"status\":\"UP\"}," + + "\"db2\":{\"status\":\"DOWN\",\"details\":{\"a\":\"b\"}}}}"); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributorTests.java new file mode 100644 index 000000000000..60f4dcf02e59 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/CompositeReactiveHealthContributorTests.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CompositeReactiveHealthContributor}. + * + * @author Phillip Webb + */ +class CompositeReactiveHealthContributorTests { + + @Test + void asHealthContributorReturnsAdaptedContributor() { + ReactiveHealthIndicator indicator = () -> Mono.just(Health.up().withDetail("spring", "boot").build()); + Map reactiveContributors = Map.of("test", indicator); + CompositeReactiveHealthContributor contributor = CompositeReactiveHealthContributor + .fromMap(reactiveContributors); + CompositeHealthContributor adapted = contributor.asHealthContributor(); + HealthIndicator byName = (HealthIndicator) adapted.getContributor("test"); + assertThat(byName.getHealth(true).getDetails()).containsEntry("spring", "boot"); + HealthContributors.Entry entry = adapted.iterator().next(); + assertThat(entry.name()).isEqualTo("test"); + HealthIndicator byEntry = (HealthIndicator) entry.contributor(); + assertThat(byEntry.getHealth(true).getDetails()).containsEntry("spring", "boot"); + } + + @Test + void fromMapReturnsCompositeReactiveHealthContributorMapAdapter() { + Map map = new LinkedHashMap<>(); + ReactiveHealthIndicator indicator = () -> Mono.just(Health.down().build()); + map.put("test", indicator); + CompositeReactiveHealthContributor composite = CompositeReactiveHealthContributor.fromMap(map); + assertThat(composite).isInstanceOf(CompositeReactiveHealthContributorMapAdapter.class); + ReactiveHealthContributors.Entry entry = composite.iterator().next(); + assertThat(entry.name()).isEqualTo("test"); + assertThat(entry.contributor()).isSameAs(indicator); + } + + @Test + void fromMapWithAdapterReturnsCompositeReactiveHealthContributorMapAdapter() { + Map map = new LinkedHashMap<>(); + ReactiveHealthIndicator downIndicator = () -> Mono.just(Health.down().build()); + ReactiveHealthIndicator upIndicator = () -> Mono.just(Health.up().build()); + map.put("test", downIndicator); + CompositeReactiveHealthContributor composite = CompositeReactiveHealthContributor.fromMap(map, + (value) -> upIndicator); + assertThat(composite).isInstanceOf(CompositeReactiveHealthContributorMapAdapter.class); + ReactiveHealthContributors.Entry entry = composite.iterator().next(); + assertThat(entry.name()).isEqualTo("test"); + assertThat(entry.contributor()).isSameAs(upIndicator); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthContributorsTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthContributorsTests.java new file mode 100644 index 000000000000..21f7bf38a8b2 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthContributorsTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Iterator; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.health.contributor.HealthContributors.Entry; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link HealthContributors}. + * + * @author Phillip Webb + */ +class HealthContributorsTests { + + @Test + void streamAdaptsIterator() { + Entry e1 = new Entry("e1", mock(HealthIndicator.class)); + Entry e2 = new Entry("e2", mock(HealthIndicator.class)); + HealthContributors contributors = new HealthContributors() { + + @Override + public Iterator iterator() { + return List.of(e1, e2).iterator(); + } + + @Override + public HealthContributor getContributor(String name) { + return null; + } + + }; + assertThat(contributors.stream()).containsExactly(e1, e2); + } + + @Test + void createEntryWhenNameIsEmptyThrowsException() { + assertThatIllegalArgumentException().isThrownBy(() -> new Entry("", mock(HealthIndicator.class))) + .withMessage("'name' must not be empty"); + } + + @Test + void createEntryWhenContributorIsNullThrowsException() { + assertThatIllegalArgumentException().isThrownBy(() -> new Entry("test", null)) + .withMessage("'contributor' must not be null"); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthIndicatorReactiveAdapterTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthIndicatorReactiveAdapterTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthIndicatorReactiveAdapterTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthIndicatorReactiveAdapterTests.java index bedaa9f75802..6a0b14a21424 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthIndicatorReactiveAdapterTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthIndicatorReactiveAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthIndicatorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthIndicatorTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthIndicatorTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthIndicatorTests.java index 7e874074665a..0b0c8d69830f 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthTests.java similarity index 99% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthTests.java index 46a7faa9d8ad..dfe1f3ffa1e6 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/HealthTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.Collections; import java.util.LinkedHashMap; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/PingHealthIndicatorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/PingHealthIndicatorTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/PingHealthIndicatorTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/PingHealthIndicatorTests.java index e6c570898669..bb9ca60905a0 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/PingHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/PingHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthContributorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthContributorTests.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthContributorTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthContributorTests.java index be1227dfea46..a247d8ccc102 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthContributorTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthContributorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import java.util.Collections; @@ -22,13 +22,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.mockito.Mockito.mock; /** * Tests for {@link ReactiveHealthContributor}. * * @author Phillip Webb + * @author Stephane Nicoll */ class ReactiveHealthContributorTests { @@ -57,11 +56,4 @@ void adaptWhenCompositeHealthContributorReturnsCompositeHealthContributorReactiv assertThat(((ReactiveHealthIndicator) contained).health().block().getStatus()).isEqualTo(Status.OUT_OF_SERVICE); } - @Test - void adaptWhenUnknownThrowsException() { - assertThatIllegalStateException() - .isThrownBy(() -> ReactiveHealthContributor.adapt(mock(HealthContributor.class))) - .withMessage("Unknown HealthContributor type"); - } - } diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthContributorsTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthContributorsTests.java new file mode 100644 index 000000000000..f4b1f3c553e9 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthContributorsTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.contributor; + +import java.util.Iterator; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.health.contributor.ReactiveHealthContributors.Entry; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link ReactiveHealthContributors}. + * + * @author Phillip Webb + */ +class ReactiveHealthContributorsTests { + + @Test + void streamAdaptsIterator() { + Entry e1 = new Entry("e1", mock(ReactiveHealthIndicator.class)); + Entry e2 = new Entry("e2", mock(ReactiveHealthIndicator.class)); + ReactiveHealthContributors contributors = new ReactiveHealthContributors() { + + @Override + public Iterator iterator() { + return List.of(e1, e2).iterator(); + } + + @Override + public ReactiveHealthContributor getContributor(String name) { + return null; + } + + }; + assertThat(contributors.stream()).containsExactly(e1, e2); + } + + @Test + void createEntryWhenNameIsEmptyThrowsException() { + assertThatIllegalArgumentException().isThrownBy(() -> new Entry("", mock(ReactiveHealthIndicator.class))) + .withMessage("'name' must not be empty"); + } + + @Test + void createEntryWhenContributorIsNullThrowsException() { + assertThatIllegalArgumentException().isThrownBy(() -> new Entry("test", null)) + .withMessage("'contributor' must not be null"); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthIndicatorTests.java similarity index 86% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthIndicatorTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthIndicatorTests.java index d81eca0d3045..3e951b0e34ad 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/ReactiveHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; @@ -30,6 +30,12 @@ class ReactiveHealthIndicatorTests { private final ReactiveHealthIndicator indicator = () -> Mono.just(Health.up().withDetail("spring", "boot").build()); + @Test + void asHealthContributor() { + HealthIndicator adapted = this.indicator.asHealthContributor(); + assertThat(adapted.getHealth(true).getDetails()).containsEntry("spring", "boot"); + } + @Test void getHealthWhenIncludeDetailsIsTrueReturnsHealthWithDetails() { Health health = this.indicator.getHealth(true).block(); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/StatusTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/StatusTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/StatusTests.java rename to spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/StatusTests.java index 8fb7f770f1dc..92ba26c4a223 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/StatusTests.java +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/contributor/StatusTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.health; +package org.springframework.boot.health.contributor; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/AbstractHealthContributorRegistryTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/AbstractHealthContributorRegistryTests.java new file mode 100644 index 000000000000..936225013e5c --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/AbstractHealthContributorRegistryTests.java @@ -0,0 +1,163 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.util.Assert; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link AbstractHealthContributorRegistry}. + * + * @param the contributor type + * @param the entry type + * @author Phillip Webb + * @author Vedran Pavic + * @author Stephane Nicoll + */ +abstract class AbstractHealthContributorRegistryTests { + + private AbstractHealthContributorRegistry registry; + + @BeforeEach + void setUp() { + this.registry = createRegistry(Collections.emptyMap(), Collections.emptyList()); + } + + @Test + void createWhenContributorsIsNullThrowsException() { + assertThatIllegalArgumentException().isThrownBy(() -> createRegistry(null, Collections.emptyList())) + .withMessage("'contributors' must not be null"); + } + + @Test + void registerContributorWhenNameIsNullThrowsException() { + assertThatIllegalArgumentException() + .isThrownBy(() -> this.registry.registerContributor(null, mockHealthIndicator())) + .withMessage("'name' must not be empty"); + } + + @Test + void registerContributorWhenContributorIsNullThrowsException() { + assertThatIllegalArgumentException().isThrownBy(() -> this.registry.registerContributor("one", null)) + .withMessage("'contributor' must not be null"); + } + + @Test + void registerContributorRegistersContributors() { + C c1 = mockHealthIndicator(); + C c2 = mockHealthIndicator(); + this.registry.registerContributor("one", c1); + this.registry.registerContributor("two", c2); + assertThat((Iterable) this.registry).hasSize(2); + assertThat(this.registry.getContributor("one")).isSameAs(c1); + assertThat(this.registry.getContributor("two")).isSameAs(c2); + } + + @Test + void registerContributorWhenNameAlreadyUsedThrowsException() { + this.registry.registerContributor("one", mockHealthIndicator()); + assertThatIllegalStateException() + .isThrownBy(() -> this.registry.registerContributor("one", mockHealthIndicator())) + .withMessageContaining("A contributor named \"one\" has already been registered"); + } + + @Test + void unregisterContributorUnregistersContributor() { + C c1 = mockHealthIndicator(); + C c2 = mockHealthIndicator(); + this.registry.registerContributor("one", c1); + this.registry.registerContributor("two", c2); + assertThat((Iterable) this.registry).hasSize(2); + C two = this.registry.unregisterContributor("two"); + assertThat(two).isSameAs(c2); + assertThat((Iterable) this.registry).hasSize(1); + } + + @Test + void unregisterContributorWhenUnknownReturnsNull() { + this.registry.registerContributor("one", mockHealthIndicator()); + assertThat((Iterable) this.registry).hasSize(1); + Object two = this.registry.unregisterContributor("two"); + assertThat(two).isNull(); + assertThat((Iterable) this.registry).hasSize(1); + } + + @Test + void getContributorReturnsContributor() { + C c1 = mockHealthIndicator(); + this.registry.registerContributor("one", c1); + assertThat(this.registry.getContributor("one")).isEqualTo(c1); + } + + @Test + void iteratorIteratesContributors() { + C c1 = mockHealthIndicator(); + C c2 = mockHealthIndicator(); + this.registry.registerContributor("one", c1); + this.registry.registerContributor("two", c2); + Iterator iterator = this.registry.iterator(); + E first = iterator.next(); + E second = iterator.next(); + assertThat(iterator.hasNext()).isFalse(); + assertThat(name(first)).isEqualTo("one"); + assertThat(contributor(first)).isEqualTo(c1); + assertThat(name(second)).isEqualTo("two"); + assertThat(contributor(second)).isEqualTo(c2); + } + + @Test + void nameValidatorsValidateMapKeys() { + assertThatIllegalStateException() + .isThrownBy(() -> createRegistry(Map.of("ok", mockHealthIndicator(), "fail", mockHealthIndicator()), + testValidator())) + .withMessage("Failed validation"); + } + + @Test + void nameValidatorsValidateRegisteredName() { + AbstractHealthContributorRegistry registry = createRegistry(Collections.emptyMap(), testValidator()); + registry.registerContributor("ok", mockHealthIndicator()); + assertThatIllegalStateException().isThrownBy(() -> registry.registerContributor("fail", mockHealthIndicator())) + .withMessage("Failed validation"); + } + + private List testValidator() { + return List.of((name) -> Assert.state(!"fail".equals(name), "Failed validation")); + } + + protected abstract AbstractHealthContributorRegistry createRegistry(Map contributors, + Collection nameValidators); + + protected abstract C mockHealthIndicator(); + + protected abstract String name(E entry); + + protected abstract C contributor(E entry); + +} diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/DefaultHealthContributorRegistryTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/DefaultHealthContributorRegistryTests.java new file mode 100644 index 000000000000..df383415616f --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/DefaultHealthContributorRegistryTests.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +import java.util.Collection; +import java.util.Map; + +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthContributors; +import org.springframework.boot.health.contributor.HealthContributors.Entry; +import org.springframework.boot.health.contributor.HealthIndicator; + +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link DefaultHealthContributorRegistry}. + * + * @author Phillip Webb + */ +class DefaultHealthContributorRegistryTests + extends AbstractHealthContributorRegistryTests { + + @Override + protected AbstractHealthContributorRegistry createRegistry( + Map contributors, + Collection nameValidators) { + return new DefaultHealthContributorRegistry(contributors, nameValidators); + } + + @Override + protected HealthContributor mockHealthIndicator() { + return mock(HealthIndicator.class); + } + + @Override + protected String name(Entry entry) { + return entry.name(); + } + + @Override + protected HealthContributor contributor(Entry entry) { + return entry.contributor(); + } + +} diff --git a/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/DefaultReactiveHealthContributorRegistryTests.java b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/DefaultReactiveHealthContributorRegistryTests.java new file mode 100644 index 000000000000..b8e0efaeb2f7 --- /dev/null +++ b/spring-boot-project/spring-boot-health/src/test/java/org/springframework/boot/health/registry/DefaultReactiveHealthContributorRegistryTests.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.health.registry; + +import java.util.Collection; +import java.util.Map; + +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributors; +import org.springframework.boot.health.contributor.ReactiveHealthContributors.Entry; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; + +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link DefaultReactiveHealthContributorRegistry}. + * + * @author Phillip Webb + */ +class DefaultReactiveHealthContributorRegistryTests + extends AbstractHealthContributorRegistryTests { + + @Override + protected AbstractHealthContributorRegistry createRegistry( + Map contributors, + Collection nameValidators) { + return new DefaultReactiveHealthContributorRegistry(contributors, nameValidators); + } + + @Override + protected ReactiveHealthContributor mockHealthIndicator() { + return mock(ReactiveHealthIndicator.class); + } + + @Override + protected String name(Entry entry) { + return entry.name(); + } + + @Override + protected ReactiveHealthContributor contributor(Entry entry) { + return entry.contributor(); + } + +} diff --git a/spring-boot-project/spring-boot-hibernate/build.gradle b/spring-boot-project/spring-boot-hibernate/build.gradle new file mode 100644 index 000000000000..b89329149b81 --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/build.gradle @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Hibernate" + +dependencies { + api(project(":spring-boot-project:spring-boot-jpa")) + api("org.hibernate.orm:hibernate-core") + api("org.springframework:spring-orm") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional("org.hibernate.orm:hibernate-micrometer") + + testImplementation(project(":spring-boot-project:spring-boot-flyway")) + testImplementation(project(":spring-boot-project:spring-boot-liquibase")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("com.zaxxer:HikariCP") + testImplementation("javax.cache:cache-api") + testImplementation("org.ehcache:ehcache") { + artifact { + classifier = 'jakarta' + } + } + testImplementation("jakarta.servlet:jakarta.servlet-api") + testImplementation("org.hibernate.orm:hibernate-envers") + testImplementation("org.hibernate.orm:hibernate-jcache") + testImplementation("org.springframework:spring-context-support") + testImplementation("org.springframework:spring-webmvc") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringImplicitNamingStrategy.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/SpringImplicitNamingStrategy.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringImplicitNamingStrategy.java rename to spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/SpringImplicitNamingStrategy.java index d107419a54ce..b4e62ff85d82 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringImplicitNamingStrategy.java +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/SpringImplicitNamingStrategy.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.orm.jpa.hibernate; +package org.springframework.boot.hibernate; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.ImplicitJoinTableNameSource; @@ -29,7 +29,7 @@ * {owning_physical_table_name}_{association_owning_property_name}. * * @author Andy Wilkinson - * @since 1.4.0 + * @since 4.0.0 */ public class SpringImplicitNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringJtaPlatform.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/SpringJtaPlatform.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringJtaPlatform.java rename to spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/SpringJtaPlatform.java index 5f54cf0d9310..8ca99dfca8d2 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/SpringJtaPlatform.java +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/SpringJtaPlatform.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.orm.jpa.hibernate; +package org.springframework.boot.hibernate; import jakarta.transaction.TransactionManager; import jakarta.transaction.UserTransaction; @@ -30,7 +30,7 @@ * * @author Josh Long * @author Phillip Webb - * @since 1.2.0 + * @since 4.0.0 */ public class SpringJtaPlatform extends AbstractJtaPlatform { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateDefaultDdlAutoProvider.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateDefaultDdlAutoProvider.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateDefaultDdlAutoProvider.java rename to spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateDefaultDdlAutoProvider.java index 422529ab7a8a..76bba1fd072a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateDefaultDdlAutoProvider.java +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateDefaultDdlAutoProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure; import java.util.stream.StreamSupport; diff --git a/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfiguration.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfiguration.java new file mode 100644 index 000000000000..a65a66ccca4d --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfiguration.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.hibernate.autoconfigure; + +import jakarta.persistence.EntityManager; +import org.hibernate.engine.spi.SessionImplementor; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jpa.autoconfigure.JpaProperties; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration; +import org.springframework.boot.transaction.jta.autoconfigure.JtaAutoConfiguration; +import org.springframework.context.annotation.Import; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Hibernate JPA. + * + * @author Phillip Webb + * @author Josh Long + * @author Manuel Doninger + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration( + after = { DataSourceAutoConfiguration.class, JtaAutoConfiguration.class, + TransactionManagerCustomizationAutoConfiguration.class }, + before = { TransactionAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class }) +@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EntityManager.class, SessionImplementor.class }) +@EnableConfigurationProperties(JpaProperties.class) +@Import(HibernateJpaConfiguration.class) +public class HibernateJpaAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java rename to spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaConfiguration.java index 5445120a69b0..bd5a67218bab 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure; import java.util.ArrayList; import java.util.Arrays; @@ -43,14 +43,16 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration.HibernateRuntimeHints; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.hibernate.SpringImplicitNamingStrategy; +import org.springframework.boot.hibernate.SpringJtaPlatform; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaConfiguration.HibernateRuntimeHints; import org.springframework.boot.jdbc.SchemaManagementProvider; import org.springframework.boot.jdbc.metadata.CompositeDataSourcePoolMetadataProvider; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadata; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; -import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; -import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform; +import org.springframework.boot.jpa.autoconfigure.JpaBaseConfiguration; +import org.springframework.boot.jpa.autoconfigure.JpaProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.jdbc.support.SQLExceptionTranslator; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateProperties.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateProperties.java rename to spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateProperties.java index 22da2b648f4e..8747597d1281 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateProperties.java +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure; import java.util.Collection; import java.util.HashMap; @@ -27,7 +27,8 @@ import org.hibernate.cfg.SchemaToolingSettings; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; +import org.springframework.boot.hibernate.SpringImplicitNamingStrategy; +import org.springframework.boot.jpa.autoconfigure.JpaProperties; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -38,7 +39,7 @@ * * @author Stephane Nicoll * @author Chris Bono - * @since 2.1.0 + * @since 4.0.0 * @see JpaProperties */ @ConfigurationProperties("spring.jpa.hibernate") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesCustomizer.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernatePropertiesCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesCustomizer.java rename to spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernatePropertiesCustomizer.java index 3465cd08f8f8..7e9736a52d2c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesCustomizer.java +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernatePropertiesCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure; import java.util.Map; @@ -23,7 +23,7 @@ * properties before it is used by an auto-configured {@code EntityManagerFactory}. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface HibernatePropertiesCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateSettings.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateSettings.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateSettings.java rename to spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateSettings.java index 6f6defb1e1bb..b05258a2d3f2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateSettings.java +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/HibernateSettings.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure; import java.util.ArrayList; import java.util.Collection; @@ -24,7 +24,7 @@ * Settings to apply when configuring Hibernate. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class HibernateSettings { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/HibernateMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/metrics/HibernateMetricsAutoConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/HibernateMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/metrics/HibernateMetricsAutoConfiguration.java index c60e3c878ce5..3f27435d831c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/HibernateMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/metrics/HibernateMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure.metrics; import java.util.Collections; import java.util.Map; @@ -28,13 +28,11 @@ import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; import org.springframework.util.StringUtils; /** @@ -43,10 +41,10 @@ * * @author Rui Figueira * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, HibernateJpaAutoConfiguration.class, - SimpleMetricsExportAutoConfiguration.class }) +@AutoConfiguration(after = HibernateJpaAutoConfiguration.class, + afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") @ConditionalOnClass({ EntityManagerFactory.class, SessionFactory.class, HibernateMetrics.class, MeterRegistry.class }) @ConditionalOnBean({ EntityManagerFactory.class, MeterRegistry.class }) public class HibernateMetricsAutoConfiguration implements SmartInitializingSingleton { diff --git a/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..c0cf82242257 --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JPA and Spring ORM. + */ +package org.springframework.boot.hibernate.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/package-info.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/package-info.java new file mode 100644 index 000000000000..b6cf06be2c83 --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JPA and Spring ORM. + */ +package org.springframework.boot.hibernate.autoconfigure; diff --git a/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/package-info.java b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/package-info.java new file mode 100644 index 000000000000..aa032b1fe737 --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/main/java/org/springframework/boot/hibernate/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Hibernate Support classes. + */ +package org.springframework.boot.hibernate; diff --git a/spring-boot-project/spring-boot-hibernate/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-hibernate/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..ccb70ad131eb --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,75 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.jpa.hibernate.use-new-id-generator-mappings", + "type": "java.lang.Boolean", + "description": "Whether to use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE. This is actually a shortcut for the \"hibernate.id.new_generator_mappings\" property. When not specified will default to \"true\".", + "deprecation": { + "level": "error", + "reason": "Hibernate no longer supports disabling the use of new ID generator mappings." + } + } + ], + "hints": [ + { + "name": "spring.jpa.hibernate.ddl-auto", + "values": [ + { + "value": "create", + "description": "Create the schema and destroy previous data." + }, + { + "value": "create-drop", + "description": "Create and then destroy the schema at the end of the session." + }, + { + "value": "create-only", + "description": "Create the schema." + }, + { + "value": "drop", + "description": "Drop the schema." + }, + { + "value": "none", + "description": "Disable DDL handling." + }, + { + "value": "truncate", + "description": "Truncate the tables in the schema." + }, + { + "value": "update", + "description": "Update the schema if necessary." + }, + { + "value": "validate", + "description": "Validate the schema, make no changes to the database." + } + ] + }, + { + "name": "spring.jpa.hibernate.naming.implicit-strategy", + "providers": [ + { + "name": "class-reference", + "parameters": { + "target": "org.hibernate.boot.model.naming.ImplicitNamingStrategy" + } + } + ] + }, + { + "name": "spring.jpa.hibernate.naming.physical-strategy", + "providers": [ + { + "name": "class-reference", + "parameters": { + "target": "org.hibernate.boot.model.naming.PhysicalNamingStrategy" + } + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-hibernate/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-hibernate/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..96cb05d86690 --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration +org.springframework.boot.hibernate.autoconfigure.metrics.HibernateMetricsAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/CustomHibernateJpaAutoConfigurationTests.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/CustomHibernateJpaAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/CustomHibernateJpaAutoConfigurationTests.java rename to spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/CustomHibernateJpaAutoConfigurationTests.java index bb19c1eb902f..4d7d9664f22a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/CustomHibernateJpaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/CustomHibernateJpaAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure; import java.sql.Connection; import java.sql.DatabaseMetaData; @@ -31,8 +31,9 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.test.City; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jpa.autoconfigure.JpaProperties; +import org.springframework.boot.jpa.autoconfigure.test.city.City; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/Hibernate2ndLevelCacheIntegrationTests.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/Hibernate2ndLevelCacheIntegrationTests.java new file mode 100644 index 000000000000..6b7b69a62f36 --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/Hibernate2ndLevelCacheIntegrationTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.hibernate.autoconfigure; + +import javax.cache.CacheManager; +import javax.cache.Caching; + +import org.ehcache.jsr107.EhcacheCachingProvider; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.jcache.JCacheCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for Hibernate 2nd level cache with jcache. + * + * @author Stephane Nicoll + */ +class Hibernate2ndLevelCacheIntegrationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class)) + .withUserConfiguration(TestConfiguration.class); + + @Test + void hibernate2ndLevelCacheWithJCacheAndEhCache() { + String cachingProviderFqn = EhcacheCachingProvider.class.getName(); + this.contextRunner + .withPropertyValues("spring.cache.type=jcache", "spring.cache.jcache.provider=" + cachingProviderFqn, + "spring.jpa.properties.hibernate.cache.region.factory_class=jcache", + "spring.jpa.properties.hibernate.cache.provider=" + cachingProviderFqn) + .run((context) -> assertThat(context).hasNotFailed()); + } + + @Configuration(proxyBeanMethods = false) + @EnableCaching + static class TestConfiguration { + + @Bean + CacheManager cacheManager() { + return Caching.getCachingProvider(EhcacheCachingProvider.class.getName()).getCacheManager(); + } + + @Bean + JCacheCacheManager jcacheCacheManager(CacheManager cacheManager) { + return new JCacheCacheManager(cacheManager); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateDefaultDdlAutoProviderTests.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateDefaultDdlAutoProviderTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateDefaultDdlAutoProviderTests.java rename to spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateDefaultDdlAutoProviderTests.java index ffccc24976be..dee2170bfea7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateDefaultDdlAutoProviderTests.java +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateDefaultDdlAutoProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure; import java.util.Collections; @@ -23,9 +23,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.SchemaManagement; import org.springframework.boot.jdbc.SchemaManagementProvider; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java new file mode 100644 index 000000000000..f141ce925395 --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernateJpaAutoConfigurationTests.java @@ -0,0 +1,1359 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.hibernate.autoconfigure; + +import java.io.File; +import java.io.IOException; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.Consumer; + +import javax.sql.DataSource; + +import com.zaxxer.hikari.HikariDataSource; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.metamodel.ManagedType; +import jakarta.persistence.spi.PersistenceUnitInfo; +import jakarta.transaction.Synchronization; +import jakarta.transaction.Transaction; +import jakarta.transaction.TransactionManager; +import jakarta.transaction.UserTransaction; +import org.hibernate.boot.model.naming.ImplicitNamingStrategy; +import org.hibernate.boot.model.naming.PhysicalNamingStrategy; +import org.hibernate.boot.model.naming.PhysicalNamingStrategySnakeCaseImpl; +import org.hibernate.cfg.ManagedBeanSettings; +import org.hibernate.cfg.SchemaToolingSettings; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; +import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; +import org.hibernate.internal.SessionFactoryImpl; +import org.hibernate.jpa.HibernatePersistenceProvider; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeReference; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.hibernate.SpringImplicitNamingStrategy; +import org.springframework.boot.hibernate.SpringJtaPlatform; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfigurationTests.JpaUsingApplicationListenerConfiguration.EventCapturingApplicationListener; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaConfiguration.HibernateRuntimeHints; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.XADataSourceAutoConfiguration; +import org.springframework.boot.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryBuilderCustomizer; +import org.springframework.boot.jpa.autoconfigure.JpaBaseConfiguration; +import org.springframework.boot.jpa.autoconfigure.JpaProperties; +import org.springframework.boot.jpa.autoconfigure.hibernate.mapping.NonAnnotatedEntity; +import org.springframework.boot.jpa.autoconfigure.test.city.City; +import org.springframework.boot.jpa.autoconfigure.test.country.Country; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; +import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.testsupport.BuildOutput; +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration; +import org.springframework.boot.transaction.jta.autoconfigure.JtaAutoConfiguration; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.SQLExceptionTranslator; +import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager; +import org.springframework.orm.jpa.persistenceunit.ManagedClassNameFilter; +import org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypes; +import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager; +import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter; +import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.jta.JtaTransactionManager; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.assertj.core.api.Assertions.entry; +import static org.mockito.Mockito.mock; + +/** + * Base for JPA tests and tests for {@link JpaBaseConfiguration}. + * + * @author Phillip Webb + * @author Dave Syer + * @author Stephane Nicoll + * @author Yanming Zhou + * @author Andy Wilkinson + * @author Kazuki Shimizu + * @author Chris Bono + * @author Moritz Halbritter + */ +class HibernateJpaAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("spring.datasource.generate-unique-name=true", + "spring.jta.log-dir=" + new File(new BuildOutput(getClass()).getRootLocation(), "transaction-logs")) + .withUserConfiguration(TestConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, TransactionAutoConfiguration.class, + TransactionManagerCustomizationAutoConfiguration.class, DataSourceInitializationAutoConfiguration.class, + HibernateJpaAutoConfiguration.class)); + + @Test + void notConfiguredIfDataSourceIsNotAvailable() { + new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class)) + .run(assertJpaIsNotAutoConfigured()); + } + + @Test + void notConfiguredIfNoSingleDataSourceCandidateIsAvailable() { + new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class)) + .withUserConfiguration(TestTwoDataSourcesConfiguration.class) + .run(assertJpaIsNotAutoConfigured()); + } + + protected ContextConsumer assertJpaIsNotAutoConfigured() { + return (context) -> { + assertThat(context).hasNotFailed(); + assertThat(context).hasSingleBean(JpaProperties.class); + assertThat(context).doesNotHaveBean(TransactionManager.class); + assertThat(context).doesNotHaveBean(EntityManagerFactory.class); + }; + } + + @Test + void configuredWithAutoConfiguredDataSource() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(DataSource.class); + assertThat(context).hasSingleBean(JpaTransactionManager.class); + assertThat(context).hasSingleBean(EntityManagerFactory.class); + assertThat(context).hasSingleBean(PersistenceManagedTypes.class); + }); + } + + @Test + void configuredWithSingleCandidateDataSource() { + this.contextRunner.withUserConfiguration(TestTwoDataSourcesAndPrimaryConfiguration.class).run((context) -> { + assertThat(context).getBeans(DataSource.class).hasSize(2); + assertThat(context).hasSingleBean(JpaTransactionManager.class); + assertThat(context).hasSingleBean(EntityManagerFactory.class); + assertThat(context).hasSingleBean(PersistenceManagedTypes.class); + }); + } + + @Test + void jpaTransactionManagerTakesPrecedenceOverSimpleDataSourceOne() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class)) + .run((context) -> { + assertThat(context).hasSingleBean(DataSource.class); + assertThat(context).hasSingleBean(JpaTransactionManager.class); + assertThat(context).getBean("transactionManager").isInstanceOf(JpaTransactionManager.class); + }); + } + + @Test + void openEntityManagerInViewInterceptorIsCreated() { + new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true") + .withUserConfiguration(TestConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class)) + .run((context) -> assertThat(context).hasSingleBean(OpenEntityManagerInViewInterceptor.class)); + } + + @Test + void openEntityManagerInViewInterceptorIsNotRegisteredWhenFilterPresent() { + new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true") + .withUserConfiguration(TestFilterConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class)) + .run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class)); + } + + @Test + void openEntityManagerInViewInterceptorIsNotRegisteredWhenFilterRegistrationPresent() { + new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true") + .withUserConfiguration(TestFilterRegistrationConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class)) + .run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class)); + } + + @Test + void openEntityManagerInViewInterceptorAutoConfigurationBacksOffWhenManuallyRegistered() { + new WebApplicationContextRunner().withPropertyValues("spring.datasource.generate-unique-name=true") + .withUserConfiguration(TestInterceptorManualConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class)) + .run((context) -> assertThat(context).getBean(OpenEntityManagerInViewInterceptor.class) + .isExactlyInstanceOf( + TestInterceptorManualConfiguration.ManualOpenEntityManagerInViewInterceptor.class)); + } + + @Test + void openEntityManagerInViewInterceptorIsNotRegisteredWhenExplicitlyOff() { + new WebApplicationContextRunner() + .withPropertyValues("spring.datasource.generate-unique-name=true", "spring.jpa.open-in-view=false") + .withUserConfiguration(TestConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + TransactionAutoConfiguration.class, HibernateJpaAutoConfiguration.class)) + .run((context) -> assertThat(context).doesNotHaveBean(OpenEntityManagerInViewInterceptor.class)); + } + + @Test + void customJpaProperties() { + this.contextRunner + .withPropertyValues("spring.jpa.properties.a:b", "spring.jpa.properties.a.b:c", "spring.jpa.properties.c:d") + .run((context) -> { + LocalContainerEntityManagerFactoryBean bean = context + .getBean(LocalContainerEntityManagerFactoryBean.class); + Map map = bean.getJpaPropertyMap(); + assertThat(map).containsEntry("a", "b"); + assertThat(map).containsEntry("c", "d"); + assertThat(map).containsEntry("a.b", "c"); + }); + } + + @Test + @WithMetaInfPersistenceXmlResource + void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanUsingBuilder() { + this.contextRunner.withPropertyValues("spring.jpa.properties.a=b") + .withUserConfiguration(TestConfigurationWithEntityManagerFactoryBuilder.class) + .run((context) -> { + LocalContainerEntityManagerFactoryBean factoryBean = context + .getBean(LocalContainerEntityManagerFactoryBean.class); + Map map = factoryBean.getJpaPropertyMap(); + assertThat(map).containsEntry("configured", "manually").containsEntry("a", "b"); + }); + } + + @Test + @WithMetaInfPersistenceXmlResource + void usesManuallyDefinedLocalContainerEntityManagerFactoryBeanIfAvailable() { + this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class) + .run((context) -> { + LocalContainerEntityManagerFactoryBean factoryBean = context + .getBean(LocalContainerEntityManagerFactoryBean.class); + Map map = factoryBean.getJpaPropertyMap(); + assertThat(map).containsEntry("configured", "manually"); + }); + } + + @Test + @WithMetaInfPersistenceXmlResource + void usesManuallyDefinedEntityManagerFactoryIfAvailable() { + this.contextRunner.withUserConfiguration(TestConfigurationWithLocalContainerEntityManagerFactoryBean.class) + .run((context) -> { + EntityManagerFactory factoryBean = context.getBean(EntityManagerFactory.class); + Map map = factoryBean.getProperties(); + assertThat(map).containsEntry("configured", "manually"); + }); + } + + @Test + void usesManuallyDefinedTransactionManagerBeanIfAvailable() { + this.contextRunner.withUserConfiguration(TestConfigurationWithTransactionManager.class).run((context) -> { + assertThat(context).hasSingleBean(JpaTransactionManager.class); + JpaTransactionManager txManager = context.getBean(JpaTransactionManager.class); + assertThat(txManager).isInstanceOf(CustomJpaTransactionManager.class); + }); + } + + @Test + void defaultPersistenceManagedTypes() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(PersistenceManagedTypes.class); + EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager(); + assertThat(getManagedJavaTypes(entityManager)).contains(City.class).doesNotContain(Country.class); + }); + } + + @Test + void customPersistenceManagedTypes() { + this.contextRunner + .withBean(PersistenceManagedTypes.class, () -> PersistenceManagedTypes.of(Country.class.getName())) + .run((context) -> { + assertThat(context).hasSingleBean(PersistenceManagedTypes.class); + EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager(); + assertThat(getManagedJavaTypes(entityManager)).contains(Country.class).doesNotContain(City.class); + }); + } + + @Test + void customPersistenceUnitManager() { + this.contextRunner.withUserConfiguration(TestConfigurationWithCustomPersistenceUnitManager.class) + .run((context) -> { + LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context + .getBean(LocalContainerEntityManagerFactoryBean.class); + assertThat(entityManagerFactoryBean).hasFieldOrPropertyWithValue("persistenceUnitManager", + context.getBean(PersistenceUnitManager.class)); + }); + } + + @Test + void customPersistenceUnitPostProcessors() { + this.contextRunner.withUserConfiguration(TestConfigurationWithCustomPersistenceUnitPostProcessors.class) + .run((context) -> { + LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = context + .getBean(LocalContainerEntityManagerFactoryBean.class); + PersistenceUnitInfo persistenceUnitInfo = entityManagerFactoryBean.getPersistenceUnitInfo(); + assertThat(persistenceUnitInfo).isNotNull(); + assertThat(persistenceUnitInfo.getManagedClassNames()) + .contains("customized.attribute.converter.class.name"); + }); + } + + @Test + void customManagedClassNameFilter() { + this.contextRunner.withBean(ManagedClassNameFilter.class, () -> (s) -> !s.endsWith("City")) + .withUserConfiguration(AutoConfigurePackageForCountry.class) + .run((context) -> { + EntityManager entityManager = context.getBean(EntityManagerFactory.class).createEntityManager(); + assertThat(getManagedJavaTypes(entityManager)).contains(Country.class).doesNotContain(City.class); + }); + } + + @Test + void testDmlScriptWithMissingDdl() { + this.contextRunner.withPropertyValues("spring.sql.init.data-locations:classpath:/city.sql", + // Missing: + "spring.sql.init.schema-locations:classpath:/ddl.sql") + .run((context) -> { + assertThat(context).hasFailed(); + assertThat(context.getStartupFailure()).hasMessageContaining("ddl.sql"); + }); + } + + @Test + void testDmlScript() { + // This can't succeed because the data SQL is executed immediately after the + // schema and Hibernate hasn't initialized yet at that point + this.contextRunner.withPropertyValues("spring.sql.init.data-locations:/city.sql").run((context) -> { + assertThat(context).hasFailed(); + assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class); + }); + } + + @Test + @WithResource(name = "city.sql", + content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google')") + void testDmlScriptRunsEarly() { + this.contextRunner.withUserConfiguration(TestInitializedJpaConfiguration.class) + .withClassLoader(new HideDataScriptClassLoader()) + .withPropertyValues("spring.jpa.show-sql=true", "spring.jpa.properties.hibernate.format_sql=true", + "spring.jpa.properties.hibernate.highlight_sql=true", "spring.jpa.hibernate.ddl-auto:create-drop", + "spring.sql.init.data-locations:/city.sql", "spring.jpa.defer-datasource-initialization=true") + .run((context) -> assertThat(context.getBean(TestInitializedJpaConfiguration.class).called).isTrue()); + } + + @Test + @WithResource(name = "db/city/V1__init.sql", content = """ + CREATE SEQUENCE city_seq INCREMENT BY 50; + CREATE TABLE CITY ( + id BIGINT GENERATED BY DEFAULT AS IDENTITY, + name VARCHAR(30), + state VARCHAR(30), + country VARCHAR(30), + map VARCHAR(30) + ); + """) + void testFlywaySwitchOffDdlAuto() { + this.contextRunner.withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city") + .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) + .run((context) -> assertThat(context).hasNotFailed()); + } + + @Test + @WithResource(name = "db/city/V1__init.sql", content = """ + CREATE SEQUENCE city_seq INCREMENT BY 50; + + CREATE TABLE CITY ( + id BIGINT GENERATED BY DEFAULT AS IDENTITY, + name VARCHAR(30), + state VARCHAR(30), + country VARCHAR(30), + map VARCHAR(30) + ); + """) + void testFlywayPlusValidation() { + this.contextRunner + .withPropertyValues("spring.sql.init.mode:never", "spring.flyway.locations:classpath:db/city", + "spring.jpa.hibernate.ddl-auto:validate") + .withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) + .run((context) -> assertThat(context).hasNotFailed()); + } + + @Test + @WithResource(name = "db/changelog/db.changelog-city.yaml", content = """ + databaseChangeLog: + - changeSet: + id: 1 + author: dsyer + changes: + - createSequence: + sequenceName: city_seq + incrementBy: 50 + - createTable: + tableName: city + columns: + - column: + name: id + type: bigint + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: name + type: varchar(50) + constraints: + nullable: false + - column: + name: state + type: varchar(50) + constraints: + nullable: false + - column: + name: country + type: varchar(50) + constraints: + nullable: false + - column: + name: map + type: varchar(50) + constraints: + nullable: true + """) + void testLiquibasePlusValidation() { + this.contextRunner + .withPropertyValues("spring.liquibase.change-log:classpath:db/changelog/db.changelog-city.yaml", + "spring.jpa.hibernate.ddl-auto:validate") + .withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class)) + .run((context) -> assertThat(context).hasNotFailed()); + } + + @Test + void hibernateDialectIsNotSetByDefault() { + this.contextRunner.run(assertJpaVendorAdapter( + (adapter) -> assertThat(adapter.getJpaPropertyMap()).doesNotContainKeys("hibernate.dialect"))); + } + + @Test + void shouldConfigureHibernateJpaDialectWithSqlExceptionTranslatorIfPresent() { + SQLStateSQLExceptionTranslator sqlExceptionTranslator = new SQLStateSQLExceptionTranslator(); + this.contextRunner.withBean(SQLStateSQLExceptionTranslator.class, () -> sqlExceptionTranslator) + .run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaDialect()) + .hasFieldOrPropertyWithValue("jdbcExceptionTranslator", sqlExceptionTranslator))); + } + + @Test + void shouldNotConfigureHibernateJpaDialectWithSqlExceptionTranslatorIfNotUnique() { + SQLStateSQLExceptionTranslator sqlExceptionTranslator1 = new SQLStateSQLExceptionTranslator(); + SQLStateSQLExceptionTranslator sqlExceptionTranslator2 = new SQLStateSQLExceptionTranslator(); + this.contextRunner + .withBean("sqlExceptionTranslator1", SQLExceptionTranslator.class, () -> sqlExceptionTranslator1) + .withBean("sqlExceptionTranslator2", SQLExceptionTranslator.class, () -> sqlExceptionTranslator2) + .run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaDialect()) + .hasFieldOrPropertyWithValue("jdbcExceptionTranslator", null))); + } + + @Test + void hibernateDialectIsSetWhenDatabaseIsSet() { + this.contextRunner.withPropertyValues("spring.jpa.database=H2") + .run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaPropertyMap()) + .contains(entry("hibernate.dialect", H2Dialect.class.getName())))); + } + + @Test + void hibernateDialectIsSetWhenDatabasePlatformIsSet() { + String databasePlatform = TestH2Dialect.class.getName(); + this.contextRunner.withPropertyValues("spring.jpa.database-platform=" + databasePlatform) + .run(assertJpaVendorAdapter((adapter) -> assertThat(adapter.getJpaPropertyMap()) + .contains(entry("hibernate.dialect", databasePlatform)))); + } + + private ContextConsumer assertJpaVendorAdapter( + Consumer adapter) { + return (context) -> { + assertThat(context).hasSingleBean(JpaVendorAdapter.class); + assertThat(context).hasSingleBean(HibernateJpaVendorAdapter.class); + adapter.accept(context.getBean(HibernateJpaVendorAdapter.class)); + }; + } + + @Test + void jtaDefaultPlatform() { + this.contextRunner.withUserConfiguration(JtaTransactionManagerConfiguration.class) + .run(assertJtaPlatform(SpringJtaPlatform.class)); + } + + @Test + void jtaCustomPlatform() { + this.contextRunner + .withPropertyValues( + "spring.jpa.properties.hibernate.transaction.jta.platform:" + TestJtaPlatform.class.getName()) + .withConfiguration(AutoConfigurations.of(JtaAutoConfiguration.class)) + .run(assertJtaPlatform(TestJtaPlatform.class)); + } + + @Test + void jtaNotUsedByTheApplication() { + this.contextRunner.run(assertJtaPlatform(NoJtaPlatform.class)); + } + + private ContextConsumer assertJtaPlatform(Class expectedType) { + return (context) -> { + SessionFactoryImpl sessionFactory = context.getBean(LocalContainerEntityManagerFactoryBean.class) + .getNativeEntityManagerFactory() + .unwrap(SessionFactoryImpl.class); + assertThat(sessionFactory.getServiceRegistry().getService(JtaPlatform.class)).isInstanceOf(expectedType); + }; + } + + @Test + void jtaCustomTransactionManagerUsingProperties() { + this.contextRunner + .withPropertyValues("spring.transaction.default-timeout:30", + "spring.transaction.rollback-on-commit-failure:true") + .run((context) -> { + JpaTransactionManager transactionManager = context.getBean(JpaTransactionManager.class); + assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); + assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); + }); + } + + @Test + void autoConfigurationBacksOffWithSeveralDataSources() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class, + XADataSourceAutoConfiguration.class, JtaAutoConfiguration.class)) + .withUserConfiguration(TestTwoDataSourcesConfiguration.class) + .run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context).doesNotHaveBean(EntityManagerFactory.class); + }); + } + + @Test + void providerDisablesAutoCommitIsConfigured() { + this.contextRunner + .withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(), + "spring.datasource.hikari.auto-commit:false") + .run((context) -> { + Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) + .getJpaPropertyMap(); + assertThat(jpaProperties).contains(entry("hibernate.connection.provider_disables_autocommit", "true")); + }); + } + + @Test + void providerDisablesAutoCommitIsNotConfiguredIfAutoCommitIsEnabled() { + this.contextRunner + .withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(), + "spring.datasource.hikari.auto-commit:true") + .run((context) -> { + Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) + .getJpaPropertyMap(); + assertThat(jpaProperties).doesNotContainKeys("hibernate.connection.provider_disables_autocommit"); + }); + } + + @Test + void providerDisablesAutoCommitIsNotConfiguredIfPropertyIsSet() { + this.contextRunner + .withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(), + "spring.datasource.hikari.auto-commit:false", + "spring.jpa.properties.hibernate.connection.provider_disables_autocommit=false") + .run((context) -> { + Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) + .getJpaPropertyMap(); + assertThat(jpaProperties).contains(entry("hibernate.connection.provider_disables_autocommit", "false")); + }); + } + + @Test + void providerDisablesAutoCommitIsNotConfiguredWithJta() { + this.contextRunner.withUserConfiguration(JtaTransactionManagerConfiguration.class) + .withPropertyValues("spring.datasource.type:" + HikariDataSource.class.getName(), + "spring.datasource.hikari.auto-commit:false") + .run((context) -> { + Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) + .getJpaPropertyMap(); + assertThat(jpaProperties).doesNotContainKeys("hibernate.connection.provider_disables_autocommit"); + }); + } + + @Test + @WithResource(name = "META-INF/mappings/non-annotated.xml", + content = """ + + + +

+ + + + + + + + + + + + """) + @WithResource(name = "non-annotated-data.sql", + content = "INSERT INTO NON_ANNOTATED (id, item) values (2000, 'Test');") + void customResourceMapping() { + this.contextRunner.withClassLoader(new HideDataScriptClassLoader()) + .withPropertyValues("spring.sql.init.data-locations:classpath:non-annotated-data.sql", + "spring.jpa.mapping-resources=META-INF/mappings/non-annotated.xml", + "spring.jpa.defer-datasource-initialization=true") + .run((context) -> { + EntityManager em = context.getBean(EntityManagerFactory.class).createEntityManager(); + NonAnnotatedEntity found = em.find(NonAnnotatedEntity.class, 2000L); + assertThat(found).isNotNull(); + assertThat(found.getItem()).isEqualTo("Test"); + }); + } + + @Test + void physicalNamingStrategyCanBeUsed() { + this.contextRunner.withUserConfiguration(TestPhysicalNamingStrategyConfiguration.class).run((context) -> { + Map hibernateProperties = getVendorProperties(context); + assertThat(hibernateProperties) + .contains(entry("hibernate.physical_naming_strategy", context.getBean("testPhysicalNamingStrategy"))); + assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy"); + }); + } + + @Test + void implicitNamingStrategyCanBeUsed() { + this.contextRunner.withUserConfiguration(TestImplicitNamingStrategyConfiguration.class).run((context) -> { + Map hibernateProperties = getVendorProperties(context); + assertThat(hibernateProperties) + .contains(entry("hibernate.implicit_naming_strategy", context.getBean("testImplicitNamingStrategy"))); + assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy"); + }); + } + + @Test + void namingStrategyInstancesTakePrecedenceOverNamingStrategyProperties() { + this.contextRunner + .withUserConfiguration(TestPhysicalNamingStrategyConfiguration.class, + TestImplicitNamingStrategyConfiguration.class) + .withPropertyValues("spring.jpa.hibernate.naming.physical-strategy:com.example.Physical", + "spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit") + .run((context) -> { + Map hibernateProperties = getVendorProperties(context); + assertThat(hibernateProperties).contains( + entry("hibernate.physical_naming_strategy", context.getBean("testPhysicalNamingStrategy")), + entry("hibernate.implicit_naming_strategy", context.getBean("testImplicitNamingStrategy"))); + assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy"); + }); + } + + @Test + void hibernatePropertiesCustomizerTakesPrecedenceOverStrategyInstancesAndNamingStrategyProperties() { + this.contextRunner + .withUserConfiguration(TestHibernatePropertiesCustomizerConfiguration.class, + TestPhysicalNamingStrategyConfiguration.class, TestImplicitNamingStrategyConfiguration.class) + .withPropertyValues("spring.jpa.hibernate.naming.physical-strategy:com.example.Physical", + "spring.jpa.hibernate.naming.implicit-strategy:com.example.Implicit") + .run((context) -> { + Map hibernateProperties = getVendorProperties(context); + TestHibernatePropertiesCustomizerConfiguration configuration = context + .getBean(TestHibernatePropertiesCustomizerConfiguration.class); + assertThat(hibernateProperties).contains( + entry("hibernate.physical_naming_strategy", configuration.physicalNamingStrategy), + entry("hibernate.implicit_naming_strategy", configuration.implicitNamingStrategy)); + assertThat(hibernateProperties).doesNotContainKeys("hibernate.ejb.naming_strategy"); + }); + } + + @Test + @WithResource(name = "city.sql", + content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google')") + void eventListenerCanBeRegisteredAsBeans() { + this.contextRunner.withUserConfiguration(TestInitializedJpaConfiguration.class) + .withClassLoader(new HideDataScriptClassLoader()) + .withPropertyValues("spring.jpa.show-sql=true", "spring.jpa.hibernate.ddl-auto:create-drop", + "spring.sql.init.data-locations:classpath:/city.sql", + "spring.jpa.defer-datasource-initialization=true") + .run((context) -> { + // See CityListener + assertThat(context).hasSingleBean(City.class); + assertThat(context.getBean(City.class).getName()).isEqualTo("Washington"); + }); + } + + @Test + void hibernatePropertiesCustomizerCanDisableBeanContainer() { + this.contextRunner.withUserConfiguration(DisableBeanContainerConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(City.class)); + } + + @Test + void vendorPropertiesWithEmbeddedDatabaseAndNoDdlProperty() { + this.contextRunner.run(vendorProperties((vendorProperties) -> { + assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION); + assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "create-drop"); + })); + } + + @Test + void vendorPropertiesWhenDdlAutoPropertyIsSet() { + this.contextRunner.withPropertyValues("spring.jpa.hibernate.ddl-auto=update") + .run(vendorProperties((vendorProperties) -> { + assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION); + assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "update"); + })); + } + + @Test + void vendorPropertiesWhenDdlAutoPropertyAndHibernatePropertiesAreSet() { + this.contextRunner + .withPropertyValues("spring.jpa.hibernate.ddl-auto=update", + "spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop") + .run(vendorProperties((vendorProperties) -> { + assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION); + assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "create-drop"); + })); + } + + @Test + void vendorPropertiesWhenDdlAutoPropertyIsSetToNone() { + this.contextRunner.withPropertyValues("spring.jpa.hibernate.ddl-auto=none") + .run(vendorProperties((vendorProperties) -> assertThat(vendorProperties).doesNotContainKeys( + SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, SchemaToolingSettings.HBM2DDL_AUTO))); + } + + @Test + void vendorPropertiesWhenJpaDdlActionIsSet() { + this.contextRunner + .withPropertyValues("spring.jpa.properties.jakarta.persistence.schema-generation.database.action=create") + .run(vendorProperties((vendorProperties) -> { + assertThat(vendorProperties).containsEntry(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, + "create"); + assertThat(vendorProperties).doesNotContainKeys(SchemaToolingSettings.HBM2DDL_AUTO); + })); + } + + @Test + void vendorPropertiesWhenBothDdlAutoPropertiesAreSet() { + this.contextRunner + .withPropertyValues("spring.jpa.properties.jakarta.persistence.schema-generation.database.action=create", + "spring.jpa.hibernate.ddl-auto=create-only") + .run(vendorProperties((vendorProperties) -> { + assertThat(vendorProperties).containsEntry(SchemaToolingSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, + "create"); + assertThat(vendorProperties).containsEntry(SchemaToolingSettings.HBM2DDL_AUTO, "create-only"); + })); + } + + private ContextConsumer vendorProperties( + Consumer> vendorProperties) { + return (context) -> vendorProperties.accept(getVendorProperties(context)); + } + + private static Map getVendorProperties(ConfigurableApplicationContext context) { + return context.getBean(HibernateJpaConfiguration.class).getVendorProperties(context.getBean(DataSource.class)); + } + + @Test + void withSyncBootstrappingAnApplicationListenerThatUsesJpaDoesNotTriggerABeanCurrentlyInCreationException() { + this.contextRunner.withUserConfiguration(JpaUsingApplicationListenerConfiguration.class).run((context) -> { + assertThat(context).hasNotFailed(); + EventCapturingApplicationListener listener = context.getBean(EventCapturingApplicationListener.class); + assertThat(listener.events).hasSize(1); + assertThat(listener.events).hasOnlyElementsOfType(ContextRefreshedEvent.class); + }); + } + + @Test + void withAsyncBootstrappingAnApplicationListenerThatUsesJpaDoesNotTriggerABeanCurrentlyInCreationException() { + this.contextRunner + .withUserConfiguration(AsyncBootstrappingConfiguration.class, + JpaUsingApplicationListenerConfiguration.class) + .run((context) -> { + assertThat(context).hasNotFailed(); + EventCapturingApplicationListener listener = context.getBean(EventCapturingApplicationListener.class); + assertThat(listener.events).hasSize(1); + assertThat(listener.events).hasOnlyElementsOfType(ContextRefreshedEvent.class); + // createEntityManager requires Hibernate bootstrapping to be complete + assertThatNoException() + .isThrownBy(() -> context.getBean(EntityManagerFactory.class).createEntityManager()); + }); + } + + @Test + @WithMetaInfPersistenceXmlResource + void whenLocalContainerEntityManagerFactoryBeanHasNoJpaVendorAdapterAutoConfigurationSucceeds() { + this.contextRunner + .withUserConfiguration( + TestConfigurationWithLocalContainerEntityManagerFactoryBeanWithNoJpaVendorAdapter.class) + .run((context) -> { + EntityManagerFactory factoryBean = context.getBean(EntityManagerFactory.class); + Map map = factoryBean.getProperties(); + assertThat(map).containsEntry("configured", "manually"); + }); + } + + @Test + void registersHintsForJtaClasses() { + RuntimeHints hints = new RuntimeHints(); + new HibernateRuntimeHints().registerHints(hints, getClass().getClassLoader()); + for (String noJtaPlatformClass : Arrays.asList( + "org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform", + "org.hibernate.service.jta.platform.internal.NoJtaPlatform")) { + assertThat(RuntimeHintsPredicates.reflection() + .onType(TypeReference.of(noJtaPlatformClass)) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints); + } + } + + @Test + void registersHintsForNamingClasses() { + RuntimeHints hints = new RuntimeHints(); + new HibernateRuntimeHints().registerHints(hints, getClass().getClassLoader()); + for (Class noJtaPlatformClass : Arrays.asList(SpringImplicitNamingStrategy.class, + PhysicalNamingStrategySnakeCaseImpl.class)) { + assertThat(RuntimeHintsPredicates.reflection() + .onType(noJtaPlatformClass) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints); + } + } + + @Test + @Disabled("gh-40177") + void whenSpringJpaGenerateDdlIsNotSetThenTableIsNotCreated() { + // spring.jpa.generated-ddl defaults to false but this test still fails because + // we're using an embedded database which means that HibernateProperties defaults + // hibernate.hbm2ddl.auto to create-drop, replacing the + // hibernate.hbm2ddl.auto=none that comes from generate-ddl being false. + this.contextRunner.run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); + } + + @Test + void whenSpringJpaGenerateDdlIsTrueThenTableIsCreated() { + this.contextRunner.withPropertyValues("spring.jpa.generate-ddl=true") + .run((context) -> assertThat(tablesFrom(context)).contains("CITY")); + } + + @Test + @Disabled("gh-40177") + void whenSpringJpaGenerateDdlIsFalseThenTableIsNotCreated() { + // This test fails because we're using an embedded database which means that + // HibernateProperties defaults hibernate.hbm2ddl.auto to create-drop, replacing + // the hibernate.hbm2ddl.auto=none that comes from setting generate-ddl to false. + this.contextRunner.withPropertyValues("spring.jpa.generate-ddl=false") + .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); + } + + @Test + void whenHbm2DdlAutoIsNoneThenTableIsNotCreated() { + this.contextRunner.withPropertyValues("spring.jpa.properties.hibernate.hbm2ddl.auto=none") + .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); + } + + @Test + void whenSpringJpaHibernateDdlAutoIsNoneThenTableIsNotCreated() { + this.contextRunner.withPropertyValues("spring.jpa.hibernate.ddl-auto=none") + .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); + } + + @Test + @Disabled("gh-40177") + void whenSpringJpaGenerateDdlIsTrueAndSpringJpaHibernateDdlAutoIsNoneThenTableIsNotCreated() { + // This test fails because when ddl-auto is set to none, we remove + // hibernate.hbm2ddl.auto from Hibernate properties. This then allows + // spring.jpa.generate-ddl to set it to create-drop + this.contextRunner.withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=none") + .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); + } + + @Test + void whenSpringJpaGenerateDdlIsTrueAndSpringJpaHibernateDdlAutoIsDropThenTableIsNotCreated() { + this.contextRunner.withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=drop") + .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); + } + + @Test + void whenSpringJpaGenerateDdlIsTrueAndJakartaSchemaGenerationIsNoneThenTableIsNotCreated() { + this.contextRunner + .withPropertyValues("spring.jpa.generate-ddl=true", + "spring.jpa.properties.jakarta.persistence.schema-generation.database.action=none") + .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); + } + + @Test + void whenSpringJpaGenerateDdlIsTrueSpringJpaHibernateDdlAutoIsCreateAndJakartaSchemaGenerationIsNoneThenTableIsNotCreated() { + this.contextRunner + .withPropertyValues("spring.jpa.generate-ddl=true", "spring.jpa.hibernate.ddl-auto=create", + "spring.jpa.properties.jakarta.persistence.schema-generation.database.action=none") + .run((context) -> assertThat(tablesFrom(context)).doesNotContain("CITY")); + } + + private List tablesFrom(AssertableApplicationContext context) { + DataSource dataSource = context.getBean(DataSource.class); + JdbcTemplate jdbc = new JdbcTemplate(dataSource); + List tables = jdbc.query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES", + (results, row) -> results.getString(1)); + return tables; + } + + private Class[] getManagedJavaTypes(EntityManager entityManager) { + Set> managedTypes = entityManager.getMetamodel().getManagedTypes(); + return managedTypes.stream().map(ManagedType::getJavaType).toArray(Class[]::new); + } + + @Configuration(proxyBeanMethods = false) + protected static class TestTwoDataSourcesConfiguration { + + @Bean + DataSource firstDataSource() { + return createRandomDataSource(); + } + + @Bean + DataSource secondDataSource() { + return createRandomDataSource(); + } + + private DataSource createRandomDataSource() { + String url = "jdbc:h2:mem:init-" + UUID.randomUUID(); + return DataSourceBuilder.create().url(url).build(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestTwoDataSourcesAndPrimaryConfiguration { + + @Bean + @Primary + DataSource firstDataSource() { + return createRandomDataSource(); + } + + @Bean + DataSource secondDataSource() { + return createRandomDataSource(); + } + + private DataSource createRandomDataSource() { + String url = "jdbc:h2:mem:init-" + UUID.randomUUID(); + return DataSourceBuilder.create().url(url).build(); + } + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + protected static class TestConfiguration { + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + static class TestFilterConfiguration { + + @Bean + OpenEntityManagerInViewFilter openEntityManagerInViewFilter() { + return new OpenEntityManagerInViewFilter(); + } + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + static class TestFilterRegistrationConfiguration { + + @Bean + FilterRegistrationBean openEntityManagerInViewFilterFilterRegistrationBean() { + return new FilterRegistrationBean<>(); + } + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + static class TestInterceptorManualConfiguration { + + @Bean + OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor() { + return new ManualOpenEntityManagerInViewInterceptor(); + } + + static class ManualOpenEntityManagerInViewInterceptor extends OpenEntityManagerInViewInterceptor { + + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestConfigurationWithEntityManagerFactoryBuilder extends TestConfiguration { + + @Bean + LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder, + DataSource dataSource) { + return builder.dataSource(dataSource).properties(Map.of("configured", "manually")).build(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestConfigurationWithLocalContainerEntityManagerFactoryBean extends TestConfiguration { + + @Bean + LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter) { + LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); + factoryBean.setJpaVendorAdapter(adapter); + factoryBean.setDataSource(dataSource); + factoryBean.setPersistenceUnitName("manually-configured"); + Map properties = new HashMap<>(); + properties.put("configured", "manually"); + properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); + factoryBean.setJpaPropertyMap(properties); + return factoryBean; + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestConfigurationWithEntityManagerFactory extends TestConfiguration { + + @Bean + EntityManagerFactory entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter) { + LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); + factoryBean.setJpaVendorAdapter(adapter); + factoryBean.setDataSource(dataSource); + factoryBean.setPersistenceUnitName("manually-configured"); + Map properties = new HashMap<>(); + properties.put("configured", "manually"); + properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); + factoryBean.setJpaPropertyMap(properties); + factoryBean.afterPropertiesSet(); + return factoryBean.getObject(); + } + + @Bean + PlatformTransactionManager transactionManager(EntityManagerFactory emf) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(emf); + return transactionManager; + } + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + static class TestConfigurationWithTransactionManager { + + @Bean + JpaTransactionManager testTransactionManager() { + return new CustomJpaTransactionManager(); + } + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(Country.class) + static class AutoConfigurePackageForCountry { + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(HibernateJpaAutoConfigurationTests.class) + static class TestConfigurationWithCustomPersistenceUnitManager { + + private final DataSource dataSource; + + TestConfigurationWithCustomPersistenceUnitManager(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Bean + PersistenceUnitManager persistenceUnitManager() { + DefaultPersistenceUnitManager persistenceUnitManager = new DefaultPersistenceUnitManager(); + persistenceUnitManager.setDefaultDataSource(this.dataSource); + persistenceUnitManager.setPackagesToScan(City.class.getPackage().getName()); + return persistenceUnitManager; + } + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(HibernateJpaAutoConfigurationTests.class) + static class TestConfigurationWithCustomPersistenceUnitPostProcessors { + + @Bean + EntityManagerFactoryBuilderCustomizer entityManagerFactoryBuilderCustomizer() { + return (builder) -> builder.setPersistenceUnitPostProcessors( + (pui) -> pui.addManagedClassName("customized.attribute.converter.class.name")); + } + + } + + static class CustomJpaTransactionManager extends JpaTransactionManager { + + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @WithResource(name = "META-INF/persistence.xml", + content = """ + + + + org.springframework.boot.jpa.autoconfigure.test.city.City + true + + + """) + protected @interface WithMetaInfPersistenceXmlResource { + + } + + @Configuration(proxyBeanMethods = false) + @TestAutoConfigurationPackage(City.class) + @DependsOnDatabaseInitialization + static class TestInitializedJpaConfiguration { + + private boolean called; + + @Autowired + void validateDataSourceIsInitialized(EntityManagerFactory entityManagerFactory) { + // Inject the entity manager to validate it is initialized at the injection + // point + EntityManager entityManager = entityManagerFactory.createEntityManager(); + City city = entityManager.find(City.class, 2000L); + assertThat(city).isNotNull(); + assertThat(city.getName()).isEqualTo("Washington"); + this.called = true; + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestImplicitNamingStrategyConfiguration { + + @Bean + ImplicitNamingStrategy testImplicitNamingStrategy() { + return new SpringImplicitNamingStrategy(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestPhysicalNamingStrategyConfiguration { + + @Bean + PhysicalNamingStrategy testPhysicalNamingStrategy() { + return new PhysicalNamingStrategySnakeCaseImpl(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestHibernatePropertiesCustomizerConfiguration { + + private final PhysicalNamingStrategy physicalNamingStrategy = new PhysicalNamingStrategySnakeCaseImpl(); + + private final ImplicitNamingStrategy implicitNamingStrategy = new SpringImplicitNamingStrategy(); + + @Bean + HibernatePropertiesCustomizer testHibernatePropertiesCustomizer() { + return (hibernateProperties) -> { + hibernateProperties.put("hibernate.physical_naming_strategy", this.physicalNamingStrategy); + hibernateProperties.put("hibernate.implicit_naming_strategy", this.implicitNamingStrategy); + }; + } + + } + + @Configuration(proxyBeanMethods = false) + static class DisableBeanContainerConfiguration { + + @Bean + HibernatePropertiesCustomizer disableBeanContainerHibernatePropertiesCustomizer() { + return (hibernateProperties) -> hibernateProperties.remove(ManagedBeanSettings.BEAN_CONTAINER); + } + + } + + public static class TestJtaPlatform implements JtaPlatform { + + @Override + public TransactionManager retrieveTransactionManager() { + return mock(TransactionManager.class); + } + + @Override + public UserTransaction retrieveUserTransaction() { + throw new UnsupportedOperationException(); + } + + @Override + public Object getTransactionIdentifier(Transaction transaction) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean canRegisterSynchronization() { + throw new UnsupportedOperationException(); + } + + @Override + public void registerSynchronization(Synchronization synchronization) { + throw new UnsupportedOperationException(); + } + + @Override + public int getCurrentStatus() { + throw new UnsupportedOperationException(); + } + + } + + static class HideDataScriptClassLoader extends URLClassLoader { + + private static final List HIDDEN_RESOURCES = Arrays.asList("schema-all.sql", "schema.sql"); + + HideDataScriptClassLoader() { + super(new URL[0], Thread.currentThread().getContextClassLoader()); + } + + @Override + public Enumeration getResources(String name) throws IOException { + if (HIDDEN_RESOURCES.contains(name)) { + return Collections.emptyEnumeration(); + } + return super.getResources(name); + } + + } + + @org.springframework.context.annotation.Configuration(proxyBeanMethods = false) + static class JpaUsingApplicationListenerConfiguration { + + @Bean + EventCapturingApplicationListener jpaUsingApplicationListener(EntityManagerFactory emf) { + return new EventCapturingApplicationListener(); + } + + static class EventCapturingApplicationListener implements ApplicationListener { + + private final List events = new ArrayList<>(); + + @Override + public void onApplicationEvent(ApplicationEvent event) { + this.events.add(event); + } + + } + + } + + @Configuration(proxyBeanMethods = false) + static class AsyncBootstrappingConfiguration { + + @Bean + ThreadPoolTaskExecutor ThreadPoolTaskExecutor() { + return new ThreadPoolTaskExecutor(); + } + + @Bean + EntityManagerFactoryBuilderCustomizer asyncBootstrappingCustomizer(ThreadPoolTaskExecutor executor) { + return (builder) -> builder.setBootstrapExecutor(executor); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestConfigurationWithLocalContainerEntityManagerFactoryBeanWithNoJpaVendorAdapter + extends TestConfiguration { + + @Bean + LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { + LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); + factoryBean.setDataSource(dataSource); + factoryBean.setPersistenceUnitName("manually-configured"); + factoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); + Map properties = new HashMap<>(); + properties.put("configured", "manually"); + properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); + factoryBean.setJpaPropertyMap(properties); + return factoryBean; + } + + } + + public static class TestH2Dialect extends H2Dialect { + + } + + @Configuration(proxyBeanMethods = false) + static class JtaTransactionManagerConfiguration { + + @Bean + JtaTransactionManager jtaTransactionManager() { + JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(); + jtaTransactionManager.setUserTransaction(mock(UserTransaction.class)); + jtaTransactionManager.setTransactionManager(mock(TransactionManager.class)); + return jtaTransactionManager; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesTests.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernatePropertiesTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesTests.java rename to spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernatePropertiesTests.java index 15739fb00459..578faf5aaa38 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernatePropertiesTests.java +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/HibernatePropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure; import java.util.Map; import java.util.function.Consumer; @@ -30,7 +30,8 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; +import org.springframework.boot.hibernate.SpringImplicitNamingStrategy; +import org.springframework.boot.jpa.autoconfigure.JpaProperties; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/HibernateMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/metrics/HibernateMetricsAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/HibernateMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/metrics/HibernateMetricsAutoConfigurationTests.java index 8eab8efb6781..0998a97211c6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/orm/jpa/HibernateMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/hibernate/autoconfigure/metrics/HibernateMetricsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa; +package org.springframework.boot.hibernate.autoconfigure.metrics; import java.util.Map; import java.util.function.Function; @@ -32,13 +32,13 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration; +import org.springframework.boot.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jpa.autoconfigure.EntityManagerFactoryBuilderCustomizer; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; @@ -63,10 +63,11 @@ */ class HibernateMetricsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, - HibernateMetricsAutoConfiguration.class)) - .withUserConfiguration(BaseConfiguration.class); + HibernateMetricsAutoConfiguration.class, MetricsAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=false"); @Test void autoConfiguredEntityManagerFactoryWithStatsIsInstrumented() { @@ -154,7 +155,7 @@ void entityManagerFactoryInstrumentationDoesNotDeadlockWithDeferredInitializatio this.contextRunner .withPropertyValues("spring.jpa.properties.hibernate.generate_statistics:true", "spring.sql.init.schema-locations:city-schema.sql", "spring.sql.init.data-locations=city-data.sql") - .withConfiguration(AutoConfigurations.of(SqlInitializationAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(DataSourceInitializationAutoConfiguration.class)) .withBean(EntityManagerFactoryBuilderCustomizer.class, () -> (builder) -> builder.setBootstrapExecutor(new SimpleAsyncTaskExecutor())) .run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/mapping/NonAnnotatedEntity.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/hibernate/mapping/NonAnnotatedEntity.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/mapping/NonAnnotatedEntity.java rename to spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/hibernate/mapping/NonAnnotatedEntity.java index 4f2613a952e3..8a22dc54288f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/mapping/NonAnnotatedEntity.java +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/hibernate/mapping/NonAnnotatedEntity.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa.mapping; +package org.springframework.boot.jpa.autoconfigure.hibernate.mapping; /** * A non annotated entity that is handled by a custom "mapping-file". diff --git a/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/city/City.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/city/City.java new file mode 100644 index 000000000000..f47ec38c3f6e --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/city/City.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jpa.autoconfigure.test.city; + +import java.io.Serializable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +@EntityListeners(CityListener.class) +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + @Column(nullable = false) + private String country; + + @Column(nullable = false) + private String map; + + protected City() { + } + + public City(String name, String state, String country, String map) { + this.name = name; + this.state = state; + this.country = country; + this.map = map; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/test/CityListener.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/city/CityListener.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/test/CityListener.java rename to spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/city/CityListener.java index 2424a8473772..6ae2f5d3c4f1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/test/CityListener.java +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/city/CityListener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa.test; +package org.springframework.boot.jpa.autoconfigure.test.city; import jakarta.persistence.PostLoad; diff --git a/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/country/Country.java b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/country/Country.java new file mode 100644 index 000000000000..ba3e3f516f39 --- /dev/null +++ b/spring-boot-project/spring-boot-hibernate/src/test/java/org/springframework/boot/jpa/autoconfigure/test/country/Country.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jpa.autoconfigure.test.country; + +import java.io.Serializable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import org.hibernate.envers.Audited; + +@Entity +public class Country implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Audited + @Column + private String name; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/spring-boot-project/spring-boot-http-client/build.gradle b/spring-boot-project/spring-boot-http-client/build.gradle new file mode 100644 index 000000000000..187014bbd6bd --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/build.gradle @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot HTTP Client" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-web") + + implementation(project(":spring-boot-project:spring-boot-http-converter")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-reactor-netty")) + optional("org.apache.httpcomponents.client5:httpclient5") + optional("org.apache.httpcomponents.core5:httpcore5-reactive") + optional("org.eclipse.jetty:jetty-client") + optional("org.eclipse.jetty:jetty-reactive-httpclient") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("org.springframework:spring-webflux") + testImplementation("io.micrometer:micrometer-observation-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactoryBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactoryBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactoryBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactoryRuntimeHints.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactoryRuntimeHints.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactoryRuntimeHints.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactoryRuntimeHints.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactorySettings.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactorySettings.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactorySettings.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ClientHttpRequestFactorySettings.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/Empty.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/Empty.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/Empty.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/Empty.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpClientSettings.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpClientSettings.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpClientSettings.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpClientSettings.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsClientHttpRequestFactoryBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsClientHttpRequestFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsClientHttpRequestFactoryBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsClientHttpRequestFactoryBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsHttpAsyncClientBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsHttpAsyncClientBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsHttpAsyncClientBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsHttpAsyncClientBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsHttpClientBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsHttpClientBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsHttpClientBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsHttpClientBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsRedirectStrategy.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsRedirectStrategy.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsRedirectStrategy.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsRedirectStrategy.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsSslBundleTlsStrategy.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsSslBundleTlsStrategy.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpComponentsSslBundleTlsStrategy.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpComponentsSslBundleTlsStrategy.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpRedirects.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpRedirects.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/HttpRedirects.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/HttpRedirects.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/JdkHttpClientBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JdkHttpClientBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/JdkHttpClientBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JdkHttpClientBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/JettyHttpClientBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JettyHttpClientBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/JettyHttpClientBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JettyHttpClientBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ReactorClientHttpRequestFactoryBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ReactorClientHttpRequestFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ReactorClientHttpRequestFactoryBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ReactorClientHttpRequestFactoryBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ReactorHttpClientBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ReactorHttpClientBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ReactorHttpClientBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ReactorHttpClientBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ReflectiveComponentsClientHttpRequestFactoryBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ReflectiveComponentsClientHttpRequestFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/ReflectiveComponentsClientHttpRequestFactoryBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/ReflectiveComponentsClientHttpRequestFactoryBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/SimpleClientHttpRequestFactoryBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/SimpleClientHttpRequestFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/SimpleClientHttpRequestFactoryBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/SimpleClientHttpRequestFactoryBuilder.java diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/AbstractHttpRequestFactoryProperties.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/AbstractHttpRequestFactoryProperties.java new file mode 100644 index 000000000000..ec66226632fe --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/AbstractHttpRequestFactoryProperties.java @@ -0,0 +1,161 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure; + +import java.time.Duration; +import java.util.function.Supplier; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.http.client.ClientHttpRequestFactory; + +/** + * Base {@link ConfigurationProperties @ConfigurationProperties} for configuring a + * {@link ClientHttpRequestFactory}. + * + * @author Phillip Webb + * @since 4.0.0 + * @see ClientHttpRequestFactorySettings + */ +public abstract class AbstractHttpRequestFactoryProperties { + + /** + * Handling for HTTP redirects. + */ + private HttpRedirects redirects; + + /** + * Default connect timeout for a client HTTP request. + */ + private Duration connectTimeout; + + /** + * Default read timeout for a client HTTP request. + */ + private Duration readTimeout; + + /** + * Default SSL configuration for a client HTTP request. + */ + private final Ssl ssl = new Ssl(); + + /** + * Default factory used for a client HTTP request. + */ + private Factory factory; + + public HttpRedirects getRedirects() { + return this.redirects; + } + + public void setRedirects(HttpRedirects redirects) { + this.redirects = redirects; + } + + public Duration getConnectTimeout() { + return this.connectTimeout; + } + + public void setConnectTimeout(Duration connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public Duration getReadTimeout() { + return this.readTimeout; + } + + public void setReadTimeout(Duration readTimeout) { + this.readTimeout = readTimeout; + } + + public Ssl getSsl() { + return this.ssl; + } + + public Factory getFactory() { + return this.factory; + } + + public void setFactory(Factory factory) { + this.factory = factory; + } + + /** + * SSL configuration. + */ + public static class Ssl { + + /** + * SSL bundle to use. + */ + private String bundle; + + public String getBundle() { + return this.bundle; + } + + public void setBundle(String bundle) { + this.bundle = bundle; + } + + } + + /** + * Supported factory types. + */ + public enum Factory { + + /** + * Apache HttpComponents HttpClient. + */ + HTTP_COMPONENTS(ClientHttpRequestFactoryBuilder::httpComponents), + + /** + * Jetty's HttpClient. + */ + JETTY(ClientHttpRequestFactoryBuilder::jetty), + + /** + * Reactor-Netty. + */ + REACTOR(ClientHttpRequestFactoryBuilder::reactor), + + /** + * Java's HttpClient. + */ + JDK(ClientHttpRequestFactoryBuilder::jdk), + + /** + * Standard JDK facilities. + */ + SIMPLE(ClientHttpRequestFactoryBuilder::simple); + + private final Supplier> builderSupplier; + + Factory(Supplier> builderSupplier) { + this.builderSupplier = builderSupplier; + } + + ClientHttpRequestFactoryBuilder builder() { + return this.builderSupplier.get(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactories.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactories.java new file mode 100644 index 000000000000..5b188cdd4283 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactories.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure; + +import java.time.Duration; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.autoconfigure.AbstractHttpRequestFactoryProperties.Factory; +import org.springframework.boot.http.client.autoconfigure.AbstractHttpRequestFactoryProperties.Ssl; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.util.StringUtils; + +/** + * Helper class to create {@link ClientHttpRequestFactoryBuilder} and + * {@link ClientHttpRequestFactorySettings}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public final class ClientHttpRequestFactories { + + private final ObjectFactory sslBundles; + + private final AbstractHttpRequestFactoryProperties[] orderedProperties; + + public ClientHttpRequestFactories(ObjectFactory sslBundles, + AbstractHttpRequestFactoryProperties... orderedProperties) { + this.sslBundles = sslBundles; + this.orderedProperties = orderedProperties; + } + + public ClientHttpRequestFactoryBuilder builder(ClassLoader classLoader) { + Factory factory = getProperty(AbstractHttpRequestFactoryProperties::getFactory); + return (factory != null) ? factory.builder() : ClientHttpRequestFactoryBuilder.detect(classLoader); + } + + public ClientHttpRequestFactorySettings settings() { + HttpRedirects redirects = getProperty(AbstractHttpRequestFactoryProperties::getRedirects); + Duration connectTimeout = getProperty(AbstractHttpRequestFactoryProperties::getConnectTimeout); + Duration readTimeout = getProperty(AbstractHttpRequestFactoryProperties::getReadTimeout); + String sslBundleName = getProperty(AbstractHttpRequestFactoryProperties::getSsl, Ssl::getBundle, + StringUtils::hasLength); + SslBundle sslBundle = (StringUtils.hasLength(sslBundleName)) + ? this.sslBundles.getObject().getBundle(sslBundleName) : null; + return new ClientHttpRequestFactorySettings(redirects, connectTimeout, readTimeout, sslBundle); + } + + private T getProperty(Function accessor) { + return getProperty(accessor, Function.identity(), Objects::nonNull); + } + + private T getProperty(Function accessor, Function extractor, + Predicate predicate) { + for (AbstractHttpRequestFactoryProperties properties : this.orderedProperties) { + if (properties != null) { + P value = accessor.apply(properties); + T extracted = (value != null) ? extractor.apply(value) : null; + if (predicate.test(extracted)) { + return extracted; + } + } + } + return null; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactoryBuilderCustomizer.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactoryBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactoryBuilderCustomizer.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactoryBuilderCustomizer.java index 977bd7b84086..bc0bbb0d84a9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/ClientHttpRequestFactoryBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactoryBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client; +package org.springframework.boot.http.client.autoconfigure; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; @@ -24,7 +24,7 @@ * * @param the builder type * @author Phillip Webb - * @since 3.5.0 + * @since 4.0.0 */ public interface ClientHttpRequestFactoryBuilderCustomizer> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/HttpClientAutoConfiguration.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/HttpClientAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/HttpClientAutoConfiguration.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/HttpClientAutoConfiguration.java index b335dcd0f9fd..cb78b816aa02 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/HttpClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/HttpClientAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client; +package org.springframework.boot.http.client.autoconfigure; import java.util.List; @@ -39,7 +39,7 @@ * {@link ClientHttpRequestFactoryBuilder} and {@link ClientHttpRequestFactorySettings}. * * @author Phillip Webb - * @since 3.4.0 + * @since 4.0.0 */ @SuppressWarnings("removal") @AutoConfiguration(after = SslAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/HttpClientProperties.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/HttpClientProperties.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/HttpClientProperties.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/HttpClientProperties.java index 079fd372c7c4..2030b33cf26a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/HttpClientProperties.java +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/HttpClientProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client; +package org.springframework.boot.http.client.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/NotReactiveWebApplicationCondition.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/NotReactiveWebApplicationCondition.java new file mode 100644 index 000000000000..f0bcf1384e86 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/NotReactiveWebApplicationCondition.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; + +/** + * {@link SpringBootCondition} that applies only when running in a non-reactive web + * application. + * + * @author Phillip Webb + */ +class NotReactiveWebApplicationCondition extends NoneNestedConditions { + + NotReactiveWebApplicationCondition() { + super(ConfigurationPhase.PARSE_CONFIGURATION); + } + + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + private static final class ReactiveWebApplication { + + } + +} diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/metrics/HttpClientMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/metrics/HttpClientMetricsAutoConfiguration.java new file mode 100644 index 000000000000..69f67b5ff35b --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/metrics/HttpClientMetricsAutoConfiguration.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure.metrics; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.config.MeterFilter; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.OnlyOnceLoggingDenyMeterFilter; +import org.springframework.boot.metrics.autoconfigure.MetricsProperties; +import org.springframework.boot.metrics.autoconfigure.MetricsProperties.Web.Client; +import org.springframework.boot.observation.autoconfigure.ObservationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.core.annotation.Order; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for HTTP client-related metrics. + * + * @author Jon Schneider + * @author Phillip Webb + * @author Stephane Nicoll + * @author Raheela Aslam + * @author Brian Clozel + * @author Moritz Halbritter + * @since 4.0.0 + */ +@AutoConfiguration(afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") +@ConditionalOnClass({ ObservationProperties.class, MeterRegistry.class, MetricsProperties.class }) +@ConditionalOnBean(MeterRegistry.class) +@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class }) +public class HttpClientMetricsAutoConfiguration { + + @Bean + @Order(0) + MeterFilter metricsHttpClientUriTagFilter(ObservationProperties observationProperties, + MetricsProperties metricsProperties) { + Client clientProperties = metricsProperties.getWeb().getClient(); + String name = observationProperties.getHttp().getClient().getRequests().getName(); + MeterFilter denyFilter = new OnlyOnceLoggingDenyMeterFilter( + () -> "Reached the maximum number of URI tags for '%s'. Are you using 'uriVariables'?".formatted(name)); + return MeterFilter.maximumAllowableTags(name, "uri", clientProperties.getMaxUriTags(), denyFilter); + } + +} diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..a23ee946b904 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for client-side HTTP metrics. + */ +package org.springframework.boot.http.client.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/package-info.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/package-info.java new file mode 100644 index 000000000000..761ff0b7489d --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for client-side HTTP. + */ +package org.springframework.boot.http.client.autoconfigure; diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/AbstractClientHttpConnectorProperties.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/AbstractClientHttpConnectorProperties.java new file mode 100644 index 000000000000..844769aa7241 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/AbstractClientHttpConnectorProperties.java @@ -0,0 +1,156 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure.reactive; + +import java.time.Duration; +import java.util.function.Supplier; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; +import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; +import org.springframework.http.client.reactive.ClientHttpConnector; + +/** + * Base {@link ConfigurationProperties @ConfigurationProperties} for configuring a + * {@link ClientHttpConnector}. + * + * @author Phillip Webb + * @since 3.5.0 + * @see ClientHttpConnectorSettings + */ +public abstract class AbstractClientHttpConnectorProperties { + + /** + * Handling for HTTP redirects. + */ + private HttpRedirects redirects; + + /** + * Default connect timeout for a client HTTP request. + */ + private Duration connectTimeout; + + /** + * Default read timeout for a client HTTP request. + */ + private Duration readTimeout; + + /** + * Default SSL configuration for a client HTTP request. + */ + private final Ssl ssl = new Ssl(); + + /** + * Default connector used for a client HTTP request. + */ + private Connector connector; + + public HttpRedirects getRedirects() { + return this.redirects; + } + + public void setRedirects(HttpRedirects redirects) { + this.redirects = redirects; + } + + public Duration getConnectTimeout() { + return this.connectTimeout; + } + + public void setConnectTimeout(Duration connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public Duration getReadTimeout() { + return this.readTimeout; + } + + public void setReadTimeout(Duration readTimeout) { + this.readTimeout = readTimeout; + } + + public Ssl getSsl() { + return this.ssl; + } + + public Connector getConnector() { + return this.connector; + } + + public void setConnector(Connector connector) { + this.connector = connector; + } + + /** + * SSL configuration. + */ + public static class Ssl { + + /** + * SSL bundle to use. + */ + private String bundle; + + public String getBundle() { + return this.bundle; + } + + public void setBundle(String bundle) { + this.bundle = bundle; + } + + } + + /** + * Supported factory types. + */ + public enum Connector { + + /** + * Reactor-Netty. + */ + REACTOR(ClientHttpConnectorBuilder::reactor), + + /** + * Jetty's HttpClient. + */ + JETTY(ClientHttpConnectorBuilder::jetty), + + /** + * Apache HttpComponents HttpClient. + */ + HTTP_COMPONENTS(ClientHttpConnectorBuilder::httpComponents), + + /** + * Java's HttpClient. + */ + JDK(ClientHttpConnectorBuilder::jdk); + + private final Supplier> builderSupplier; + + Connector(Supplier> builderSupplier) { + this.builderSupplier = builderSupplier; + } + + ClientHttpConnectorBuilder builder() { + return this.builderSupplier.get(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorAutoConfiguration.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorAutoConfiguration.java new file mode 100644 index 000000000000..4d5db4705fa8 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorAutoConfiguration.java @@ -0,0 +1,108 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure.reactive; + +import java.util.List; + +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; +import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; +import org.springframework.boot.reactor.netty.autoconfigure.ReactorNettyConfigurations; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.boot.util.LambdaSafe; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Lazy; +import org.springframework.http.client.reactive.ClientHttpConnector; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link ClientHttpConnectorBuilder} and {@link ClientHttpConnectorSettings}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +@AutoConfiguration(after = SslAutoConfiguration.class) +@ConditionalOnClass({ ClientHttpConnector.class, Mono.class }) +@Conditional(ConditionalOnClientHttpConnectorBuilderDetection.class) +@EnableConfigurationProperties(HttpReactiveClientProperties.class) +public class ClientHttpConnectorAutoConfiguration implements BeanClassLoaderAware { + + private final ClientHttpConnectors connectors; + + private ClassLoader beanClassLoader; + + ClientHttpConnectorAutoConfiguration(ObjectProvider sslBundles, + HttpReactiveClientProperties properties) { + this.connectors = new ClientHttpConnectors(sslBundles, properties); + } + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.beanClassLoader = classLoader; + } + + @Bean + @ConditionalOnMissingBean + ClientHttpConnectorBuilder clientHttpConnectorBuilder( + ObjectProvider> clientHttpConnectorBuilderCustomizers) { + ClientHttpConnectorBuilder builder = this.connectors.builder(this.beanClassLoader); + return customize(builder, clientHttpConnectorBuilderCustomizers.orderedStream().toList()); + } + + @SuppressWarnings("unchecked") + private ClientHttpConnectorBuilder customize(ClientHttpConnectorBuilder builder, + List> customizers) { + ClientHttpConnectorBuilder[] builderReference = { builder }; + LambdaSafe.callbacks(ClientHttpConnectorBuilderCustomizer.class, customizers, builderReference[0]) + .invoke((customizer) -> builderReference[0] = customizer.customize(builderReference[0])); + return builderReference[0]; + } + + @Bean + @ConditionalOnMissingBean + ClientHttpConnectorSettings clientHttpConnectorSettings() { + return this.connectors.settings(); + } + + @Bean + @Lazy + @ConditionalOnMissingBean + ClientHttpConnector clientHttpConnector(ClientHttpConnectorBuilder clientHttpConnectorBuilder, + ClientHttpConnectorSettings clientHttpRequestFactorySettings) { + return clientHttpConnectorBuilder.build(clientHttpRequestFactorySettings); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ reactor.netty.http.client.HttpClient.class, ReactorNettyConfigurations.class }) + @Import(ReactorNettyConfigurations.ReactorResourceFactoryConfiguration.class) + static class ReactorNetty { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorBuilderCustomizer.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorBuilderCustomizer.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorBuilderCustomizer.java index 5157921564d5..fa6cc3a2efbf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive; +package org.springframework.boot.http.client.autoconfigure.reactive; import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectors.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectors.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectors.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectors.java index b99fef6c71f1..412353786375 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectors.java +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectors.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive; +package org.springframework.boot.http.client.autoconfigure.reactive; import java.time.Duration; import java.util.Objects; @@ -22,9 +22,9 @@ import java.util.function.Predicate; import org.springframework.beans.factory.ObjectFactory; -import org.springframework.boot.autoconfigure.http.client.AbstractHttpClientProperties.Ssl; -import org.springframework.boot.autoconfigure.http.client.reactive.AbstractClientHttpConnectorProperties.Connector; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.autoconfigure.reactive.AbstractClientHttpConnectorProperties.Connector; +import org.springframework.boot.http.client.autoconfigure.reactive.AbstractClientHttpConnectorProperties.Ssl; import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; import org.springframework.boot.ssl.SslBundle; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ConditionalOnClientHttpConnectorBuilderDetection.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ConditionalOnClientHttpConnectorBuilderDetection.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ConditionalOnClientHttpConnectorBuilderDetection.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ConditionalOnClientHttpConnectorBuilderDetection.java index 44e949d72eb9..7bf517f6d538 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/ConditionalOnClientHttpConnectorBuilderDetection.java +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/ConditionalOnClientHttpConnectorBuilderDetection.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive; +package org.springframework.boot.http.client.autoconfigure.reactive; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/HttpReactiveClientProperties.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/HttpReactiveClientProperties.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/HttpReactiveClientProperties.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/HttpReactiveClientProperties.java index ece4cf609fd4..9c0a09bf140b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/HttpReactiveClientProperties.java +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/HttpReactiveClientProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive; +package org.springframework.boot.http.client.autoconfigure.reactive; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; @@ -24,7 +24,7 @@ * apply to Spring's reactive client HTTP connectors. * * @author Phillip Webb - * @since 3.5.0 + * @since 4.0.0 * @see ClientHttpConnectorSettings */ @ConfigurationProperties("spring.http.reactiveclient") diff --git a/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..b13038f2f6c3 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for client-side reactive HTTP. + */ +package org.springframework.boot.http.client.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/package-info.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/package-info.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/package-info.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorSettings.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorSettings.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorSettings.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorSettings.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/HttpComponentsClientHttpConnectorBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/HttpComponentsClientHttpConnectorBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/HttpComponentsClientHttpConnectorBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/HttpComponentsClientHttpConnectorBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/JdkClientHttpConnectorBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/JdkClientHttpConnectorBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/JdkClientHttpConnectorBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/JdkClientHttpConnectorBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/ReactorClientHttpConnectorBuilder.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/ReactorClientHttpConnectorBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/ReactorClientHttpConnectorBuilder.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/ReactorClientHttpConnectorBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/package-info.java b/spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/http/client/reactive/package-info.java rename to spring-boot-project/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/package-info.java diff --git a/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..980d82c81437 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.http.client.ClientHttpRequestFactoryRuntimeHints diff --git a/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..bb71dd8618f1 --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.http.client.autoconfigure.HttpClientAutoConfiguration +org.springframework.boot.http.client.autoconfigure.metrics.HttpClientMetricsAutoConfiguration +org.springframework.boot.http.client.autoconfigure.reactive.ClientHttpConnectorAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilderTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilderTests.java index d6979a0fe9f6..0312620c452e 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilderTests.java +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/AbstractClientHttpRequestFactoryBuilderTests.java @@ -40,8 +40,7 @@ import org.springframework.boot.ssl.jks.JksSslStoreBundle; import org.springframework.boot.ssl.jks.JksSslStoreDetails; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl.ClientAuth; import org.springframework.boot.web.server.WebServer; @@ -62,7 +61,6 @@ * @author Phillip Webb * @author Andy Wilkinson */ -@DirtiesUrlFactories abstract class AbstractClientHttpRequestFactoryBuilderTests { private static final Function ALWAYS_FOUND = (method) -> HttpStatus.FOUND; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactoryBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactoryBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactoryBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactoryBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactoryRuntimeHintsTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactoryRuntimeHintsTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactoryRuntimeHintsTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactoryRuntimeHintsTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactorySettingsTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactorySettingsTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactorySettingsTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ClientHttpRequestFactorySettingsTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/HttpComponentsClientHttpRequestFactoryBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/HttpComponentsClientHttpRequestFactoryBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/HttpComponentsClientHttpRequestFactoryBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/HttpComponentsClientHttpRequestFactoryBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/JdkClientHttpRequestFactoryBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ReactorClientHttpRequestFactoryBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ReactorClientHttpRequestFactoryBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ReactorClientHttpRequestFactoryBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ReactorClientHttpRequestFactoryBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ReflectiveComponentsClientHttpRequestFactoryBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ReflectiveComponentsClientHttpRequestFactoryBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/ReflectiveComponentsClientHttpRequestFactoryBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/ReflectiveComponentsClientHttpRequestFactoryBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/SimpleClientHttpRequestFactoryBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/SimpleClientHttpRequestFactoryBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/SimpleClientHttpRequestFactoryBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/SimpleClientHttpRequestFactoryBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/TestCustomizer.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/TestCustomizer.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/TestCustomizer.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/TestCustomizer.java diff --git a/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactoriesTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactoriesTests.java new file mode 100644 index 000000000000..5e6070e79f0e --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/ClientHttpRequestFactoriesTests.java @@ -0,0 +1,98 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure; + +import java.time.Duration; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.HttpComponentsClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.JettyClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.autoconfigure.AbstractHttpRequestFactoryProperties.Factory; +import org.springframework.boot.ssl.DefaultSslBundleRegistry; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.ssl.SslBundles; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link ClientHttpRequestFactories} + * + * @author Phillip Webb + */ +class ClientHttpRequestFactoriesTests { + + private final DefaultSslBundleRegistry bundleRegistry = new DefaultSslBundleRegistry(); + + private ObjectFactory sslBundles = () -> this.bundleRegistry; + + @Test + void builderWhenHasFactoryPropertyReturnsFirst() { + TestProperties p1 = new TestProperties(); + TestProperties p2 = new TestProperties(); + p2.setFactory(Factory.JETTY); + TestProperties p3 = new TestProperties(); + p3.setFactory(Factory.REACTOR); + ClientHttpRequestFactories factories = new ClientHttpRequestFactories(this.sslBundles, p1, p2, p3); + assertThat(factories.builder(null)).isInstanceOf(JettyClientHttpRequestFactoryBuilder.class); + } + + @Test + void buildWhenHasNoFactoryPropertyReturnsDetected() { + TestProperties properties = new TestProperties(); + ClientHttpRequestFactories factories = new ClientHttpRequestFactories(this.sslBundles, properties); + assertThat(factories.builder(null)).isInstanceOf(HttpComponentsClientHttpRequestFactoryBuilder.class); + } + + @Test + void settingsWhenHasNoSettingProperties() { + TestProperties properties = new TestProperties(); + ClientHttpRequestFactories factories = new ClientHttpRequestFactories(this.sslBundles, properties); + ClientHttpRequestFactorySettings settings = factories.settings(); + assertThat(settings).isEqualTo(new ClientHttpRequestFactorySettings(null, null, null, null)); + } + + @Test + void settingsWhenHasMultipleSettingProperties() { + this.bundleRegistry.registerBundle("p2", mock(SslBundle.class)); + this.bundleRegistry.registerBundle("p3", mock(SslBundle.class)); + TestProperties p1 = new TestProperties(); + TestProperties p2 = new TestProperties(); + p2.setRedirects(HttpRedirects.DONT_FOLLOW); + p2.setConnectTimeout(Duration.ofSeconds(1)); + p2.setReadTimeout(Duration.ofSeconds(2)); + p2.getSsl().setBundle("p2"); + TestProperties p3 = new TestProperties(); + p3.setRedirects(HttpRedirects.FOLLOW); + p3.setConnectTimeout(Duration.ofSeconds(10)); + p3.setReadTimeout(Duration.ofSeconds(20)); + p3.getSsl().setBundle("p3"); + ClientHttpRequestFactories factories = new ClientHttpRequestFactories(this.sslBundles, p1, p2, p3); + ClientHttpRequestFactorySettings settings = factories.settings(); + assertThat(settings).isEqualTo(new ClientHttpRequestFactorySettings(HttpRedirects.DONT_FOLLOW, + Duration.ofSeconds(1), Duration.ofSeconds(2), this.bundleRegistry.getBundle("p2"))); + } + + static class TestProperties extends AbstractHttpRequestFactoryProperties { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/HttpClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/HttpClientAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/HttpClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/HttpClientAutoConfigurationTests.java index ba6ceed93acc..d845d1728d10 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/HttpClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/HttpClientAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client; +package org.springframework.boot.http.client.autoconfigure; import java.time.Duration; import java.util.ArrayList; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/HttpClientPropertiesTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/HttpClientPropertiesTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/HttpClientPropertiesTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/HttpClientPropertiesTests.java index 6f739b312216..f7905b7d5a8f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/HttpClientPropertiesTests.java +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/HttpClientPropertiesTests.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client; +package org.springframework.boot.http.client.autoconfigure; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.http.client.AbstractHttpRequestFactoryProperties.Factory; import org.springframework.boot.http.client.HttpComponentsClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.JdkClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.JettyClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ReactorClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.SimpleClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.autoconfigure.AbstractHttpRequestFactoryProperties.Factory; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/metrics/HttpClientMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/metrics/HttpClientMetricsAutoConfigurationTests.java new file mode 100644 index 000000000000..1d4f07cf634e --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/metrics/HttpClientMetricsAutoConfigurationTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure.metrics; + +import java.time.Duration; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link HttpClientMetricsAutoConfiguration}. + * + * @author Andy Wilkinson + */ +@ExtendWith(OutputCaptureExtension.class) +class HttpClientMetricsAutoConfigurationTests { + + @Test + void afterMaxUrisReachedFurtherUrisAreDenied(CapturedOutput output) { + new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(HttpClientMetricsAutoConfiguration.class, MetricsAutoConfiguration.class)) + .withBean(SimpleMeterRegistry.class) + .withPropertyValues("management.metrics.web.client.max-uri-tags=2") + .run((context) -> { + MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); + for (int i = 0; i < 3; i++) { + meterRegistry.timer("http.client.requests", "uri", "/test/" + i).record(Duration.ofSeconds(1)); + } + assertThat(meterRegistry.find("http.client.requests").timers()).hasSize(2); + assertThat(output).contains("Reached the maximum number of URI tags for 'http.client.requests'.") + .contains("Are you using 'uriVariables'?"); + }); + } + +} diff --git a/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorAutoConfigurationTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorAutoConfigurationTests.java new file mode 100644 index 000000000000..204e096cae6b --- /dev/null +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorAutoConfigurationTests.java @@ -0,0 +1,215 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.client.autoconfigure.reactive; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; + +import org.apache.hc.client5.http.impl.async.HttpAsyncClients; +import org.junit.jupiter.api.Test; +import reactor.netty.http.client.HttpClient; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; +import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; +import org.springframework.boot.http.client.reactive.JdkClientHttpConnectorBuilder; +import org.springframework.boot.http.client.reactive.JettyClientHttpConnectorBuilder; +import org.springframework.boot.http.client.reactive.ReactorClientHttpConnectorBuilder; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ReactorResourceFactory; +import org.springframework.http.client.reactive.ClientHttpConnector; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link ClientHttpConnectorAutoConfiguration} + * + * @author Brian Clozel + * @author Phillip Webb + */ +class ClientHttpConnectorAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( + AutoConfigurations.of(ClientHttpConnectorAutoConfiguration.class, SslAutoConfiguration.class)); + + @Test + void whenReactorIsAvailableThenReactorBeansAreDefined() { + this.contextRunner.run((context) -> { + BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("clientHttpConnector"); + assertThat(connectorDefinition.isLazyInit()).isTrue(); + assertThat(context).hasSingleBean(ReactorResourceFactory.class); + assertThat(context.getBean(ClientHttpConnectorBuilder.class)) + .isExactlyInstanceOf(ReactorClientHttpConnectorBuilder.class); + }); + } + + @Test + void whenReactorIsUnavailableThenJettyClientBeansAreDefined() { + this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class)).run((context) -> { + BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("clientHttpConnector"); + assertThat(connectorDefinition.isLazyInit()).isTrue(); + assertThat(context.getBean(ClientHttpConnectorBuilder.class)) + .isExactlyInstanceOf(JettyClientHttpConnectorBuilder.class); + }); + } + + @Test + void whenReactorAndHttpClientAreUnavailableThenJettyClientBeansAreDefined() { + this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class, HttpAsyncClients.class)) + .run((context) -> { + BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("clientHttpConnector"); + assertThat(connectorDefinition.isLazyInit()).isTrue(); + assertThat(context.getBean(ClientHttpConnectorBuilder.class)) + .isExactlyInstanceOf(JettyClientHttpConnectorBuilder.class); + }); + } + + @Test + void whenReactorAndHttpClientAndJettyAreUnavailableThenJdkClientBeansAreDefined() { + this.contextRunner + .withClassLoader(new FilteredClassLoader(HttpClient.class, HttpAsyncClients.class, + org.eclipse.jetty.client.HttpClient.class)) + .run((context) -> { + BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("clientHttpConnector"); + assertThat(connectorDefinition.isLazyInit()).isTrue(); + assertThat(context.getBean(ClientHttpConnectorBuilder.class)) + .isExactlyInstanceOf(JdkClientHttpConnectorBuilder.class); + }); + } + + @Test + void shouldNotOverrideCustomClientConnector() { + this.contextRunner.withUserConfiguration(CustomClientHttpConnectorConfig.class).run((context) -> { + assertThat(context).hasSingleBean(ClientHttpConnector.class); + assertThat(context).hasBean("customConnector"); + }); + } + + @Test + void shouldUseCustomReactorResourceFactory() { + this.contextRunner.withUserConfiguration(CustomReactorResourceConfig.class).run((context) -> { + assertThat(context).hasSingleBean(ClientHttpConnector.class); + assertThat(context).hasSingleBean(ReactorResourceFactory.class); + assertThat(context).hasBean("customReactorResourceFactory"); + }); + } + + @Test + void configuresDetectedClientHttpConnectorBuilderBuilder() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ClientHttpConnectorBuilder.class)); + } + + @Test + void configuresDefinedClientHttpConnectorBuilder() { + this.contextRunner.withPropertyValues("spring.http.reactiveclient.connector=jetty") + .run((context) -> assertThat(context.getBean(ClientHttpConnectorBuilder.class)) + .isInstanceOf(JettyClientHttpConnectorBuilder.class)); + } + + @Test + void configuresClientHttpConnectorSettings() { + this.contextRunner.withPropertyValues(sslPropertyValues().toArray(String[]::new)) + .withPropertyValues("spring.http.reactiveclient.redirects=dont-follow", + "spring.http.reactiveclient.connect-timeout=10s", "spring.http.reactiveclient.read-timeout=20s", + "spring.http.reactiveclient.ssl.bundle=test") + .run((context) -> { + ClientHttpConnectorSettings settings = context.getBean(ClientHttpConnectorSettings.class); + assertThat(settings.redirects()).isEqualTo(HttpRedirects.DONT_FOLLOW); + assertThat(settings.connectTimeout()).isEqualTo(Duration.ofSeconds(10)); + assertThat(settings.readTimeout()).isEqualTo(Duration.ofSeconds(20)); + assertThat(settings.sslBundle().getKey().getAlias()).isEqualTo("alias1"); + }); + } + + @Test + void shouldBeConditionalOnAtLeastOneHttpConnectorClass() { + FilteredClassLoader classLoader = new FilteredClassLoader(reactor.netty.http.client.HttpClient.class, + org.eclipse.jetty.client.HttpClient.class, org.apache.hc.client5.http.impl.async.HttpAsyncClients.class, + java.net.http.HttpClient.class); + assertThatIllegalStateException().as("enough filtering") + .isThrownBy(() -> ClientHttpConnectorBuilder.detect(classLoader)); + this.contextRunner.withClassLoader(classLoader) + .run((context) -> assertThat(context).doesNotHaveBean(ClientHttpConnectorSettings.class)); + } + + private List sslPropertyValues() { + List propertyValues = new ArrayList<>(); + String location = "classpath:org/springframework/boot/autoconfigure/ssl/"; + propertyValues.add("spring.ssl.bundle.pem.test.key.alias=alias1"); + propertyValues.add("spring.ssl.bundle.pem.test.truststore.type=PKCS12"); + propertyValues.add("spring.ssl.bundle.pem.test.truststore.certificate=" + location + "rsa-cert.pem"); + propertyValues.add("spring.ssl.bundle.pem.test.truststore.private-key=" + location + "rsa-key.pem"); + return propertyValues; + } + + @Test + void clientHttpConnectorBuilderCustomizersAreApplied() { + this.contextRunner.withPropertyValues("spring.http.reactiveclient.connector=jdk") + .withUserConfiguration(ClientHttpConnectorBuilderCustomizersConfiguration.class) + .run((context) -> { + ClientHttpConnector connector = context.getBean(ClientHttpConnectorBuilder.class).build(); + assertThat(connector).extracting("readTimeout").isEqualTo(Duration.ofSeconds(5)); + }); + } + + @Configuration(proxyBeanMethods = false) + static class CustomClientHttpConnectorConfig { + + @Bean + ClientHttpConnector customConnector() { + return mock(ClientHttpConnector.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomReactorResourceConfig { + + @Bean + ReactorResourceFactory customReactorResourceFactory() { + return new ReactorResourceFactory(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ClientHttpConnectorBuilderCustomizersConfiguration { + + @Bean + ClientHttpConnectorBuilderCustomizer jdkCustomizer() { + return (builder) -> builder.withCustomizer((connector) -> connector.setReadTimeout(Duration.ofSeconds(5))); + } + + @Bean + ClientHttpConnectorBuilderCustomizer jettyCustomizer() { + return (builder) -> { + throw new IllegalStateException(); + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorsTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorsTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorsTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorsTests.java index 05cf03de1bdd..1c38495be569 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/ClientHttpConnectorsTests.java +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/ClientHttpConnectorsTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive; +package org.springframework.boot.http.client.autoconfigure.reactive; import java.time.Duration; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectFactory; -import org.springframework.boot.autoconfigure.http.client.reactive.AbstractClientHttpConnectorProperties.Connector; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.autoconfigure.reactive.AbstractClientHttpConnectorProperties.Connector; import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; import org.springframework.boot.http.client.reactive.JettyClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.ReactorClientHttpConnectorBuilder; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/HttpReactiveClientSettingsPropertiesTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/HttpReactiveClientSettingsPropertiesTests.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/HttpReactiveClientSettingsPropertiesTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/HttpReactiveClientSettingsPropertiesTests.java index 6ad379ba83e9..c65d9b202ec3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/HttpReactiveClientSettingsPropertiesTests.java +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/autoconfigure/reactive/HttpReactiveClientSettingsPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive; +package org.springframework.boot.http.client.autoconfigure.reactive; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.http.client.reactive.AbstractClientHttpConnectorProperties.Connector; +import org.springframework.boot.http.client.autoconfigure.reactive.AbstractClientHttpConnectorProperties.Connector; import org.springframework.boot.http.client.reactive.HttpComponentsClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.JdkClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.JettyClientHttpConnectorBuilder; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilderTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilderTests.java index d3e990713813..3fbc886cfe90 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilderTests.java +++ b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/AbstractClientHttpConnectorBuilderTests.java @@ -40,8 +40,7 @@ import org.springframework.boot.ssl.jks.JksSslStoreBundle; import org.springframework.boot.ssl.jks.JksSslStoreDetails; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl.ClientAuth; import org.springframework.boot.web.server.WebServer; @@ -63,7 +62,6 @@ * @author Phillip Webb * @author Andy Wilkinson */ -@DirtiesUrlFactories abstract class AbstractClientHttpConnectorBuilderTests { private static final Function ALWAYS_FOUND = (method) -> HttpStatus.FOUND; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/HttpComponentsClientHttpConnectorBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/HttpComponentsClientHttpConnectorBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/HttpComponentsClientHttpConnectorBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/HttpComponentsClientHttpConnectorBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/JdkClientHttpConnectorBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/JdkClientHttpConnectorBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/JdkClientHttpConnectorBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/JdkClientHttpConnectorBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/ReactorClientHttpConnectorBuilderTests.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/ReactorClientHttpConnectorBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/ReactorClientHttpConnectorBuilderTests.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/ReactorClientHttpConnectorBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/TestCustomizer.java b/spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/TestCustomizer.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/TestCustomizer.java rename to spring-boot-project/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/TestCustomizer.java diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/http/client/reactive/test.jks b/spring-boot-project/spring-boot-http-client/src/test/resources/org/springframework/boot/http/client/reactive/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/http/client/reactive/test.jks rename to spring-boot-project/spring-boot-http-client/src/test/resources/org/springframework/boot/http/client/reactive/test.jks diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/http/client/test.jks b/spring-boot-project/spring-boot-http-client/src/test/resources/org/springframework/boot/http/client/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/http/client/test.jks rename to spring-boot-project/spring-boot-http-client/src/test/resources/org/springframework/boot/http/client/test.jks diff --git a/spring-boot-project/spring-boot-http-codec/build.gradle b/spring-boot-project/spring-boot-http-codec/build.gradle new file mode 100644 index 000000000000..ec2b858e7dfd --- /dev/null +++ b/spring-boot-project/spring-boot-http-codec/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot HTTP Codec" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-web") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-jackson")) + optional("org.springframework:spring-webflux") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/codec/CodecCustomizer.java b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/CodecCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/codec/CodecCustomizer.java rename to spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/CodecCustomizer.java index a96e36821174..5d60dbf38958 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/codec/CodecCustomizer.java +++ b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/CodecCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.codec; +package org.springframework.boot.http.codec; import org.springframework.http.codec.CodecConfigurer; @@ -23,7 +23,7 @@ * client and/or server with a {@link CodecConfigurer}. * * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface CodecCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfiguration.java b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfiguration.java rename to spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfiguration.java index 797c7e97d532..c2a294025b91 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.codec; +package org.springframework.boot.http.codec.autoconfigure; import com.fasterxml.jackson.databind.ObjectMapper; @@ -22,10 +22,9 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.codec.CodecCustomizer; +import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -44,7 +43,7 @@ * @author Brian Clozel * @since 2.0.0 */ -@AutoConfiguration(after = JacksonAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration") @ConditionalOnClass({ CodecConfigurer.class, WebClient.class }) public class CodecsAutoConfiguration { @@ -70,19 +69,15 @@ CodecCustomizer jacksonCodecCustomizer(ObjectMapper objectMapper) { } - @SuppressWarnings("removal") @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties({ org.springframework.boot.autoconfigure.codec.CodecProperties.class, - HttpCodecsProperties.class }) + @EnableConfigurationProperties(HttpCodecsProperties.class) static class DefaultCodecsConfiguration { @Bean - DefaultCodecCustomizer defaultCodecCustomizer( - org.springframework.boot.autoconfigure.codec.CodecProperties codecProperties, - HttpCodecsProperties httpCodecProperties, Environment environment) { - return new DefaultCodecCustomizer( - httpCodecProperties.isLogRequestDetails(codecProperties::isLogRequestDetails), - httpCodecProperties.getMaxInMemorySize(codecProperties::getMaxInMemorySize)); + DefaultCodecCustomizer defaultCodecCustomizer(HttpCodecsProperties httpCodecProperties, + Environment environment) { + return new DefaultCodecCustomizer(httpCodecProperties.isLogRequestDetails(), + httpCodecProperties.getMaxInMemorySize()); } static final class DefaultCodecCustomizer implements CodecCustomizer, Ordered { diff --git a/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/HttpCodecsProperties.java b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/HttpCodecsProperties.java new file mode 100644 index 000000000000..c6ad9af9bccc --- /dev/null +++ b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/HttpCodecsProperties.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.codec.autoconfigure; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.unit.DataSize; + +/** + * {@link ConfigurationProperties Properties} for reactive HTTP codecs. + * + * @author Brian Clozel + * @author Andy Wilkinson + * @since 3.5.0 + */ +@ConfigurationProperties("spring.http.codecs") +public class HttpCodecsProperties { + + /** + * Whether to log form data at DEBUG level, and headers at TRACE level. + */ + private boolean logRequestDetails; + + /** + * Limit on the number of bytes that can be buffered whenever the input stream needs + * to be aggregated. This applies only to the auto-configured WebFlux server and + * WebClient instances. By default this is not set, in which case individual codec + * defaults apply. Most codecs are limited to 256K by default. + */ + private DataSize maxInMemorySize; + + public boolean isLogRequestDetails() { + return this.logRequestDetails; + } + + public void setLogRequestDetails(boolean logRequestDetails) { + this.logRequestDetails = logRequestDetails; + } + + public DataSize getMaxInMemorySize() { + return this.maxInMemorySize; + } + + public void setMaxInMemorySize(DataSize maxInMemorySize) { + this.maxInMemorySize = maxInMemorySize; + } + +} diff --git a/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/package-info.java b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/package-info.java new file mode 100644 index 000000000000..955ac067ea24 --- /dev/null +++ b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for HTTP codecs. + */ +package org.springframework.boot.http.codec.autoconfigure; diff --git a/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/package-info.java b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/package-info.java new file mode 100644 index 000000000000..d6b8bdfa7eea --- /dev/null +++ b/spring-boot-project/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for web-based codecs. + */ +package org.springframework.boot.http.codec; diff --git a/spring-boot-project/spring-boot-http-codec/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-http-codec/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-http-codec/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-http-codec/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-http-codec/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..b99c83d2eca5 --- /dev/null +++ b/spring-boot-project/spring-boot-http-codec/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration diff --git a/spring-boot-project/spring-boot-http-codec/src/test/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfigurationTests.java b/spring-boot-project/spring-boot-http-codec/src/test/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfigurationTests.java new file mode 100644 index 000000000000..d43c0bc6bd37 --- /dev/null +++ b/spring-boot-project/spring-boot-http-codec/src/test/java/org/springframework/boot/http/codec/autoconfigure/CodecsAutoConfigurationTests.java @@ -0,0 +1,152 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.codec.autoconfigure; + +import java.util.List; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.http.codec.CodecCustomizer; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.http.codec.CodecConfigurer; +import org.springframework.http.codec.CodecConfigurer.DefaultCodecs; +import org.springframework.http.codec.support.DefaultClientCodecConfigurer; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CodecsAutoConfiguration}. + * + * @author Madhura Bhave + * @author Andy Wilkinson + */ +class CodecsAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(CodecsAutoConfiguration.class)); + + @Test + void autoConfigShouldProvideALoggingRequestDetailsCustomizer() { + this.contextRunner.run((context) -> assertThat(defaultCodecs(context)) + .hasFieldOrPropertyWithValue("enableLoggingRequestDetails", false)); + } + + @Test + void loggingRequestDetailsCustomizerShouldUseHttpCodecsProperties() { + this.contextRunner.withPropertyValues("spring.http.codecs.log-request-details=true") + .run((context) -> assertThat(defaultCodecs(context)) + .hasFieldOrPropertyWithValue("enableLoggingRequestDetails", true)); + } + + @Test + void maxInMemorySizeShouldUseHttpCodecProperties() { + this.contextRunner.withPropertyValues("spring.http.codecs.max-in-memory-size=64KB") + .run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize", + 64 * 1024)); + } + + @Test + void defaultCodecCustomizerBeanShouldHaveOrderZero() { + this.contextRunner + .run((context) -> assertThat(context.getBean("defaultCodecCustomizer", Ordered.class).getOrder()).isZero()); + } + + @Test + void jacksonCodecCustomizerBacksOffWhenThereIsNoObjectMapper() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean("jacksonCodecCustomizer")); + } + + @Test + void jacksonCodecCustomizerIsAutoConfiguredWhenObjectMapperIsPresent() { + this.contextRunner.withUserConfiguration(ObjectMapperConfiguration.class) + .run((context) -> assertThat(context).hasBean("jacksonCodecCustomizer")); + } + + @Test + void userProvidedCustomizerCanOverrideJacksonCodecCustomizer() { + this.contextRunner.withUserConfiguration(ObjectMapperConfiguration.class, CodecCustomizerConfiguration.class) + .run((context) -> { + List codecCustomizers = context.getBean(CodecCustomizers.class).codecCustomizers; + assertThat(codecCustomizers).hasSize(3); + assertThat(codecCustomizers.get(2)).isInstanceOf(TestCodecCustomizer.class); + }); + } + + @Test + void maxInMemorySizeEnforcedInDefaultCodecs() { + this.contextRunner.withPropertyValues("spring.http.codecs.max-in-memory-size=1MB") + .run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize", + 1048576)); + } + + private DefaultCodecs defaultCodecs(AssertableApplicationContext context) { + CodecCustomizer customizer = context.getBean(CodecCustomizer.class); + CodecConfigurer configurer = new DefaultClientCodecConfigurer(); + customizer.customize(configurer); + return configurer.defaultCodecs(); + } + + @Configuration(proxyBeanMethods = false) + static class ObjectMapperConfiguration { + + @Bean + ObjectMapper objectMapper() { + return new ObjectMapper(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CodecCustomizerConfiguration { + + @Bean + CodecCustomizer codecCustomizer() { + return new TestCodecCustomizer(); + } + + @Bean + CodecCustomizers codecCustomizers(List customizers) { + return new CodecCustomizers(customizers); + } + + } + + private static final class TestCodecCustomizer implements CodecCustomizer { + + @Override + public void customize(CodecConfigurer configurer) { + } + + } + + private static final class CodecCustomizers { + + private final List codecCustomizers; + + private CodecCustomizers(List codecCustomizers) { + this.codecCustomizers = codecCustomizers; + } + + } + +} diff --git a/spring-boot-project/spring-boot-http-converter/build.gradle b/spring-boot-project/spring-boot-http-converter/build.gradle new file mode 100644 index 000000000000..521116b64ab5 --- /dev/null +++ b/spring-boot-project/spring-boot-http-converter/build.gradle @@ -0,0 +1,52 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot HTTP Converter" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-web") + + compileOnly("jakarta.servlet:jakarta.servlet-api") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-gson")) + optional(project(":spring-boot-project:spring-boot-jackson")) + optional(project(":spring-boot-project:spring-boot-jsonb")) + optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml") + optional("com.google.code.gson:gson") + optional("jakarta.json.bind:jakarta.json.bind-api") + optional("org.springframework:spring-webmvc") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("org.springframework.data:spring-data-rest-webmvc") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor") + testRuntimeOnly("jakarta.servlet:jakarta.servlet-api") + testRuntimeOnly("org.eclipse:yasson") + testRuntimeOnly("org.springframework:spring-webflux") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/GsonHttpMessageConvertersConfiguration.java b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/GsonHttpMessageConvertersConfiguration.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/GsonHttpMessageConvertersConfiguration.java rename to spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/GsonHttpMessageConvertersConfiguration.java index 027fa6290aeb..79e3c646ca51 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/GsonHttpMessageConvertersConfiguration.java +++ b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/GsonHttpMessageConvertersConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import com.google.gson.Gson; @@ -22,8 +22,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.boot.autoconfigure.http.ConditionalOnPreferredJsonMapper.JsonMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -60,7 +60,8 @@ private static class PreferGsonOrJacksonAndJsonbUnavailableCondition extends Any super(ConfigurationPhase.REGISTER_BEAN); } - @ConditionalOnPreferredJsonMapper(JsonMapper.GSON) + @ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, + havingValue = "gson") static class GsonPreferred { } @@ -84,7 +85,8 @@ static class JacksonAvailable { } - @ConditionalOnPreferredJsonMapper(JsonMapper.JSONB) + @ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, + havingValue = "jsonb") static class JsonbPreferred { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConverters.java b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConverters.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConverters.java rename to spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConverters.java index 774306dfa754..296dc6180cab 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConverters.java +++ b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConverters.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import java.util.ArrayList; import java.util.Arrays; @@ -48,7 +48,7 @@ * @author Dave Syer * @author Phillip Webb * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 * @see #HttpMessageConverters(HttpMessageConverter...) * @see #HttpMessageConverters(Collection) * @see #getConverters() diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.java b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.java rename to spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfiguration.java index 4889db57e06f..1c9f14999a0d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.java +++ b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -24,11 +24,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration.NotReactiveWebApplicationCondition; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration.NotReactiveWebApplicationCondition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -48,16 +45,19 @@ * @author Sebastien Deleuze * @author Stephane Nicoll * @author Eddú Meléndez - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration( - after = { GsonAutoConfiguration.class, JacksonAutoConfiguration.class, JsonbAutoConfiguration.class }) +@AutoConfiguration(afterName = { "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration", + "org.springframework.boot.jsonb.autoconfigure.JsonbAutoConfiguration", + "org.springframework.boot.gson.autoconfigure.GsonAutoConfiguration" }) @ConditionalOnClass(HttpMessageConverter.class) @Conditional(NotReactiveWebApplicationCondition.class) @Import({ JacksonHttpMessageConvertersConfiguration.class, GsonHttpMessageConvertersConfiguration.class, JsonbHttpMessageConvertersConfiguration.class }) public class HttpMessageConvertersAutoConfiguration { + static final String PREFERRED_MAPPER_PROPERTY = "spring.http.converters.preferred-json-mapper"; + @Bean @ConditionalOnMissingBean public HttpMessageConverters messageConverters(ObjectProvider> converters) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersProperties.java b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersProperties.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersProperties.java rename to spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersProperties.java index eaf5d7a76a4b..fb141e1fec32 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersProperties.java +++ b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/JacksonHttpMessageConvertersConfiguration.java b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/JacksonHttpMessageConvertersConfiguration.java similarity index 82% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/JacksonHttpMessageConvertersConfiguration.java rename to spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/JacksonHttpMessageConvertersConfiguration.java index d2604eebc999..a6e53490f4d1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/JacksonHttpMessageConvertersConfiguration.java +++ b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/JacksonHttpMessageConvertersConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; @@ -22,7 +22,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.http.ConditionalOnPreferredJsonMapper.JsonMapper; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @@ -41,14 +41,14 @@ class JacksonHttpMessageConvertersConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(ObjectMapper.class) @ConditionalOnBean(ObjectMapper.class) - @ConditionalOnPreferredJsonMapper(JsonMapper.JACKSON) + @ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, + havingValue = "jackson", matchIfMissing = true) static class MappingJackson2HttpMessageConverterConfiguration { @Bean - @ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class, - ignoredType = { - "org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter", - "org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" }) + @ConditionalOnMissingBean(ignoredType = { + "org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter", + "org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" }) MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) { return new MappingJackson2HttpMessageConverter(objectMapper); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/JsonbHttpMessageConvertersConfiguration.java b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/JsonbHttpMessageConvertersConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/JsonbHttpMessageConvertersConfiguration.java rename to spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/JsonbHttpMessageConvertersConfiguration.java index d15dc1f8cbd7..440cfa555a84 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/JsonbHttpMessageConvertersConfiguration.java +++ b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/JsonbHttpMessageConvertersConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import jakarta.json.bind.Jsonb; @@ -22,7 +22,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.http.ConditionalOnPreferredJsonMapper.JsonMapper; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -59,7 +59,8 @@ private static class PreferJsonbOrMissingJacksonAndGsonCondition extends AnyNest super(ConfigurationPhase.REGISTER_BEAN); } - @ConditionalOnPreferredJsonMapper(JsonMapper.JSONB) + @ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, + havingValue = "jsonb") static class JsonbPreferred { } diff --git a/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/MessageConverterBackgroundPreinitializer.java b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/MessageConverterBackgroundPreinitializer.java new file mode 100644 index 000000000000..c0b83033b200 --- /dev/null +++ b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/MessageConverterBackgroundPreinitializer.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.http.converter.autoconfigure; + +import org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; + +/** + * {@link BackgroundPreinitializer} Spring's {@link HttpMessageConverter} implementations. + * + * @author Phillip Webb + */ +final class MessageConverterBackgroundPreinitializer implements BackgroundPreinitializer { + + @Override + public void preinitialize() throws Exception { + new AllEncompassingFormHttpMessageConverter(); + } + +} diff --git a/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/package-info.java b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/package-info.java new file mode 100644 index 000000000000..f8b87f5ab81b --- /dev/null +++ b/spring-boot-project/spring-boot-http-converter/src/main/java/org/springframework/boot/http/converter/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for HTTP converters. + */ +package org.springframework.boot.http.converter.autoconfigure; diff --git a/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..d2a39422bf94 --- /dev/null +++ b/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,31 @@ +{ + "properties": [ + { + "name": "spring.http.converters.preferred-json-mapper", + "type": "java.lang.String", + "defaultValue": "jackson", + "description": "Preferred JSON mapper to use for HTTP message conversion. By default, auto-detected according to the environment. Supported values are 'jackson', 'gson', and 'jsonb'. When other json mapping libraries (such as kotlinx.serialization) are present, use a custom HttpMessageConverters bean to control the preferred mapper." + } + ], + "hints": [ + { + "name": "spring.http.converters.preferred-json-mapper", + "values": [ + { + "value": "gson" + }, + { + "value": "jackson" + }, + { + "value": "jsonb" + } + ], + "providers": [ + { + "name": "any" + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..0ae7a5e48b65 --- /dev/null +++ b/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Background Preinitializers +org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer=\ +org.springframework.boot.http.converter.autoconfigure.MessageConverterBackgroundPreinitializer diff --git a/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..06c28ed7ca84 --- /dev/null +++ b/spring-boot-project/spring-boot-http-converter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationTests.java b/spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationTests.java similarity index 77% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationTests.java rename to spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationTests.java index 70178acb0e96..93c7974fd8e9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationTests.java @@ -14,22 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import java.nio.charset.StandardCharsets; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; -import org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.http.converter.autoconfigure.JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -114,14 +111,14 @@ void gsonNotAvailable() { @Test void gsonDefaultConverter() { - this.contextRunner.withConfiguration(AutoConfigurations.of(GsonAutoConfiguration.class)) + this.contextRunner.withBean(Gson.class) .run(assertConverter(GsonHttpMessageConverter.class, "gsonHttpMessageConverter")); } @Test void gsonCustomConverter() { this.contextRunner.withUserConfiguration(GsonConverterConfig.class) - .withConfiguration(AutoConfigurations.of(GsonAutoConfiguration.class)) + .withBean(Gson.class) .run(assertConverter(GsonHttpMessageConverter.class, "customGsonMessageConverter")); } @@ -135,31 +132,6 @@ void gsonCanBePreferred() { }); } - @Test - @Deprecated(since = "3.5.0", forRemoval = true) - void gsonCanBePreferredWithDeprecatedProperty() { - allOptionsRunner().withPropertyValues("spring.mvc.converters.preferred-json-mapper:gson").run((context) -> { - assertConverterBeanExists(context, GsonHttpMessageConverter.class, "gsonHttpMessageConverter"); - assertConverterBeanRegisteredWithHttpMessageConverters(context, GsonHttpMessageConverter.class); - assertThat(context).doesNotHaveBean(JsonbHttpMessageConverter.class); - assertThat(context).doesNotHaveBean(MappingJackson2HttpMessageConverter.class); - }); - } - - @Test - @Deprecated(since = "3.5.0", forRemoval = true) - void gsonCanBePreferredWithNonDeprecatedPropertyTakingPrecedence() { - allOptionsRunner() - .withPropertyValues("spring.http.converters.preferred-json-mapper:gson", - "spring.mvc.converters.preferred-json-mapper:jackson") - .run((context) -> { - assertConverterBeanExists(context, GsonHttpMessageConverter.class, "gsonHttpMessageConverter"); - assertConverterBeanRegisteredWithHttpMessageConverters(context, GsonHttpMessageConverter.class); - assertThat(context).doesNotHaveBean(JsonbHttpMessageConverter.class); - assertThat(context).doesNotHaveBean(MappingJackson2HttpMessageConverter.class); - }); - } - @Test void jsonbNotAvailable() { this.contextRunner.run((context) -> { @@ -170,14 +142,14 @@ void jsonbNotAvailable() { @Test void jsonbDefaultConverter() { - this.contextRunner.withConfiguration(AutoConfigurations.of(JsonbAutoConfiguration.class)) + this.contextRunner.withBean(Jsonb.class, JsonbBuilder::create) .run(assertConverter(JsonbHttpMessageConverter.class, "jsonbHttpMessageConverter")); } @Test void jsonbCustomConverter() { this.contextRunner.withUserConfiguration(JsonbConverterConfig.class) - .withConfiguration(AutoConfigurations.of(JsonbAutoConfiguration.class)) + .withBean(Jsonb.class, JsonbBuilder::create) .run(assertConverter(JsonbHttpMessageConverter.class, "customJsonbMessageConverter")); } @@ -191,31 +163,6 @@ void jsonbCanBePreferred() { }); } - @Test - @Deprecated(since = "3.5.0", forRemoval = true) - void jsonbCanBePreferredWithDeprecatedProperty() { - allOptionsRunner().withPropertyValues("spring.mvc.converters.preferred-json-mapper:jsonb").run((context) -> { - assertConverterBeanExists(context, JsonbHttpMessageConverter.class, "jsonbHttpMessageConverter"); - assertConverterBeanRegisteredWithHttpMessageConverters(context, JsonbHttpMessageConverter.class); - assertThat(context).doesNotHaveBean(GsonHttpMessageConverter.class); - assertThat(context).doesNotHaveBean(MappingJackson2HttpMessageConverter.class); - }); - } - - @Test - @Deprecated(since = "3.5.0", forRemoval = true) - void jsonbCanBePreferredWithNonDeprecatedPropertyTakingPrecedence() { - allOptionsRunner() - .withPropertyValues("spring.http.converters.preferred-json-mapper:jsonb", - "spring.mvc.converters.preferred-json-mapper:gson") - .run((context) -> { - assertConverterBeanExists(context, JsonbHttpMessageConverter.class, "jsonbHttpMessageConverter"); - assertConverterBeanRegisteredWithHttpMessageConverters(context, JsonbHttpMessageConverter.class); - assertThat(context).doesNotHaveBean(GsonHttpMessageConverter.class); - assertThat(context).doesNotHaveBean(MappingJackson2HttpMessageConverter.class); - }); - } - @Test void stringDefaultConverter() { this.contextRunner.run(assertConverter(StringHttpMessageConverter.class, "stringHttpMessageConverter")); @@ -317,19 +264,10 @@ void whenEncodingCharsetIsConfiguredThenStringMessageConverterUsesSpecificCharse }); } - @Test // gh-21789 - void whenAutoConfigurationIsActiveThenServerPropertiesConfigurationPropertiesAreNotEnabled() { - new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpMessageConvertersAutoConfiguration.class)) - .run((context) -> { - assertThat(context).hasSingleBean(HttpMessageConverters.class); - assertThat(context).doesNotHaveBean(ServerProperties.class); - }); - } - private ApplicationContextRunner allOptionsRunner() { - return this.contextRunner.withConfiguration(AutoConfigurations.of(GsonAutoConfiguration.class, - JacksonAutoConfiguration.class, JsonbAutoConfiguration.class)); + return this.contextRunner.withBean(Gson.class) + .withBean(ObjectMapper.class) + .withBean(Jsonb.class, JsonbBuilder::create); } private ContextConsumer assertConverter( diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationWithoutJacksonTests.java b/spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationWithoutJacksonTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationWithoutJacksonTests.java rename to spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationWithoutJacksonTests.java index 7615d9256555..2c4a8ffdb4d3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationWithoutJacksonTests.java +++ b/spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersAutoConfigurationWithoutJacksonTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersTests.java b/spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersTests.java rename to spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersTests.java index 1e4750983687..baf81f76a541 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersTests.java +++ b/spring-boot-project/spring-boot-http-converter/src/test/java/org/springframework/boot/http/converter/autoconfigure/HttpMessageConvertersTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http; +package org.springframework.boot.http.converter.autoconfigure; import java.util.ArrayList; import java.util.Collection; @@ -33,7 +33,6 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; -import org.springframework.http.converter.yaml.MappingJackson2YamlHttpMessageConverter; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -58,7 +57,7 @@ void containsDefaults() { StringHttpMessageConverter.class, ResourceHttpMessageConverter.class, ResourceRegionHttpMessageConverter.class, AllEncompassingFormHttpMessageConverter.class, MappingJackson2HttpMessageConverter.class, MappingJackson2CborHttpMessageConverter.class, - MappingJackson2YamlHttpMessageConverter.class, MappingJackson2XmlHttpMessageConverter.class); + MappingJackson2XmlHttpMessageConverter.class); } @Test @@ -127,8 +126,7 @@ protected List> postProcessConverters(List> postProcessPartConverters( } assertThat(converterClasses).containsExactly(ByteArrayHttpMessageConverter.class, StringHttpMessageConverter.class, ResourceHttpMessageConverter.class, - MappingJackson2HttpMessageConverter.class, MappingJackson2CborHttpMessageConverter.class, - MappingJackson2YamlHttpMessageConverter.class); + MappingJackson2HttpMessageConverter.class, MappingJackson2CborHttpMessageConverter.class); } private List> extractFormPartConverters(List> converters) { diff --git a/spring-boot-project/spring-boot-integration-tests/build.gradle b/spring-boot-project/spring-boot-integration-tests/build.gradle new file mode 100644 index 000000000000..0e7d91cc7c05 --- /dev/null +++ b/spring-boot-project/spring-boot-integration-tests/build.gradle @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java" +} + +description = "Spring Boot Integration Tests" + +dependencies { + testImplementation(project(":spring-boot-project:spring-boot")) + testImplementation(project(":spring-boot-project:spring-boot-jetty")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-undertow")) + testImplementation("io.projectreactor.netty:reactor-netty-http") + testImplementation("org.apache.httpcomponents.client5:httpclient5") + testImplementation("org.apache.httpcomponents.core5:httpcore5-reactive") + testImplementation("org.eclipse.jetty:jetty-client") + testImplementation("org.eclipse.jetty:jetty-reactive-httpclient") + testImplementation("org.springframework:spring-webflux") + testImplementation("org.springframework:spring-webmvc") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("io.undertow:undertow-servlet") + testRuntimeOnly("org.eclipse.jetty.ee10:jetty-ee10-servlets") + testRuntimeOnly("org.eclipse.jetty.ee10:jetty-ee10-webapp") +} + +test { + jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterIntegrationTests.java b/spring-boot-project/spring-boot-integration-tests/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterIntegrationTests.java rename to spring-boot-project/spring-boot-integration-tests/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterIntegrationTests.java index 3cacb75e3626..35b803d4e4aa 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-integration-tests/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterIntegrationTests.java @@ -27,9 +27,9 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.support.ErrorPageFilterIntegrationTests.EmbeddedWebContextLoader; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-integration/build.gradle b/spring-boot-project/spring-boot-integration/build.gradle new file mode 100644 index 000000000000..6734538cff78 --- /dev/null +++ b/spring-boot-project/spring-boot-integration/build.gradle @@ -0,0 +1,56 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Integration" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.integration:spring-integration-core") + + implementation(project(":spring-boot-project:spring-boot-sql")) + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-jdbc")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-rsocket")) + optional("org.springframework.integration:spring-integration-jdbc") + optional("org.springframework.integration:spring-integration-jmx") + optional("org.springframework.integration:spring-integration-rsocket") + + testImplementation(project(":spring-boot-project:spring-boot-flyway")) + testImplementation(project(":spring-boot-project:spring-boot-rsocket")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) + testImplementation("org.springframework:spring-web") + + testRuntimeOnly(project(":spring-boot-project:spring-boot-reactor-netty")) + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java rename to spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfiguration.java index 484b19fdde56..dedaeea2740d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import java.time.Duration; @@ -25,7 +25,6 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; @@ -35,16 +34,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; import org.springframework.boot.autoconfigure.condition.SearchStrategy; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxProperties; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition; import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration; import org.springframework.boot.autoconfigure.thread.Threading; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; +import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.sql.autoconfigure.init.OnDatabaseInitializationCondition; import org.springframework.boot.task.SimpleAsyncTaskSchedulerBuilder; import org.springframework.boot.task.ThreadPoolTaskSchedulerBuilder; import org.springframework.context.ApplicationContext; @@ -87,10 +85,11 @@ * @author Madhura Bhave * @author Yong-Hyun Kim * @author Yanming Zhou - * @since 1.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { DataSourceAutoConfiguration.class, JmxAutoConfiguration.class, - TaskSchedulingAutoConfiguration.class }) +@AutoConfiguration(beforeName = "org.springframework.boot.rsocket.autoconfigure.RSocketMessagingAutoConfiguration", + after = { JmxAutoConfiguration.class, TaskSchedulingAutoConfiguration.class }, + afterName = "org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration") @ConditionalOnClass(EnableIntegration.class) @EnableConfigurationProperties({ IntegrationProperties.class, JmxProperties.class }) public class IntegrationAutoConfiguration { @@ -265,7 +264,7 @@ protected static class IntegrationComponentScanConfiguration { * Integration JDBC configuration. */ @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(JdbcMessageStore.class) + @ConditionalOnClass({ JdbcMessageStore.class, DataSourceScriptDatabaseInitializer.class }) @ConditionalOnSingleCandidate(DataSource.class) @Conditional(OnIntegrationDatasourceInitializationCondition.class) protected static class IntegrationJdbcConfiguration { @@ -311,7 +310,6 @@ static class RSocketOutboundGatewayAvailable { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(TcpServerTransport.class) - @AutoConfigureBefore(RSocketMessagingAutoConfiguration.class) protected static class IntegrationRSocketServerConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationScanRegistrar.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfigurationScanRegistrar.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationScanRegistrar.java rename to spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfigurationScanRegistrar.java index d21749e78043..1b44677a502b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationScanRegistrar.java +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfigurationScanRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import java.util.Collection; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationDataSourceScriptDatabaseInitializer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializer.java rename to spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationDataSourceScriptDatabaseInitializer.java index 906015ce359f..4a947661b695 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationDataSourceScriptDatabaseInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import java.util.List; @@ -32,7 +32,7 @@ * * @author Vedran Pavic * @author Andy Wilkinson - * @since 2.6.0 + * @since 4.0.0 */ public class IntegrationDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java rename to spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationProperties.java index 2b3b9e737e33..c0a5fea09003 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import java.net.URI; import java.time.Duration; @@ -30,7 +30,7 @@ * @author Vedran Pavic * @author Stephane Nicoll * @author Artem Bilan - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.integration") public class IntegrationProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationPropertiesEnvironmentPostProcessor.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationPropertiesEnvironmentPostProcessor.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationPropertiesEnvironmentPostProcessor.java rename to spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationPropertiesEnvironmentPostProcessor.java index 5eab59047a27..751e7c11f188 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationPropertiesEnvironmentPostProcessor.java +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/IntegrationPropertiesEnvironmentPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import java.io.IOException; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/PollerMetadataCustomizer.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/PollerMetadataCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/PollerMetadataCustomizer.java rename to spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/PollerMetadataCustomizer.java index aee3dcb75e50..5a9e05f3c080 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/PollerMetadataCustomizer.java +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/PollerMetadataCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import org.springframework.integration.scheduling.PollerMetadata; @@ -23,7 +23,7 @@ * {@link PollerMetadata} whilst retaining default auto-configuration. * * @author Yanming Zhou - * @since 3.5.0 + * @since 4.0.0 */ @FunctionalInterface public interface PollerMetadataCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/endpoint/IntegrationGraphEndpointAutoConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointAutoConfiguration.java rename to spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/endpoint/IntegrationGraphEndpointAutoConfiguration.java index 763e0f9b47ab..4297151c9914 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/endpoint/IntegrationGraphEndpointAutoConfiguration.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure.endpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; +import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration; +import org.springframework.boot.integration.endpoint.IntegrationGraphEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.integration.config.IntegrationConfigurationBeanFactoryPostProcessor; import org.springframework.integration.graph.IntegrationGraphServer; @@ -34,10 +34,11 @@ * * @author Tim Ysewyn * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = IntegrationAutoConfiguration.class) -@ConditionalOnClass(IntegrationGraphServer.class) +@ConditionalOnClass({ IntegrationGraphServer.class, IntegrationGraphEndpoint.class, + ConditionalOnAvailableEndpoint.class }) @ConditionalOnBean(IntegrationConfigurationBeanFactoryPostProcessor.class) @ConditionalOnAvailableEndpoint(IntegrationGraphEndpoint.class) public class IntegrationGraphEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/endpoint/package-info.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/endpoint/package-info.java new file mode 100644 index 000000000000..6c649a89da38 --- /dev/null +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Integration endpoint. + */ +package org.springframework.boot.integration.autoconfigure.endpoint; diff --git a/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/metrics/IntegrationMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/metrics/IntegrationMetricsAutoConfiguration.java new file mode 100644 index 000000000000..d3090a8c83be --- /dev/null +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/metrics/IntegrationMetricsAutoConfiguration.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.integration.autoconfigure.metrics; + +import io.micrometer.core.instrument.MeterRegistry; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Integration's metrics. + * Orders auto-configuration classes to ensure that the {@link MeterRegistry} bean has + * been defined before Spring Integration's Micrometer support queries the bean factory + * for it. + * + * @author Andy Wilkinson + */ +@AutoConfiguration(before = IntegrationAutoConfiguration.class, + afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") +class IntegrationMetricsAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..c778c0dd31ea --- /dev/null +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Integration metrics. + */ +package org.springframework.boot.integration.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/package-info.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/package-info.java new file mode 100644 index 000000000000..9265113755b3 --- /dev/null +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Integration. + */ +package org.springframework.boot.integration.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpoint.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpoint.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpoint.java rename to spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpoint.java index 13ec3271dbcd..0d0c6021112b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpoint.java +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpoint.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.integration; +package org.springframework.boot.integration.endpoint; import java.util.Collection; import java.util.Map; @@ -32,7 +32,7 @@ * {@link Endpoint @Endpoint} to expose the Spring Integration graph. * * @author Tim Ysewyn - * @since 2.1.0 + * @since 4.0.0 */ @Endpoint(id = "integrationgraph") public class IntegrationGraphEndpoint { diff --git a/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/endpoint/package-info.java b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/endpoint/package-info.java new file mode 100644 index 000000000000..32bb9ce52f0c --- /dev/null +++ b/spring-boot-project/spring-boot-integration/src/main/java/org/springframework/boot/integration/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator endpoint for Spring Integration. + */ +package org.springframework.boot.integration.endpoint; diff --git a/spring-boot-project/spring-boot-integration/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-integration/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..92b0d0837995 --- /dev/null +++ b/spring-boot-project/spring-boot-integration/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Environment Post Processors +org.springframework.boot.env.EnvironmentPostProcessor=\ +org.springframework.boot.integration.autoconfigure.IntegrationPropertiesEnvironmentPostProcessor diff --git a/spring-boot-project/spring-boot-integration/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-integration/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..f67355c6e439 --- /dev/null +++ b/spring-boot-project/spring-boot-integration/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration +org.springframework.boot.integration.autoconfigure.endpoint.IntegrationGraphEndpointAutoConfiguration +org.springframework.boot.integration.autoconfigure.metrics.IntegrationMetricsAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java rename to spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfigurationTests.java index 22ff39611874..16fed9dd4219 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import java.beans.PropertyDescriptor; import java.time.Duration; @@ -39,20 +39,21 @@ import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.PropertyAccessorFactory; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration.IntegrationComponentScanConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration; +import org.springframework.boot.context.annotation.UserConfigurations; import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration.IntegrationComponentScanConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.rsocket.autoconfigure.RSocketMessagingAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketRequesterAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketServerAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketStrategiesAutoConfiguration; import org.springframework.boot.sql.init.DatabaseInitializationMode; import org.springframework.boot.sql.init.DatabaseInitializationSettings; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -77,6 +78,8 @@ import org.springframework.integration.handler.BridgeHandler; import org.springframework.integration.handler.LoggingHandler; import org.springframework.integration.handler.MessageProcessor; +import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport; +import org.springframework.integration.monitor.IntegrationMBeanExporter; import org.springframework.integration.rsocket.ClientRSocketConnector; import org.springframework.integration.rsocket.IntegrationRSocketEndpoint; import org.springframework.integration.rsocket.ServerRSocketConnector; @@ -152,7 +155,7 @@ void enableJmxIntegration() { this.contextRunner.withPropertyValues("spring.jmx.enabled=true").run((context) -> { MBeanServer mBeanServer = context.getBean(MBeanServer.class); assertThat(mBeanServer.getDomains()).contains("org.springframework.integration", - "org.springframework.boot.autoconfigure.integration"); + "org.springframework.boot.integration.autoconfigure"); assertThat(context).hasBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME); }); } @@ -175,6 +178,17 @@ void customizeJmxDomain() { }); } + @Test + void customJmxDomainUsingEnableIntegrationMBeanExport() { + this.contextRunner.withConfiguration(UserConfigurations.of(CustomJmxDomainConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, IntegrationAutoConfiguration.class)) + .run((context) -> { + assertThat(context).hasSingleBean(IntegrationMBeanExporter.class); + IntegrationMBeanExporter exporter = context.getBean(IntegrationMBeanExporter.class); + assertThat(exporter).hasFieldOrPropertyWithValue("domain", "foo.my"); + }); + } + @Test void primaryExporterIsAllowed() { this.contextRunner.withPropertyValues("spring.jmx.enabled=true") @@ -674,4 +688,10 @@ public String toString() { } + @Configuration(proxyBeanMethods = false) + @EnableIntegrationMBeanExport(defaultDomain = "foo.my") + static class CustomJmxDomainConfiguration { + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationDataSourceScriptDatabaseInitializerTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializerTests.java rename to spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationDataSourceScriptDatabaseInitializerTests.java index 7ab4fb2fe33c..d0d0c097ccd7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationDataSourceScriptDatabaseInitializerTests.java +++ b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationDataSourceScriptDatabaseInitializerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import javax.sql.DataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationPropertiesEnvironmentPostProcessorTests.java b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationPropertiesEnvironmentPostProcessorTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationPropertiesEnvironmentPostProcessorTests.java rename to spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationPropertiesEnvironmentPostProcessorTests.java index f05ea88ea054..59a72e8fa7be 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationPropertiesEnvironmentPostProcessorTests.java +++ b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/IntegrationPropertiesEnvironmentPostProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure; import java.io.FileNotFoundException; import java.lang.reflect.Modifier; @@ -160,11 +160,11 @@ private static List integrationPropertyNames() { @MethodSource("mappedConfigurationProperties") @ParameterizedTest void mappedPropertiesExistOnBootsIntegrationProperties(String mapping) { - Bindable bindable = Bindable - .of(org.springframework.boot.autoconfigure.integration.IntegrationProperties.class); + Bindable bindable = Bindable + .of(org.springframework.boot.integration.autoconfigure.IntegrationProperties.class); MockEnvironment environment = new MockEnvironment().withProperty(mapping, (mapping.contains("max") || mapping.contains("timeout")) ? "1" : "true"); - BindResult result = Binder + BindResult result = Binder .get(environment) .bind("spring.integration", bindable); assertThat(result.isBound()).isTrue(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/endpoint/IntegrationGraphEndpointAutoConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointAutoConfigurationTests.java rename to spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/endpoint/IntegrationGraphEndpointAutoConfigurationTests.java index a81eed685dbc..aebf7d5b510d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integration/IntegrationGraphEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/endpoint/IntegrationGraphEndpointAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integration; +package org.springframework.boot.integration.autoconfigure.endpoint; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; +import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration; +import org.springframework.boot.integration.endpoint.IntegrationGraphEndpoint; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.integration.graph.IntegrationGraphServer; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/IntegrationMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/metrics/IntegrationMetricsAutoConfigurationTests.java similarity index 76% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/IntegrationMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/metrics/IntegrationMetricsAutoConfigurationTests.java index 83e5608e88ff..029609145542 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/integration/IntegrationMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/autoconfigure/metrics/IntegrationMetricsAutoConfigurationTests.java @@ -14,16 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.integration; +package org.springframework.boot.integration.autoconfigure.metrics; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.integration.IntegrationGraphEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; +import org.springframework.boot.integration.autoconfigure.IntegrationAutoConfiguration; +import org.springframework.boot.integration.autoconfigure.endpoint.IntegrationGraphEndpointAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -37,9 +38,11 @@ class IntegrationMetricsAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(IntegrationAutoConfiguration.class, - IntegrationGraphEndpointAutoConfiguration.class, IntegrationMetricsAutoConfiguration.class)) - .with(MetricsRun.simple()) - .withPropertyValues("management.metrics.tags.someTag=someValue"); + IntegrationGraphEndpointAutoConfiguration.class, IntegrationMetricsAutoConfiguration.class, + MetricsAutoConfiguration.class)) + .withBean(SimpleMeterRegistry.class) + .withPropertyValues("management.metrics.tags.someTag=someValue", + "management.metrics.use-global-registry=false"); @Test void integrationMetersAreInstrumented() { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointTests.java b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpointTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointTests.java rename to spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpointTests.java index c53a112822b7..e7bdbb07d710 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointTests.java +++ b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpointTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.integration; +package org.springframework.boot.integration.endpoint; import java.util.ArrayList; import java.util.Collection; @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint.GraphDescriptor; +import org.springframework.boot.integration.endpoint.IntegrationGraphEndpoint.GraphDescriptor; import org.springframework.integration.graph.Graph; import org.springframework.integration.graph.IntegrationGraphServer; import org.springframework.integration.graph.IntegrationNode; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpointWebIntegrationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpointWebIntegrationTests.java index 263bd242baa4..dfc2a62d7838 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-integration/src/test/java/org/springframework/boot/integration/endpoint/IntegrationGraphEndpointWebIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.integration; +package org.springframework.boot.integration.endpoint; import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/integration/spring.integration.properties b/spring-boot-project/spring-boot-integration/src/test/resources/org/springframework/boot/integration/autoconfigure/spring.integration.properties similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/integration/spring.integration.properties rename to spring-boot-project/spring-boot-integration/src/test/resources/org/springframework/boot/integration/autoconfigure/spring.integration.properties diff --git a/spring-boot-project/spring-boot-jackson/build.gradle b/spring-boot-project/spring-boot-jackson/build.gradle new file mode 100644 index 000000000000..1b57b2336040 --- /dev/null +++ b/spring-boot-project/spring-boot-jackson/build.gradle @@ -0,0 +1,44 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Jackson" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("com.fasterxml.jackson.core:jackson-databind") + + implementation("org.springframework:spring-web") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor") + optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml") + optional("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") + optional("com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations") + optional("com.fasterxml.jackson.module:jackson-module-parameter-names") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonComponent.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonComponent.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonComponent.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonComponent.java index 64e91b90dfe8..44fe45c06710 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonComponent.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonComponent.java @@ -55,7 +55,7 @@ * * * @see JsonComponentModule - * @since 1.4.0 + * @since 4.0.0 * @author Phillip Webb * @author Paul Aly */ diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonComponentModule.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonComponentModule.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonComponentModule.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonComponentModule.java index 90d10f020b86..261473e1acb3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonComponentModule.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonComponentModule.java @@ -57,7 +57,7 @@ * * @author Phillip Webb * @author Paul Aly - * @since 1.4.0 + * @since 4.0.0 * @see JsonComponent */ public class JsonComponentModule extends SimpleModule implements BeanFactoryAware, InitializingBean { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixin.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixin.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixin.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixin.java index 0ce430c76e23..3e5e563b0834 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixin.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixin.java @@ -30,7 +30,7 @@ * * @author Guirong Hu * @see JsonMixinModule - * @since 2.7.0 + * @since 4.0.0 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixinModule.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixinModule.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixinModule.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixinModule.java index 92671d54b592..69872d568554 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixinModule.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixinModule.java @@ -26,7 +26,7 @@ * * @author Guirong Hu * @author Stephane Nicoll - * @since 2.7.0 + * @since 4.0.0 * @see JsonMixin */ public class JsonMixinModule extends SimpleModule { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntries.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntries.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntries.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntries.java index 0a1d5d1b9313..6231f7f1246f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntries.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntries.java @@ -38,7 +38,7 @@ * Provide the mapping of json mixin class to consider. * * @author Stephane Nicoll - * @since 3.0.0 + * @since 4.0.0 */ public final class JsonMixinModuleEntries { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntriesBeanRegistrationAotProcessor.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntriesBeanRegistrationAotProcessor.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntriesBeanRegistrationAotProcessor.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonMixinModuleEntriesBeanRegistrationAotProcessor.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectDeserializer.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonObjectDeserializer.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectDeserializer.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonObjectDeserializer.java index 3a3012b43921..8e9e3fc25e89 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectDeserializer.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonObjectDeserializer.java @@ -38,7 +38,7 @@ * * @param the supported object type * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 * @see JsonObjectSerializer */ public abstract class JsonObjectDeserializer extends com.fasterxml.jackson.databind.JsonDeserializer { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectSerializer.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonObjectSerializer.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectSerializer.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonObjectSerializer.java index e248f1112a96..ef6254375f66 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectSerializer.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/JsonObjectSerializer.java @@ -28,7 +28,7 @@ * * @param the supported object type * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 * @see JsonObjectDeserializer */ public abstract class JsonObjectSerializer extends JsonSerializer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/Jackson2ObjectMapperBuilderCustomizer.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/Jackson2ObjectMapperBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/Jackson2ObjectMapperBuilderCustomizer.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/Jackson2ObjectMapperBuilderCustomizer.java index db1fc7189c9c..02267227440f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/Jackson2ObjectMapperBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/Jackson2ObjectMapperBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jackson; +package org.springframework.boot.jackson.autoconfigure; import com.fasterxml.jackson.databind.ObjectMapper; @@ -26,7 +26,7 @@ * auto-configuration. * * @author Grzegorz Poznachowski - * @since 1.4.0 + * @since 4.0.0 */ @FunctionalInterface @SuppressWarnings("removal") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java index 54bcfccc4cfa..a9685aecc04b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jackson; +package org.springframework.boot.jackson.autoconfigure; import java.lang.reflect.Field; import java.text.DateFormat; @@ -49,11 +49,11 @@ import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jackson.JacksonProperties.ConstructorDetectorStrategy; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jackson.JsonComponentModule; import org.springframework.boot.jackson.JsonMixinModule; import org.springframework.boot.jackson.JsonMixinModuleEntries; +import org.springframework.boot.jackson.autoconfigure.JacksonProperties.ConstructorDetectorStrategy; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -82,7 +82,7 @@ * @author Phillip Webb * @author Eddú Meléndez * @author Ralf Ueberfuhr - * @since 1.1.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(ObjectMapper.class) diff --git a/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonBackgroundPreinitializer.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonBackgroundPreinitializer.java new file mode 100644 index 000000000000..6763ba9d6ae3 --- /dev/null +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonBackgroundPreinitializer.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jackson.autoconfigure; + +import org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +/** + * {@link JacksonBackgroundPreinitializer} for Jackson. + * + * @author Phillip Webb + */ +@SuppressWarnings("removal") +final class JacksonBackgroundPreinitializer implements BackgroundPreinitializer { + + @Override + public void preinitialize() throws Exception { + Jackson2ObjectMapperBuilder.json().build(); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java index 758db90966dc..ced5e641a9a7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jackson; +package org.springframework.boot.jackson.autoconfigure; import java.util.EnumMap; import java.util.Locale; @@ -41,7 +41,7 @@ * @author Marcel Overdijk * @author Johannes Edmeier * @author Eddú Meléndez - * @since 1.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.jackson") public class JacksonProperties { diff --git a/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/package-info.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/package-info.java new file mode 100644 index 000000000000..1dd8b6487c47 --- /dev/null +++ b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Jackson. + */ +package org.springframework.boot.jackson.autoconfigure; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/package-info.java b/spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/package-info.java rename to spring-boot-project/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/package-info.java diff --git a/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..aa7027015550 --- /dev/null +++ b/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,20 @@ +{ + "properties": [ + { + "name": "spring.jackson.constructor-detector", + "defaultValue": "default" + }, + { + "name": "spring.jackson.datatype.enum", + "description": "Jackson on/off features for enums." + }, + { + "name": "spring.jackson.joda-date-time-format", + "type": "java.lang.String", + "description": "Joda date time format string. If not configured, \"date-format\" is used as a fallback if it is configured with a format string.", + "deprecation": { + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..2726c4bd0696 --- /dev/null +++ b/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Background Preinitializers +org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer=\ +org.springframework.boot.jackson.autoconfigure.JacksonBackgroundPreinitializer diff --git a/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..3e334b6ac072 --- /dev/null +++ b/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,8 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration$JacksonAutoConfigurationRuntimeHints + +org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=\ +org.springframework.boot.jackson.JsonComponentModule$JsonComponentBeanFactoryInitializationAotProcessor + +org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\ +org.springframework.boot.jackson.JsonMixinModuleEntriesBeanRegistrationAotProcessor diff --git a/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..a34159d6087d --- /dev/null +++ b/spring-boot-project/spring-boot-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonComponentModuleTests.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonComponentModuleTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonComponentModuleTests.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonComponentModuleTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonMixinModuleEntriesBeanRegistrationAotProcessorTests.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonMixinModuleEntriesBeanRegistrationAotProcessorTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonMixinModuleEntriesBeanRegistrationAotProcessorTests.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonMixinModuleEntriesBeanRegistrationAotProcessorTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonMixinModuleTests.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonMixinModuleTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonMixinModuleTests.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonMixinModuleTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonObjectDeserializerTests.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonObjectDeserializerTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonObjectDeserializerTests.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonObjectDeserializerTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonObjectSerializerTests.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonObjectSerializerTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/JsonObjectSerializerTests.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/JsonObjectSerializerTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/NameAndAgeJsonComponent.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/NameAndAgeJsonComponent.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/NameAndAgeJsonComponent.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/NameAndAgeJsonComponent.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/NameAndAgeJsonKeyComponent.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/NameAndAgeJsonKeyComponent.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/NameAndAgeJsonKeyComponent.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/NameAndAgeJsonKeyComponent.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/NameAndCareerJsonComponent.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/NameAndCareerJsonComponent.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/NameAndCareerJsonComponent.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/NameAndCareerJsonComponent.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java index 90f70768a285..d3faca5ab207 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jackson; +package org.springframework.boot.jackson.autoconfigure; import java.io.IOException; import java.text.DateFormat; @@ -59,13 +59,12 @@ import org.springframework.beans.factory.BeanCurrentlyInCreationException; import org.springframework.boot.autoconfigure.AutoConfigurationPackage; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration.JacksonAutoConfigurationRuntimeHints; import org.springframework.boot.jackson.JsonComponent; import org.springframework.boot.jackson.JsonMixin; import org.springframework.boot.jackson.JsonMixinModule; import org.springframework.boot.jackson.JsonMixinModuleEntries; import org.springframework.boot.jackson.JsonObjectSerializer; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration.JacksonAutoConfigurationRuntimeHints; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -100,12 +99,10 @@ class JacksonAutoConfigurationTests { @Test void doubleModuleRegistration() { - this.contextRunner.withUserConfiguration(DoubleModulesConfig.class) - .withConfiguration(AutoConfigurations.of(HttpMessageConvertersAutoConfiguration.class)) - .run((context) -> { - ObjectMapper mapper = context.getBean(ObjectMapper.class); - assertThat(mapper.writeValueAsString(new Foo())).isEqualTo("{\"foo\":\"bar\"}"); - }); + this.contextRunner.withUserConfiguration(DoubleModulesConfig.class).run((context) -> { + ObjectMapper mapper = context.getBean(ObjectMapper.class); + assertThat(mapper.writeValueAsString(new Foo())).isEqualTo("{\"foo\":\"bar\"}"); + }); } @Test @@ -138,8 +135,7 @@ void customDateFormat() { @Test void customDateFormatClass() { - this.contextRunner.withPropertyValues( - "spring.jackson.date-format:org.springframework.boot.autoconfigure.jackson.JacksonAutoConfigurationTests.MyDateFormat") + this.contextRunner.withPropertyValues("spring.jackson.date-format:" + MyDateFormat.class.getName()) .run((context) -> { ObjectMapper mapper = context.getBean(ObjectMapper.class); assertThat(mapper.getDateFormat()).isInstanceOf(MyDateFormat.class); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/a/RenameMixInClass.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/a/RenameMixInClass.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/a/RenameMixInClass.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/a/RenameMixInClass.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/b/RenameMixInAbstractClass.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/b/RenameMixInAbstractClass.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/b/RenameMixInAbstractClass.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/b/RenameMixInAbstractClass.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/c/RenameMixInInterface.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/c/RenameMixInInterface.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/c/RenameMixInInterface.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/c/RenameMixInInterface.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/d/EmptyMixInClass.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/d/EmptyMixInClass.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/d/EmptyMixInClass.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/d/EmptyMixInClass.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/e/PrivateMixInClass.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/e/PrivateMixInClass.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/e/PrivateMixInClass.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/e/PrivateMixInClass.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/f/EmptyMixIn.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/f/EmptyMixIn.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/scan/f/EmptyMixIn.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/scan/f/EmptyMixIn.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/types/Name.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/types/Name.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/types/Name.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/types/Name.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/types/NameAndAge.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/types/NameAndAge.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/types/NameAndAge.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/types/NameAndAge.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/types/NameAndCareer.java b/spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/types/NameAndCareer.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jackson/types/NameAndCareer.java rename to spring-boot-project/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/types/NameAndCareer.java diff --git a/spring-boot-project/spring-boot-jdbc/build.gradle b/spring-boot-project/spring-boot-jdbc/build.gradle new file mode 100644 index 000000000000..37f4b1ceb3e0 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/build.gradle @@ -0,0 +1,105 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot JDBC" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-sql")) + api("org.springframework:spring-jdbc") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + implementation(project(":spring-boot-project:spring-boot-tx")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("com.h2database:h2") + optional("com.mchange:c3p0") + optional("com.oracle.database.jdbc:ojdbc11") + optional("com.oracle.database.jdbc:ucp11") + optional("com.zaxxer:HikariCP") + optional("io.micrometer:micrometer-core") + optional("org.apache.commons:commons-dbcp2") { + exclude group: "commons-logging", module: "commons-logging" + } + optional("org.apache.tomcat:tomcat-jdbc") + optional("org.postgresql:postgresql") + optional("org.testcontainers:jdbc") + optional("org.vibur:vibur-dbcp") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:postgresql") + + dockerTestRuntimeOnly("com.clickhouse:clickhouse-jdbc") + dockerTestRuntimeOnly("com.microsoft.sqlserver:mssql-jdbc") + dockerTestRuntimeOnly("org.lz4:lz4-java:1.8.0") + dockerTestRuntimeOnly("org.postgresql:postgresql") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-sql"))) + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("com.ibm.db2:jcc") + testImplementation("com.microsoft.sqlserver:mssql-jdbc") + testImplementation("io.r2dbc:r2dbc-spi") + testImplementation("org.hsqldb:hsqldb") + testImplementation("org.mariadb.jdbc:mariadb-java-client") { + exclude group: "org.slf4j", module: "jcl-over-slf4j" + } + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.clickhouse:clickhouse-jdbc") + testRuntimeOnly("com.mysql:mysql-connector-j") + testRuntimeOnly("net.sourceforge.jtds:jtds") + testRuntimeOnly("org.apache.derby:derby") + testRuntimeOnly("org.apache.derby:derbytools") + testRuntimeOnly("org.firebirdsql.jdbc:jaybird") { + exclude group: "javax.resource", module: "connector-api" + } + testRuntimeOnly("org.testcontainers:jdbc") { + exclude group: "javax.annotation", module: "javax.annotation-api" + exclude group: "javax.xml.bind", module: "jaxb-api" + } + testRuntimeOnly("org.xerial:sqlite-jdbc") + testRuntimeOnly("software.amazon.jdbc:aws-advanced-jdbc-wrapper") +} + +tasks.named("checkSpringConfigurationMetadata").configure { + exclusions = [ + "spring.datasource.dbcp2.*", + "spring.datasource.hikari.*", + "spring.datasource.oracleucp.*", + "spring.datasource.tomcat.*", + ] +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/ClickHouseJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/ClickHouseJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index e4342ec488d1..849bb73cceed 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/ClickHouseJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.clickhouse; +package org.springframework.boot.jdbc.docker.compose; import java.sql.Driver; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 5e4c9818d49e..d71275da04ba 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mariadb; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 93cbf9f1ac66..e8a1e916edd6 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mysql; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 6a981a96641f..0c9f3d10ea63 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.jdbc.docker.compose; import java.sql.Driver; import java.time.Duration; import org.awaitility.Awaitility; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index cfee46692254..9872e787e331 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.jdbc.docker.compose; import java.sql.Driver; import java.time.Duration; @@ -22,9 +22,9 @@ import org.awaitility.Awaitility; import org.junit.jupiter.api.condition.OS; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 96% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index ea2e7feadda1..83f393699c99 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.postgres; +package org.springframework.boot.jdbc.docker.compose; import java.sql.Driver; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index b618f9f14dd8..bea6f1b43ada 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.sqlserver; +package org.springframework.boot.jdbc.docker.compose; import java.sql.Driver; import org.junit.jupiter.api.condition.OS; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/jdbc/JdbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/testcontainers/JdbcContainerConnectionDetailsFactoryTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/jdbc/JdbcContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/testcontainers/JdbcContainerConnectionDetailsFactoryTests.java index f2d84bec8102..f0fb0444b02e 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/jdbc/JdbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/testcontainers/JdbcContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.jdbc; +package org.springframework.boot.jdbc.testcontainers; import javax.sql.DataSource; @@ -25,9 +25,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/clickhouse/clickhouse-bitnami-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/clickhouse-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/clickhouse/clickhouse-bitnami-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/clickhouse-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/clickhouse/clickhouse-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/clickhouse-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/clickhouse/clickhouse-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/clickhouse-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mariadb/mariadb-bitnami-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mariadb-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mariadb/mariadb-bitnami-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mariadb-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mariadb/mariadb-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mariadb-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mariadb/mariadb-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mariadb-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/sqlserver/mssqlserver-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mssqlserver-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/sqlserver/mssqlserver-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mssqlserver-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/sqlserver/mssqlserver-with-jdbc-parameters-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mssqlserver-with-jdbc-parameters-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/sqlserver/mssqlserver-with-jdbc-parameters-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mssqlserver-with-jdbc-parameters-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mysql/mysql-bitnami-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mysql-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mysql/mysql-bitnami-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mysql-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mysql/mysql-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mysql-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mysql/mysql-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mysql-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/oracle/oracle-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/oracle-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/oracle/oracle-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/oracle-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/otlp/otlp-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/otlp-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/otlp/otlp-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/otlp-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-application-name-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/postgres-application-name-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-application-name-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/postgres-application-name-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-bitnami-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/postgres-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-bitnami-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/postgres-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/postgres-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/postgres-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-with-trust-host-auth-method-compose.yaml b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/postgres-with-trust-host-auth-method-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-with-trust-host-auth-method-compose.yaml rename to spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/postgres-with-trust-host-auth-method-compose.yaml diff --git a/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java index bcf1d6980369..1006963dec21 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java @@ -232,7 +232,6 @@ public static DataSourceBuilder create(ClassLoader classLoader) { * set. * @param dataSource the source {@link DataSource} * @return a new {@link DataSource} builder - * @since 2.5.0 */ public static DataSourceBuilder derivedFrom(DataSource dataSource) { return new DataSourceBuilder<>(unwrap(dataSource)); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHints.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHints.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHints.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHints.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnection.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnection.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnection.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnection.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycle.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycle.java similarity index 90% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycle.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycle.java index af12b9eeee6c..1fcdac1a18fc 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycle.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycle.java @@ -75,20 +75,6 @@ public class HikariCheckpointRestoreLifecycle implements Lifecycle { private final ConfigurableApplicationContext applicationContext; - /** - * Creates a new {@code HikariCheckpointRestoreLifecycle} that will allow the given - * {@code dataSource} to participate in checkpoint-restore. The {@code dataSource} is - * {@link DataSourceUnwrapper#unwrap unwrapped} to a {@link HikariDataSource}. If such - * unwrapping is not possible, the lifecycle will have no effect. - * @param dataSource the checkpoint-restore participant - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #HikariCheckpointRestoreLifecycle(DataSource, ConfigurableApplicationContext)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public HikariCheckpointRestoreLifecycle(DataSource dataSource) { - this(dataSource, null); - } - /** * Creates a new {@code HikariCheckpointRestoreLifecycle} that will allow the given * {@code dataSource} to participate in checkpoint-restore. The {@code dataSource} is diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/SchemaManagement.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/SchemaManagement.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/SchemaManagement.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/SchemaManagement.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/SchemaManagementProvider.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/SchemaManagementProvider.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/SchemaManagementProvider.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/SchemaManagementProvider.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/SpringJdbcDependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/SpringJdbcDependsOnDatabaseInitializationDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/SpringJdbcDependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/SpringJdbcDependsOnDatabaseInitializationDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/UnsupportedDataSourcePropertyException.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/UnsupportedDataSourcePropertyException.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/UnsupportedDataSourcePropertyException.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/UnsupportedDataSourcePropertyException.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/XADataSourceWrapper.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/XADataSourceWrapper.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/XADataSourceWrapper.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/XADataSourceWrapper.java diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/ApplicationDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/ApplicationDataSourceScriptDatabaseInitializer.java new file mode 100644 index 000000000000..d597a156a3fc --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/ApplicationDataSourceScriptDatabaseInitializer.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.autoconfigure; + +import javax.sql.DataSource; + +import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.sql.autoconfigure.init.ApplicationScriptDatabaseInitializer; +import org.springframework.boot.sql.autoconfigure.init.SqlInitializationProperties; +import org.springframework.boot.sql.init.DatabaseInitializationSettings; + +/** + * {@link DataSourceScriptDatabaseInitializer} for the primary SQL database. May be + * registered as a bean to override auto-configuration. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 4.0.0 + */ +public class ApplicationDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer + implements ApplicationScriptDatabaseInitializer { + + /** + * Create a new {@link ApplicationDataSourceScriptDatabaseInitializer} instance. + * @param dataSource the primary SQL data source + * @param properties the SQL initialization properties + */ + public ApplicationDataSourceScriptDatabaseInitializer(DataSource dataSource, + SqlInitializationProperties properties) { + this(dataSource, ApplicationScriptDatabaseInitializer.getSettings(properties)); + } + + /** + * Create a new {@link ApplicationDataSourceScriptDatabaseInitializer} instance. + * @param dataSource the primary SQL data source + * @param settings the database initialization settings + */ + public ApplicationDataSourceScriptDatabaseInitializer(DataSource dataSource, + DatabaseInitializationSettings settings) { + super(dataSource, settings); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfiguration.java index afb8b33b88ee..8399cfe77249 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; import javax.sql.XADataSource; @@ -29,8 +29,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; @@ -54,9 +52,9 @@ * @author Stephane Nicoll * @author Kazuki Shimizu * @author Olga Maciaszek-Sharma - * @since 1.0.0 + * @since 4.0.0 */ -@AutoConfiguration(before = SqlInitializationAutoConfiguration.class) +@AutoConfiguration(before = DataSourceInitializationAutoConfiguration.class) @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) @ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory") @EnableConfigurationProperties(DataSourceProperties.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBeanCreationFailureAnalyzer.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceBeanCreationFailureAnalyzer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBeanCreationFailureAnalyzer.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceBeanCreationFailureAnalyzer.java index 42b0c08c39e6..653a28e2ed41 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBeanCreationFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceBeanCreationFailureAnalyzer.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.DataSourceBeanCreationException; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties.DataSourceBeanCreationException; import org.springframework.core.env.Environment; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceCheckpointRestoreConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceCheckpointRestoreConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceCheckpointRestoreConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceCheckpointRestoreConfiguration.java index c87941d15218..cdb5c25edab0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceCheckpointRestoreConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceCheckpointRestoreConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceConfiguration.java index 65f7c8d69f9f..cd2784bf3a46 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.sql.SQLException; diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceInitializationAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceInitializationAutoConfiguration.java new file mode 100644 index 000000000000..92a1193af0d0 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceInitializationAutoConfiguration.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.autoconfigure; + +import javax.sql.DataSource; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.sql.autoconfigure.init.ApplicationScriptDatabaseInitializer; +import org.springframework.boot.sql.autoconfigure.init.ConditionalOnSqlInitialization; +import org.springframework.boot.sql.autoconfigure.init.SqlInitializationProperties; +import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.jdbc.datasource.SimpleDriverDataSource; +import org.springframework.jdbc.datasource.init.DatabasePopulator; +import org.springframework.util.StringUtils; + +/** + * Auto-configuration for {@link DataSource} initialization. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnMissingBean(ApplicationScriptDatabaseInitializer.class) +@ConditionalOnSingleCandidate(DataSource.class) +@ConditionalOnClass(DatabasePopulator.class) +@Import(DatabaseInitializationDependencyConfigurer.class) +@EnableConfigurationProperties(SqlInitializationProperties.class) +@ConditionalOnSqlInitialization +public class DataSourceInitializationAutoConfiguration { + + @Bean + ApplicationDataSourceScriptDatabaseInitializer dataSourceScriptDatabaseInitializer(DataSource dataSource, + SqlInitializationProperties properties) { + return new ApplicationDataSourceScriptDatabaseInitializer( + determineDataSource(dataSource, properties.getUsername(), properties.getPassword()), properties); + } + + private static DataSource determineDataSource(DataSource dataSource, String username, String password) { + if (StringUtils.hasText(username) && StringUtils.hasText(password)) { + return DataSourceBuilder.derivedFrom(dataSource) + .username(username) + .password(password) + .type(SimpleDriverDataSource.class) + .build(); + } + return dataSource; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJmxConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJmxConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJmxConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJmxConfiguration.java index 561b5109b742..53472a0e9e91 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJmxConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJmxConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.sql.SQLException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/metadata/DataSourcePoolMetadataProvidersConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourcePoolMetadataProvidersConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/metadata/DataSourcePoolMetadataProvidersConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourcePoolMetadataProvidersConfiguration.java index 063c2ac6c9e8..91626848fce9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/metadata/DataSourcePoolMetadataProvidersConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourcePoolMetadataProvidersConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc.metadata; +package org.springframework.boot.jdbc.autoconfigure; import com.zaxxer.hikari.HikariConfigMXBean; import com.zaxxer.hikari.HikariDataSource; @@ -40,7 +40,7 @@ * * @author Stephane Nicoll * @author Fabio Grassi - * @since 1.2.0 + * @since 4.0.0 */ @Configuration(proxyBeanMethods = false) public class DataSourcePoolMetadataProvidersConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceProperties.java index 8d02cefa2e8d..be60068586a8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.util.LinkedHashMap; import java.util.Map; @@ -42,7 +42,7 @@ * @author Benedikt Ritter * @author Eddú Meléndez * @author Scott Frederick - * @since 1.1.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.datasource") public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean { @@ -168,7 +168,6 @@ public void setDriverClassName(String driverClassName) { /** * Determine the driver to use based on this configuration and the environment. * @return the driver to use - * @since 1.4.0 */ public String determineDriverClassName() { String driverClassName = findDriverClassName(); @@ -224,7 +223,6 @@ public void setUrl(String url) { /** * Determine the url to use based on this configuration and the environment. * @return the url to use - * @since 1.4.0 */ public String determineUrl() { if (StringUtils.hasText(this.url)) { @@ -242,7 +240,6 @@ public String determineUrl() { /** * Determine the name to used based on this configuration. * @return the database name to use or {@code null} - * @since 2.0.0 */ public String determineDatabaseName() { if (this.generateUniqueName) { @@ -276,7 +273,6 @@ public void setUsername(String username) { /** * Determine the username to use based on this configuration and the environment. * @return the username to use - * @since 1.4.0 */ public String determineUsername() { if (StringUtils.hasText(this.username)) { @@ -304,7 +300,6 @@ public void setPassword(String password) { /** * Determine the password to use based on this configuration and the environment. * @return the password to use - * @since 1.4.0 */ public String determinePassword() { if (StringUtils.hasText(this.password)) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceTransactionManagerAutoConfiguration.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceTransactionManagerAutoConfiguration.java index cc0715cbc415..3cf85838f44b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/DataSourceTransactionManagerAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; @@ -25,9 +25,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizers; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -44,7 +44,7 @@ * @author Stephane Nicoll * @author Andy Wilkinson * @author Kazuki Shimizu - * @since 1.0.0 + * @since 4.0.0 */ @AutoConfiguration(before = TransactionAutoConfiguration.class, after = { DataSourceAutoConfiguration.class, TransactionManagerCustomizationAutoConfiguration.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/Dbcp2JdbcConnectionDetailsBeanPostProcessor.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/Dbcp2JdbcConnectionDetailsBeanPostProcessor.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/Dbcp2JdbcConnectionDetailsBeanPostProcessor.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/Dbcp2JdbcConnectionDetailsBeanPostProcessor.java index 426f39bff585..aa8a936557d7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/Dbcp2JdbcConnectionDetailsBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/Dbcp2JdbcConnectionDetailsBeanPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.apache.commons.dbcp2.BasicDataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/EmbeddedDataSourceConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/EmbeddedDataSourceConfiguration.java index dc6f3f0b5f66..312dda3abef3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/EmbeddedDataSourceConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -29,7 +29,7 @@ * * @author Phillip Webb * @author Stephane Nicoll - * @since 1.0.0 + * @since 4.0.0 * @see DataSourceAutoConfiguration */ @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzer.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/HikariDriverConfigurationFailureAnalyzer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzer.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/HikariDriverConfigurationFailureAnalyzer.java index a5c189164579..b8f888517ca0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/HikariDriverConfigurationFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariJdbcConnectionDetailsBeanPostProcessor.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/HikariJdbcConnectionDetailsBeanPostProcessor.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariJdbcConnectionDetailsBeanPostProcessor.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/HikariJdbcConnectionDetailsBeanPostProcessor.java index 615531b499a1..e3fef4b1ee13 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariJdbcConnectionDetailsBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/HikariJdbcConnectionDetailsBeanPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import com.zaxxer.hikari.HikariDataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcClientAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcClientAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcClientAutoConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcClientAutoConfiguration.java index e000cdee1d80..2cde99663008 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcClientAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -30,7 +30,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link JdbcClient}. * * @author Stephane Nicoll - * @since 3.2.0 + * @since 4.0.0 */ @AutoConfiguration(after = JdbcTemplateAutoConfiguration.class) @ConditionalOnSingleCandidate(NamedParameterJdbcTemplate.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcConnectionDetails.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcConnectionDetails.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetails.java index 238d439d2081..7961d11a2ce4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcConnectionDetails.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; import org.springframework.boot.jdbc.DatabaseDriver; @@ -25,7 +25,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface JdbcConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcConnectionDetailsBeanPostProcessor.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetailsBeanPostProcessor.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcConnectionDetailsBeanPostProcessor.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetailsBeanPostProcessor.java index 8c7031b51ba2..23d1f7378246 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcConnectionDetailsBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcConnectionDetailsBeanPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectProvider; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcProperties.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcProperties.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcProperties.java index f3a5023f6f50..ff5c5fe6be78 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcProperties.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -27,7 +27,7 @@ * * @author Kazuki Shimizu * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.jdbc") public class JdbcProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateAutoConfiguration.java index 02320273a872..73de0d2411aa 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; @@ -36,7 +36,7 @@ * @author Phillip Webb * @author Stephane Nicoll * @author Kazuki Shimizu - * @since 1.4.0 + * @since 4.0.0 */ @AutoConfiguration(after = DataSourceAutoConfiguration.class) @ConditionalOnClass({ DataSource.class, JdbcTemplate.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateConfiguration.java index db38aa6743e9..a8ff4d555a6f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JndiDataSourceAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JndiDataSourceAutoConfiguration.java index 593d67e225e0..5605986efe96 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/JndiDataSourceAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; @@ -37,7 +37,7 @@ * * @author Phillip Webb * @author Andy Wilkinson - * @since 1.2.0 + * @since 4.0.0 */ @AutoConfiguration(before = { XADataSourceAutoConfiguration.class, DataSourceAutoConfiguration.class }) @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/NamedParameterJdbcTemplateConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/NamedParameterJdbcTemplateConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/NamedParameterJdbcTemplateConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/NamedParameterJdbcTemplateConfiguration.java index 8c7becddd4a3..8e113562090a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/NamedParameterJdbcTemplateConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/NamedParameterJdbcTemplateConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpJdbcConnectionDetailsBeanPostProcessor.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpJdbcConnectionDetailsBeanPostProcessor.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpJdbcConnectionDetailsBeanPostProcessor.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpJdbcConnectionDetailsBeanPostProcessor.java index a7e46134e97c..8d7c8238d790 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpJdbcConnectionDetailsBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpJdbcConnectionDetailsBeanPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.sql.SQLException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/PropertiesJdbcConnectionDetails.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/PropertiesJdbcConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/PropertiesJdbcConnectionDetails.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/PropertiesJdbcConnectionDetails.java index 893c0d0ae91b..6558e5e3c873 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/PropertiesJdbcConnectionDetails.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/PropertiesJdbcConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; /** * Adapts {@link DataSourceProperties} to {@link JdbcConnectionDetails}. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatJdbcConnectionDetailsBeanPostProcessor.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/TomcatJdbcConnectionDetailsBeanPostProcessor.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatJdbcConnectionDetailsBeanPostProcessor.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/TomcatJdbcConnectionDetailsBeanPostProcessor.java index 1a2931ebf800..21a25d2e236a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatJdbcConnectionDetailsBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/TomcatJdbcConnectionDetailsBeanPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.apache.tomcat.jdbc.pool.DataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/XADataSourceAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/XADataSourceAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/XADataSourceAutoConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/XADataSourceAutoConfiguration.java index e270ab75850e..2b230275bab8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/XADataSourceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/XADataSourceAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.util.HashMap; import java.util.Map; @@ -32,7 +32,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.DataSourceBeanCreationException; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; @@ -41,6 +40,8 @@ import org.springframework.boot.context.properties.source.ConfigurationPropertySource; import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; import org.springframework.boot.jdbc.XADataSourceWrapper; +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties.DataSourceBeanCreationException; +import org.springframework.boot.transaction.jta.autoconfigure.JtaAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.util.Assert; @@ -55,9 +56,9 @@ * @author Madhura Bhave * @author Moritz Halbritter * @author Andy Wilkinson - * @since 1.2.0 + * @since 4.0.0 */ -@AutoConfiguration(before = DataSourceAutoConfiguration.class) +@AutoConfiguration(before = DataSourceAutoConfiguration.class, after = JtaAutoConfiguration.class) @EnableConfigurationProperties(DataSourceProperties.class) @ConditionalOnClass({ DataSource.class, TransactionManager.class, EmbeddedDatabaseType.class }) @ConditionalOnBean(XADataSourceWrapper.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthContributorAutoConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthContributorAutoConfiguration.java index 661f02070c22..ae16dd7a1b12 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthContributorAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure.health; import java.sql.SQLException; import java.util.Collection; @@ -30,18 +30,18 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.NamedContributor; -import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthContributors; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.health.DataSourceHealthIndicator; import org.springframework.boot.jdbc.metadata.CompositeDataSourcePoolMetadataProvider; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadata; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; @@ -61,10 +61,10 @@ * @author Arthur Kalimullin * @author Julio Gomez * @author Safeer Ansari - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = DataSourceAutoConfiguration.class) -@ConditionalOnClass({ JdbcTemplate.class, AbstractRoutingDataSource.class }) +@ConditionalOnClass({ JdbcTemplate.class, AbstractRoutingDataSource.class, ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(DataSource.class) @ConditionalOnEnabledHealthIndicator("db") @EnableConfigurationProperties(DataSourceHealthIndicatorProperties.class) @@ -171,7 +171,7 @@ public HealthContributor getContributor(String name) { } @Override - public Iterator> iterator() { + public Iterator iterator() { return this.delegate.iterator(); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthIndicatorProperties.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthIndicatorProperties.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthIndicatorProperties.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthIndicatorProperties.java index f3cb9d3d47ae..2626bde5c690 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthIndicatorProperties.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthIndicatorProperties.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure.health; -import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.health.DataSourceHealthIndicator; /** * External configuration properties for {@link DataSourceHealthIndicator}. * * @author Julio Gomez - * @since 2.4.0 + * @since 4.0.0 */ @ConfigurationProperties("management.health.db") public class DataSourceHealthIndicatorProperties { diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..9f3415f3bfee --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JDBC health. + */ +package org.springframework.boot.jdbc.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/metrics/DataSourcePoolMetricsAutoConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/metrics/DataSourcePoolMetricsAutoConfiguration.java index c83743332739..18787c6f17d5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/metrics/DataSourcePoolMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.jdbc; +package org.springframework.boot.jdbc.autoconfigure.metrics; import java.util.Collection; import java.util.Collections; @@ -34,16 +34,14 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.metrics.jdbc.DataSourcePoolMetrics; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.DataSourceUnwrapper; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; +import org.springframework.boot.jdbc.metrics.DataSourcePoolMetrics; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.log.LogMessage; @@ -55,10 +53,10 @@ * * @author Stephane Nicoll * @author Yanming Zhou - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, DataSourceAutoConfiguration.class, - SimpleMetricsExportAutoConfiguration.class }) +@AutoConfiguration(after = DataSourceAutoConfiguration.class, + afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") @ConditionalOnClass({ DataSource.class, MeterRegistry.class }) @ConditionalOnBean({ DataSource.class, MeterRegistry.class }) public class DataSourcePoolMetricsAutoConfiguration { diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..cba531b9eb0a --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JDBC metrics. + */ +package org.springframework.boot.jdbc.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/package-info.java new file mode 100644 index 000000000000..18748f5632b1 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JDBC. + */ +package org.springframework.boot.jdbc.autoconfigure; diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/ClickHouseEnvironment.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/ClickHouseEnvironment.java new file mode 100644 index 000000000000..99e081bd86d1 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/ClickHouseEnvironment.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * ClickHouse environment details. + * + * @author Stephane Nicoll + */ +class ClickHouseEnvironment { + + private final String username; + + private final String password; + + private final String database; + + ClickHouseEnvironment(Map env) { + this.username = env.getOrDefault("CLICKHOUSE_USER", "default"); + this.password = extractPassword(env); + this.database = env.getOrDefault("CLICKHOUSE_DB", "default"); + } + + private String extractPassword(Map env) { + boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD"); + String password = env.get("CLICKHOUSE_PASSWORD"); + Assert.state(StringUtils.hasLength(password) || allowEmpty, "No ClickHouse password found"); + return (password != null) ? password : ""; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseJdbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/ClickHouseJdbcDockerComposeConnectionDetailsFactory.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseJdbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/ClickHouseJdbcDockerComposeConnectionDetailsFactory.java index bda3302cf257..f259801f5347 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseJdbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/ClickHouseJdbcDockerComposeConnectionDetailsFactory.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.clickhouse; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.jdbc.JdbcUrlBuilder; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link JdbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/jdbc/JdbcUrlBuilder.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/JdbcUrlBuilder.java similarity index 89% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/jdbc/JdbcUrlBuilder.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/JdbcUrlBuilder.java index e59f481f04f0..b168cde2c796 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/jdbc/JdbcUrlBuilder.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/JdbcUrlBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.jdbc; +package org.springframework.boot.jdbc.docker.compose; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.util.Assert; @@ -26,9 +26,8 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 */ -public class JdbcUrlBuilder { +class JdbcUrlBuilder { private static final String PARAMETERS_LABEL = "org.springframework.boot.jdbc.parameters"; @@ -41,7 +40,7 @@ public class JdbcUrlBuilder { * @param driverProtocol the driver protocol * @param containerPort the source container port */ - public JdbcUrlBuilder(String driverProtocol, int containerPort) { + JdbcUrlBuilder(String driverProtocol, int containerPort) { Assert.notNull(driverProtocol, "'driverProtocol' must not be null"); this.driverProtocol = driverProtocol; this.containerPort = containerPort; @@ -52,7 +51,7 @@ public JdbcUrlBuilder(String driverProtocol, int containerPort) { * @param service the running service * @return a new JDBC URL */ - public String build(RunningService service) { + String build(RunningService service) { return build(service, null); } @@ -62,7 +61,7 @@ public String build(RunningService service) { * @param database the database to connect to * @return a new JDBC URL */ - public String build(RunningService service, String database) { + String build(RunningService service, String database) { return urlFor(service, database); } @@ -87,7 +86,6 @@ private String urlFor(RunningService service, String database) { * The default implementation appends a {@code ?} followed by the {@code parameters}. * @param url the url * @param parameters the parameters - * @since 3.2.7 */ protected void appendParameters(StringBuilder url, String parameters) { url.append("?").append(parameters); diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironment.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironment.java new file mode 100644 index 000000000000..355e64d43d20 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironment.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * MariaDB environment details. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + */ +class MariaDbEnvironment { + + private final String username; + + private final String password; + + private final String database; + + MariaDbEnvironment(Map env) { + this.username = extractUsername(env); + this.password = extractPassword(env); + this.database = extractDatabase(env); + } + + private String extractUsername(Map env) { + String user = env.get("MARIADB_USER"); + return (user != null) ? user : env.getOrDefault("MYSQL_USER", "root"); + } + + private String extractPassword(Map env) { + Assert.state(!env.containsKey("MARIADB_RANDOM_ROOT_PASSWORD"), "MARIADB_RANDOM_ROOT_PASSWORD is not supported"); + Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported"); + Assert.state(!env.containsKey("MARIADB_ROOT_PASSWORD_HASH"), "MARIADB_ROOT_PASSWORD_HASH is not supported"); + boolean allowEmpty = env.containsKey("MARIADB_ALLOW_EMPTY_PASSWORD") + || env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD"); + String password = env.get("MARIADB_PASSWORD"); + password = (password != null) ? password : env.get("MYSQL_PASSWORD"); + password = (password != null) ? password : env.get("MARIADB_ROOT_PASSWORD"); + password = (password != null) ? password : env.get("MYSQL_ROOT_PASSWORD"); + Assert.state(StringUtils.hasLength(password) || allowEmpty, "No MariaDB password found"); + return (password != null) ? password : ""; + } + + private String extractDatabase(Map env) { + String database = env.get("MARIADB_DATABASE"); + database = (database != null) ? database : env.get("MYSQL_DATABASE"); + Assert.state(database != null, "No MARIADB_DATABASE defined"); + return database; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbJdbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactory.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbJdbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactory.java index 362ae7a638b5..50339b302d1d 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbJdbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactory.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mariadb; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.jdbc.JdbcUrlBuilder; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link JdbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MySqlEnvironment.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MySqlEnvironment.java new file mode 100644 index 000000000000..e2dc5f2d070e --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MySqlEnvironment.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * MySQL environment details. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + */ +class MySqlEnvironment { + + private final String username; + + private final String password; + + private final String database; + + MySqlEnvironment(Map env) { + this.username = env.getOrDefault("MYSQL_USER", "root"); + this.password = extractPassword(env); + this.database = extractDatabase(env); + } + + private String extractPassword(Map env) { + Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported"); + boolean allowEmpty = env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD"); + String password = env.get("MYSQL_PASSWORD"); + password = (password != null) ? password : env.get("MYSQL_ROOT_PASSWORD"); + Assert.state(StringUtils.hasLength(password) || allowEmpty, "No MySQL password found"); + return (password != null) ? password : ""; + } + + private String extractDatabase(Map env) { + String database = env.get("MYSQL_DATABASE"); + Assert.state(database != null, "No MYSQL_DATABASE defined"); + return database; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlJdbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MySqlJdbcDockerComposeConnectionDetailsFactory.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlJdbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MySqlJdbcDockerComposeConnectionDetailsFactory.java index f8f40676f9c2..80643e848227 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlJdbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MySqlJdbcDockerComposeConnectionDetailsFactory.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mysql; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.jdbc.JdbcUrlBuilder; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link JdbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleContainer.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleContainer.java new file mode 100644 index 000000000000..3199bdcac74c --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleContainer.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +/** + * Enumeration of supported Oracle containers. + * + * @author Andy Wilkinson + */ +enum OracleContainer { + + FREE("gvenzl/oracle-free", "freepdb1"), + + XE("gvenzl/oracle-xe", "xepdb1"); + + private final String imageName; + + private final String defaultDatabase; + + OracleContainer(String imageName, String defaultDatabase) { + this.imageName = imageName; + this.defaultDatabase = defaultDatabase; + } + + String getImageName() { + return this.imageName; + } + + String getDefaultDatabase() { + return this.defaultDatabase; + } + +} diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleEnvironment.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleEnvironment.java new file mode 100644 index 000000000000..0374a5ea16d6 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleEnvironment.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Oracle Database environment details. + * + * @author Andy Wilkinson + */ +class OracleEnvironment { + + private final String username; + + private final String password; + + private final String database; + + OracleEnvironment(Map env, String defaultDatabase) { + this.username = env.getOrDefault("APP_USER", "system"); + this.password = extractPassword(env); + this.database = env.getOrDefault("ORACLE_DATABASE", defaultDatabase); + } + + private String extractPassword(Map env) { + if (env.containsKey("APP_USER")) { + String password = env.get("APP_USER_PASSWORD"); + Assert.state(StringUtils.hasLength(password), "No Oracle app password found"); + return password; + } + Assert.state(!env.containsKey("ORACLE_RANDOM_PASSWORD"), + "ORACLE_RANDOM_PASSWORD is not supported without APP_USER and APP_USER_PASSWORD"); + String password = env.get("ORACLE_PASSWORD"); + Assert.state(StringUtils.hasLength(password), "No Oracle password found"); + return password; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeJdbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleFreeJdbcDockerComposeConnectionDetailsFactory.java similarity index 89% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeJdbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleFreeJdbcDockerComposeConnectionDetailsFactory.java index 93dd3df4ad43..9967f6e2db44 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeJdbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleFreeJdbcDockerComposeConnectionDetailsFactory.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link JdbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleJdbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleJdbcDockerComposeConnectionDetailsFactory.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleJdbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleJdbcDockerComposeConnectionDetailsFactory.java index 1799599ab4d6..00d58fe9d00b 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleJdbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleJdbcDockerComposeConnectionDetailsFactory.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.util.StringUtils; /** diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeJdbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleXeJdbcDockerComposeConnectionDetailsFactory.java similarity index 89% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeJdbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleXeJdbcDockerComposeConnectionDetailsFactory.java index b6faf5eff4ea..88061e7e9cd8 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeJdbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/OracleXeJdbcDockerComposeConnectionDetailsFactory.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link JdbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/PostgresEnvironment.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/PostgresEnvironment.java new file mode 100644 index 000000000000..d4cc1653a4ea --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/PostgresEnvironment.java @@ -0,0 +1,92 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Postgres environment details. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + * @author Sidmar Theodoro + * @author He Zean + */ +class PostgresEnvironment { + + private static final String[] USERNAME_KEYS = new String[] { "POSTGRES_USER", "POSTGRESQL_USER", + "POSTGRESQL_USERNAME" }; + + private static final String DEFAULT_USERNAME = "postgres"; + + private static final String[] DATABASE_KEYS = new String[] { "POSTGRES_DB", "POSTGRESQL_DB", + "POSTGRESQL_DATABASE" }; + + private final String username; + + private final String password; + + private final String database; + + PostgresEnvironment(Map env) { + this.username = extract(env, USERNAME_KEYS, DEFAULT_USERNAME); + this.password = extractPassword(env); + this.database = extract(env, DATABASE_KEYS, this.username); + } + + private String extract(Map env, String[] keys, String defaultValue) { + for (String key : keys) { + if (env.containsKey(key)) { + return env.get(key); + } + } + return defaultValue; + } + + private String extractPassword(Map env) { + if (isUsingTrustHostAuthMethod(env)) { + return null; + } + String password = env.getOrDefault("POSTGRES_PASSWORD", env.get("POSTGRESQL_PASSWORD")); + boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD"); + Assert.state(allowEmpty || StringUtils.hasLength(password), "No PostgreSQL password found"); + return (password != null) ? password : ""; + } + + private boolean isUsingTrustHostAuthMethod(Map env) { + String hostAuthMethod = env.get("POSTGRES_HOST_AUTH_METHOD"); + return "trust".equals(hostAuthMethod); + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactory.java index 820628b56e3b..58e25da83df7 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactory.java @@ -14,16 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.postgres; +package org.springframework.boot.jdbc.docker.compose; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.jdbc.JdbcUrlBuilder; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/SqlServerEnvironment.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/SqlServerEnvironment.java new file mode 100644 index 000000000000..44d605bfab99 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/SqlServerEnvironment.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * MS SQL Server environment details. + * + * @author Andy Wilkinson + */ +class SqlServerEnvironment { + + private final String username = "SA"; + + private final String password; + + SqlServerEnvironment(Map env) { + this.password = extractPassword(env); + } + + private String extractPassword(Map env) { + String password = env.get("MSSQL_SA_PASSWORD"); + password = (password != null) ? password : env.get("SA_PASSWORD"); + Assert.state(StringUtils.hasLength(password), "No MSSQL password found"); + return password; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerJdbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/SqlServerJdbcDockerComposeConnectionDetailsFactory.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerJdbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/SqlServerJdbcDockerComposeConnectionDetailsFactory.java index 1c083ed6109d..e2f97e1bafdf 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerJdbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/SqlServerJdbcDockerComposeConnectionDetailsFactory.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.sqlserver; +package org.springframework.boot.jdbc.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.jdbc.JdbcUrlBuilder; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link JdbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/package-info.java new file mode 100644 index 000000000000..1cb18cad141e --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose JDBC service connections. + */ +package org.springframework.boot.jdbc.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicator.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/health/DataSourceHealthIndicator.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicator.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/health/DataSourceHealthIndicator.java index 56cad6861802..855f7a3d93cd 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicator.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/health/DataSourceHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.jdbc; +package org.springframework.boot.jdbc.health; import java.sql.Connection; import java.sql.ResultSet; @@ -25,10 +25,10 @@ import javax.sql.DataSource; import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.dao.support.DataAccessUtils; import org.springframework.jdbc.IncorrectResultSetColumnCountException; import org.springframework.jdbc.core.ConnectionCallback; @@ -47,7 +47,7 @@ * @author Andy Wilkinson * @author Stephane Nicoll * @author Arthur Kalimullin - * @since 2.0.0 + * @since 4.0.0 */ public class DataSourceHealthIndicator extends AbstractHealthIndicator implements InitializingBean { diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/health/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/health/package-info.java new file mode 100644 index 000000000000..8b08ab049fa5 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for JDBC. + */ +package org.springframework.boot.jdbc.health; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializer.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerDetector.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerDetector.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolver.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolver.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolver.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolver.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/init/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/init/package-info.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/init/package-info.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadata.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadata.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadata.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadata.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CompositeDataSourcePoolMetadataProvider.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/CompositeDataSourcePoolMetadataProvider.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CompositeDataSourcePoolMetadataProvider.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/CompositeDataSourcePoolMetadataProvider.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadataProvider.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadataProvider.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadataProvider.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadataProvider.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/OracleUcpDataSourcePoolMetadata.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/OracleUcpDataSourcePoolMetadata.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/OracleUcpDataSourcePoolMetadata.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/OracleUcpDataSourcePoolMetadata.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/package-info.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metadata/package-info.java diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jdbc/DataSourcePoolMetrics.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metrics/DataSourcePoolMetrics.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jdbc/DataSourcePoolMetrics.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metrics/DataSourcePoolMetrics.java index 44cb1ae1218c..a496a8699dc4 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jdbc/DataSourcePoolMetrics.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metrics/DataSourcePoolMetrics.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.jdbc; +package org.springframework.boot.jdbc.metrics; import java.util.Collection; import java.util.Map; @@ -39,7 +39,7 @@ * * @author Jon Schneider * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ public class DataSourcePoolMetrics implements MeterBinder { diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metrics/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metrics/package-info.java new file mode 100644 index 000000000000..6f9f61e739e4 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Metrics for JDBC. + */ +package org.springframework.boot.jdbc.metrics; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/package-info.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/package-info.java diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/jdbc/JdbcContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/testcontainers/JdbcContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/jdbc/JdbcContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/testcontainers/JdbcContainerConnectionDetailsFactory.java index a80fc0256e50..c984999462d4 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/jdbc/JdbcContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/testcontainers/JdbcContainerConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.jdbc; +package org.springframework.boot.jdbc.testcontainers; import org.testcontainers.containers.JdbcDatabaseContainer; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/testcontainers/package-info.java b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/testcontainers/package-info.java new file mode 100644 index 000000000000..03956e55e9f4 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers JDBC service connections. + */ +package org.springframework.boot.jdbc.testcontainers; diff --git a/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..0a619e8601ba --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,190 @@ +{ + "properties": [ + { + "name": "management.health.db.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable database health check.", + "defaultValue": true + }, + { + "name": "spring.datasource.continue-on-error", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.continue-on-error" + } + }, + { + "name": "spring.datasource.data", + "type": "java.util.List", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.data-locations" + } + }, + { + "name": "spring.datasource.data-password", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.password" + } + }, + { + "name": "spring.datasource.data-username", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.username" + } + }, + { + "name": "spring.datasource.initialization-mode", + "type": "org.springframework.boot.jdbc.DataSourceInitializationMode", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.mode" + } + }, + { + "name": "spring.datasource.jmx-enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable JMX support (if provided by the underlying pool).", + "defaultValue": false, + "deprecation": { + "level": "error", + "replacement": "spring.datasource.tomcat.jmx-enabled" + } + }, + { + "name": "spring.datasource.platform", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.platform" + } + }, + { + "name": "spring.datasource.schema", + "type": "java.util.List", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.schema-locations" + } + }, + { + "name": "spring.datasource.schema-password", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.password" + } + }, + { + "name": "spring.datasource.schema-username", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.username" + } + }, + { + "name": "spring.datasource.separator", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.separator" + } + }, + { + "name": "spring.datasource.sql-script-encoding", + "type": "java.nio.charset.Charset", + "deprecation": { + "level": "error", + "replacement": "spring.sql.init.encoding" + } + } + ], + "hints": [ + { + "name": "spring.datasource.data", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "java.util.List" + } + } + ] + }, + { + "name": "spring.datasource.driver-class-name", + "providers": [ + { + "name": "class-reference", + "parameters": { + "target": "java.sql.Driver" + } + } + ] + }, + { + "name": "spring.datasource.schema", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "java.util.List" + } + } + ] + }, + { + "name": "spring.datasource.xa.data-source-class-name", + "providers": [ + { + "name": "class-reference", + "parameters": { + "target": "javax.sql.XADataSource" + } + } + ] + }, + { + "name": "spring.datasource.xa.data-source-class-name", + "providers": [ + { + "name": "class-reference", + "parameters": { + "target": "javax.sql.XADataSource" + } + } + ] + } + ], + "ignored": { + "properties": [ + { + "name": "spring.datasource.dbcp2.driver" + }, + { + "name": "spring.datasource.hikari.credentials" + }, + { + "name": "spring.datasource.hikari.exception-override" + }, + { + "name": "spring.datasource.hikari.metrics-tracker-factory" + }, + { + "name": "spring.datasource.hikari.scheduled-executor" + }, + { + "name": "spring.datasource.oracleucp.connection-wait-duration-in-millis" + }, + { + "name": "spring.datasource.oracleucp.hostname-resolver" + } + ] + } +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..6e60a1e18d5c --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring.factories @@ -0,0 +1,23 @@ +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.boot.jdbc.autoconfigure.DataSourceBeanCreationFailureAnalyzer,\ +org.springframework.boot.jdbc.autoconfigure.HikariDriverConfigurationFailureAnalyzer + +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.jdbc.docker.compose.ClickHouseJdbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.jdbc.docker.compose.MariaDbJdbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.jdbc.docker.compose.MySqlJdbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.jdbc.docker.compose.OracleFreeJdbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.jdbc.docker.compose.OracleXeJdbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.jdbc.docker.compose.PostgresJdbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.jdbc.docker.compose.SqlServerJdbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.jdbc.testcontainers.JdbcContainerConnectionDetailsFactory + +# Database Initializer Detectors +org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\ +org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializerDetector + +# Depends On Database Initialization Detectors +org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ +org.springframework.boot.jdbc.SpringJdbcDependsOnDatabaseInitializationDetector diff --git a/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..5065a4782e20 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.jdbc.DataSourceBuilderRuntimeHints diff --git a/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..e34e2446d03f --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,9 @@ +org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JdbcClientAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JndiDataSourceAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.XADataSourceAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.health.DataSourceHealthContributorAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.metrics.DataSourcePoolMetricsAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderNoHikariTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderNoHikariTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderNoHikariTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderNoHikariTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHintsTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHintsTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHintsTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderRuntimeHintsTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperNoSpringJdbcTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperNoSpringJdbcTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperNoSpringJdbcTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperNoSpringJdbcTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DatabaseDriverClassNameTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DatabaseDriverClassNameTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DatabaseDriverClassNameTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DatabaseDriverClassNameTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DatabaseDriverTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DatabaseDriverTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DatabaseDriverTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/DatabaseDriverTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnectionTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnectionTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnectionTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/EmbeddedDatabaseConnectionTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycleTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycleTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycleTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/HikariCheckpointRestoreLifecycleTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfigurationTests.java index a7579c3227d9..7d7287f41381 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.net.URL; import java.net.URLClassLoader; @@ -41,9 +41,11 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener; import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.logging.LogLevel; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -238,6 +240,7 @@ void whenThereIsAUserProvidedDataSourceAnUnresolvablePlaceholderDoesNotCauseAPro @Test void whenThereIsAnEmptyUserProvidedDataSource() { this.contextRunner.with(hideConnectionPools()) + .withInitializer(ConditionEvaluationReportLoggingListener.forLogLevel(LogLevel.INFO)) .withPropertyValues("spring.datasource.url:") .run((context) -> assertThat(context).getBean(DataSource.class).isInstanceOf(EmbeddedDatabase.class)); } @@ -297,7 +300,7 @@ void genericUsesCustomJdbcConnectionDetailsWhenAvailable() { private static Function hideConnectionPools() { return (runner) -> runner.withClassLoader(new FilteredClassLoader("org.apache.tomcat", "com.zaxxer.hikari", - "org.apache.commons.dbcp2", "oracle.ucp.jdbc", "com.mchange")); + "org.apache.commons.dbcp2", "oracle.ucp.jdbc", "org.vibur.dbcp", "com.mchange")); } private void assertDataSource(Class expectedType, List hiddenPackages, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationWithoutSpringJdbcTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfigurationWithoutSpringJdbcTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationWithoutSpringJdbcTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfigurationWithoutSpringJdbcTests.java index 73e35108a9d0..f3f373fbfc80 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationWithoutSpringJdbcTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceAutoConfigurationWithoutSpringJdbcTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.util.Random; import java.util.function.Function; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBeanCreationFailureAnalyzerTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceBeanCreationFailureAnalyzerTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBeanCreationFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceBeanCreationFailureAnalyzerTests.java index 45995da4b73c..6a38c5798975 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBeanCreationFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceBeanCreationFailureAnalyzerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.junit.jupiter.api.Test; @@ -34,7 +34,7 @@ * @author Andy Wilkinson * @author Stephane Nicoll */ -@ClassPathExclusions({ "h2-*.jar", "hsqldb-*.jar" }) +@ClassPathExclusions({ "derby-*.jar", "derbytools-*.jar", "h2-*.jar", "hsqldb-*.jar" }) class DataSourceBeanCreationFailureAnalyzerTests { private final MockEnvironment environment = new MockEnvironment(); diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceInitializationAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceInitializationAutoConfigurationTests.java new file mode 100644 index 000000000000..2f4ae04a7ebb --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceInitializationAutoConfigurationTests.java @@ -0,0 +1,152 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.autoconfigure; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.sql.autoconfigure.init.ApplicationScriptDatabaseInitializer; +import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer; +import org.springframework.boot.sql.init.DatabaseInitializationSettings; +import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.init.DatabasePopulator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link DataSourceInitializationAutoConfiguration}. + * + * @author Andy Wilkinson + * @author Phillip Webb + */ +class DataSourceInitializationAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(DataSourceInitializationAutoConfiguration.class)) + .withPropertyValues("spring.datasource.generate-unique-name:true"); + + @Test + void whenNoDataSourceIsAvailableThenAutoConfigurationBacksOff() { + this.contextRunner + .run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class)); + } + + @Test + void whenDataSourceIsAvailableThenDataSourceInitializerIsAutoConfigured() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .run((context) -> assertThat(context).hasSingleBean(DataSourceScriptDatabaseInitializer.class)); + } + + @Test + void whenDataSourceIsAvailableAndModeIsNeverThenInitializerIsNotAutoConfigured() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withPropertyValues("spring.sql.init.mode:never") + .run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class)); + } + + @Test + void whenAnApplicationInitializerIsDefinedThenInitializerIsNotAutoConfigured() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withUserConfiguration(ApplicationDatabaseInitializerConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ApplicationScriptDatabaseInitializer.class) + .hasBean("customInitializer")); + } + + @Test + void whenAnInitializerIsDefinedThenApplicationInitializerIsStillAutoConfigured() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withUserConfiguration(DatabaseInitializerConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ApplicationDataSourceScriptDatabaseInitializer.class) + .hasBean("customInitializer")); + } + + @Test + void whenBeanIsAnnotatedAsDependingOnDatabaseInitializationThenItDependsOnDataSourceScriptDatabaseInitializer() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withUserConfiguration(DependsOnInitializedDatabaseConfiguration.class) + .run((context) -> { + ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); + BeanDefinition beanDefinition = beanFactory.getBeanDefinition( + "dataSourceInitializationAutoConfigurationTests.DependsOnInitializedDatabaseConfiguration"); + assertThat(beanDefinition.getDependsOn()) + .containsExactlyInAnyOrder("dataSourceScriptDatabaseInitializer"); + }); + } + + @Test + void whenADataSourceIsAvailableAndSpringJdbcIsNotThenAutoConfigurationBacksOff() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withClassLoader(new FilteredClassLoader(DatabasePopulator.class)) + .run((context) -> { + assertThat(context).hasSingleBean(DataSource.class); + assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class); + }); + } + + @Configuration(proxyBeanMethods = false) + static class ApplicationDatabaseInitializerConfiguration { + + @Bean + ApplicationScriptDatabaseInitializer customInitializer() { + return mock(ApplicationScriptDatabaseInitializer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class DatabaseInitializerConfiguration { + + @Bean + DataSourceScriptDatabaseInitializer customInitializer() { + return new DataSourceScriptDatabaseInitializer(null, new DatabaseInitializationSettings()) { + + @Override + protected void runScripts(Scripts scripts) { + // No-op + } + + @Override + protected boolean isEmbeddedDatabase() { + return true; + } + + }; + } + + } + + @Configuration(proxyBeanMethods = false) + @DependsOnDatabaseInitialization + static class DependsOnInitializedDatabaseConfiguration { + + DependsOnInitializedDatabaseConfiguration() { + + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJmxConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJmxConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJmxConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJmxConfigurationTests.java index 818551e9a859..46e24bd9291c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJmxConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJmxConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.lang.management.ManagementFactory; import java.util.Set; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJsonSerializationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJsonSerializationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJsonSerializationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJsonSerializationTests.java index fd07eb1c0469..84ab5bcb9508 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceJsonSerializationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceJsonSerializationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.beans.PropertyDescriptor; import java.io.IOException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourcePropertiesTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourcePropertiesTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourcePropertiesTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourcePropertiesTests.java index 62a57d802ab5..d9cf18b6a7a3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourcePropertiesTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourcePropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceTransactionManagerAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceTransactionManagerAutoConfigurationTests.java index f21ffa3962aa..86a7d40b589f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/DataSourceTransactionManagerAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.util.UUID; @@ -23,10 +23,10 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizationAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.transaction.TransactionManager; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/Dbcp2JdbcConnectionDetailsBeanPostProcessorTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/Dbcp2JdbcConnectionDetailsBeanPostProcessorTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/Dbcp2JdbcConnectionDetailsBeanPostProcessorTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/Dbcp2JdbcConnectionDetailsBeanPostProcessorTests.java index cc14aefcc53a..67b1cdee827f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/Dbcp2JdbcConnectionDetailsBeanPostProcessorTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/Dbcp2JdbcConnectionDetailsBeanPostProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.apache.commons.dbcp2.BasicDataSource; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/EmbeddedDataSourceConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/EmbeddedDataSourceConfigurationTests.java index b645084dbcce..1eaba3eea3ad 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/EmbeddedDataSourceConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/EmbeddedDataSourceConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.sql.Connection; import java.sql.ResultSet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariDataSourceConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariDataSourceConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariDataSourceConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariDataSourceConfigurationTests.java index 1b580daa280a..ebc83d72a5d2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariDataSourceConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariDataSourceConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.io.PrintWriter; import java.sql.Connection; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzerTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariDriverConfigurationFailureAnalyzerTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariDriverConfigurationFailureAnalyzerTests.java index 21d45f48a17d..6edb62a48676 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariDriverConfigurationFailureAnalyzerTests.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import com.zaxxer.hikari.HikariDataSource; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; import org.springframework.boot.diagnostics.FailureAnalysis; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.testsupport.classpath.resources.WithResource; @@ -78,7 +77,7 @@ private BeanCreationException createFailure(Class configuration) { } @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ DataSourceAutoConfiguration.class, SqlInitializationAutoConfiguration.class }) + @ImportAutoConfiguration({ DataSourceAutoConfiguration.class, DataSourceInitializationAutoConfiguration.class }) static class TestConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariJdbcConnectionDetailsBeanPostProcessorTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariJdbcConnectionDetailsBeanPostProcessorTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariJdbcConnectionDetailsBeanPostProcessorTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariJdbcConnectionDetailsBeanPostProcessorTests.java index 8f50dbb28927..b32eb190393f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/HikariJdbcConnectionDetailsBeanPostProcessorTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/HikariJdbcConnectionDetailsBeanPostProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import com.zaxxer.hikari.HikariDataSource; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JdbcClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JdbcClientAutoConfigurationTests.java new file mode 100644 index 000000000000..d80d15b326f6 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JdbcClientAutoConfigurationTests.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.autoconfigure; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.JdbcClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link JdbcClientAutoConfiguration}. + * + * @author Stephane Nicoll + */ +class JdbcClientAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("spring.datasource.generate-unique-name=true") + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, + JdbcClientAutoConfiguration.class)); + + @Test + void jdbcClientWhenNoAvailableJdbcTemplateIsNotCreated() { + new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(DataSourceAutoConfiguration.class, JdbcClientAutoConfiguration.class)) + .run((context) -> assertThat(context).doesNotHaveBean(JdbcClient.class)); + } + + @Test + void jdbcClientWhenExistingJdbcTemplateIsCreated() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(JdbcClient.class); + NamedParameterJdbcTemplate namedParameterJdbcTemplate = context.getBean(NamedParameterJdbcTemplate.class); + assertThat(namedParameterJdbcTemplate.getJdbcOperations()).isEqualTo(context.getBean(JdbcOperations.class)); + }); + } + + @Test + void jdbcClientWithCustomJdbcClientIsNotCreated() { + this.contextRunner.withBean("customJdbcClient", JdbcClient.class, () -> mock(JdbcClient.class)) + .run((context) -> { + assertThat(context).hasSingleBean(JdbcClient.class); + assertThat(context.getBean(JdbcClient.class)).isEqualTo(context.getBean("customJdbcClient")); + }); + } + +} diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateAutoConfigurationTests.java new file mode 100644 index 000000000000..3e8020d97391 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JdbcTemplateAutoConfigurationTests.java @@ -0,0 +1,304 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.autoconfigure; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.sql.DataSource; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.support.SQLExceptionTranslator; +import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link JdbcTemplateAutoConfiguration}. + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Kazuki Shimizu + * @author Dan Zheng + */ +class JdbcTemplateAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("spring.datasource.generate-unique-name=true") + .withConfiguration( + AutoConfigurations.of(DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class)); + + @Test + void testJdbcTemplateExists() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(JdbcOperations.class); + JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); + assertThat(jdbcTemplate.getDataSource()).isEqualTo(context.getBean(DataSource.class)); + assertThat(jdbcTemplate.isIgnoreWarnings()).isEqualTo(true); + assertThat(jdbcTemplate.getFetchSize()).isEqualTo(-1); + assertThat(jdbcTemplate.getQueryTimeout()).isEqualTo(-1); + assertThat(jdbcTemplate.getMaxRows()).isEqualTo(-1); + assertThat(jdbcTemplate.isSkipResultsProcessing()).isEqualTo(false); + assertThat(jdbcTemplate.isSkipUndeclaredResults()).isEqualTo(false); + assertThat(jdbcTemplate.isResultsMapCaseInsensitive()).isEqualTo(false); + }); + } + + @Test + void testJdbcTemplateWithCustomProperties() { + this.contextRunner + .withPropertyValues("spring.jdbc.template.ignore-warnings:false", "spring.jdbc.template.fetch-size:100", + "spring.jdbc.template.query-timeout:60", "spring.jdbc.template.max-rows:1000", + "spring.jdbc.template.skip-results-processing:true", + "spring.jdbc.template.skip-undeclared-results:true", + "spring.jdbc.template.results-map-case-insensitive:true") + .run((context) -> { + assertThat(context).hasSingleBean(JdbcOperations.class); + JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); + assertThat(jdbcTemplate.getDataSource()).isNotNull(); + assertThat(jdbcTemplate.isIgnoreWarnings()).isEqualTo(false); + assertThat(jdbcTemplate.getFetchSize()).isEqualTo(100); + assertThat(jdbcTemplate.getQueryTimeout()).isEqualTo(60); + assertThat(jdbcTemplate.getMaxRows()).isEqualTo(1000); + assertThat(jdbcTemplate.isSkipResultsProcessing()).isEqualTo(true); + assertThat(jdbcTemplate.isSkipUndeclaredResults()).isEqualTo(true); + assertThat(jdbcTemplate.isResultsMapCaseInsensitive()).isEqualTo(true); + }); + } + + @Test + void testJdbcTemplateExistsWithCustomDataSource() { + this.contextRunner.withUserConfiguration(TestDataSourceConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(JdbcOperations.class); + JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); + assertThat(jdbcTemplate.getDataSource()).isEqualTo(context.getBean("customDataSource")); + }); + } + + @Test + void testNamedParameterJdbcTemplateExists() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class); + NamedParameterJdbcTemplate namedParameterJdbcTemplate = context.getBean(NamedParameterJdbcTemplate.class); + assertThat(namedParameterJdbcTemplate.getJdbcOperations()).isEqualTo(context.getBean(JdbcOperations.class)); + }); + } + + @Test + void testMultiDataSource() { + this.contextRunner.withUserConfiguration(MultiDataSourceConfiguration.class).run((context) -> { + assertThat(context).doesNotHaveBean(JdbcOperations.class); + assertThat(context).doesNotHaveBean(NamedParameterJdbcOperations.class); + }); + } + + @Test + void testMultiJdbcTemplate() { + this.contextRunner.withUserConfiguration(MultiJdbcTemplateConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(NamedParameterJdbcOperations.class)); + } + + @Test + void testMultiDataSourceUsingPrimary() { + this.contextRunner.withUserConfiguration(MultiDataSourceUsingPrimaryConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(JdbcOperations.class); + assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class); + assertThat(context.getBean(JdbcTemplate.class).getDataSource()) + .isEqualTo(context.getBean("test1DataSource")); + }); + } + + @Test + void testMultiJdbcTemplateUsingPrimary() { + this.contextRunner.withUserConfiguration(MultiJdbcTemplateUsingPrimaryConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class); + assertThat(context.getBean(NamedParameterJdbcTemplate.class).getJdbcOperations()) + .isEqualTo(context.getBean("test1Template")); + }); + } + + @Test + void testExistingCustomJdbcTemplate() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(JdbcOperations.class); + assertThat(context.getBean(JdbcOperations.class)).isEqualTo(context.getBean("customJdbcOperations")); + }); + } + + @Test + void testExistingCustomNamedParameterJdbcTemplate() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class); + assertThat(context.getBean(NamedParameterJdbcOperations.class)) + .isEqualTo(context.getBean("customNamedParameterJdbcOperations")); + }); + } + + @Test + @WithResource(name = "schema.sql", content = """ + CREATE TABLE BAR ( + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name VARCHAR(30) + ); + """) + @WithResource(name = "data.sql", content = "INSERT INTO BAR VALUES (1, 'Andy');") + void testDependencyToScriptBasedDataSourceInitialization() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceInitializationAutoConfiguration.class)) + .withUserConfiguration(DataSourceInitializationValidator.class) + .run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context.getBean(DataSourceInitializationValidator.class).count).isOne(); + }); + } + + @Test + void shouldConfigureJdbcTemplateWithSQLExceptionTranslatorIfPresent() { + SQLStateSQLExceptionTranslator sqlExceptionTranslator = new SQLStateSQLExceptionTranslator(); + this.contextRunner.withBean(SQLExceptionTranslator.class, () -> sqlExceptionTranslator).run((context) -> { + assertThat(context).hasSingleBean(JdbcTemplate.class); + JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); + assertThat(jdbcTemplate.getExceptionTranslator()).isSameAs(sqlExceptionTranslator); + }); + } + + @Test + void shouldNotConfigureJdbcTemplateWithSQLExceptionTranslatorIfNotUnique() { + SQLStateSQLExceptionTranslator sqlExceptionTranslator1 = new SQLStateSQLExceptionTranslator(); + SQLStateSQLExceptionTranslator sqlExceptionTranslator2 = new SQLStateSQLExceptionTranslator(); + this.contextRunner + .withBean("sqlExceptionTranslator1", SQLExceptionTranslator.class, () -> sqlExceptionTranslator1) + .withBean("sqlExceptionTranslator2", SQLExceptionTranslator.class, () -> sqlExceptionTranslator2) + .run((context) -> { + assertThat(context).hasSingleBean(JdbcTemplate.class); + JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); + assertThat(jdbcTemplate.getExceptionTranslator()).isNotSameAs(sqlExceptionTranslator1) + .isNotSameAs(sqlExceptionTranslator2); + }); + } + + @Configuration(proxyBeanMethods = false) + static class CustomConfiguration { + + @Bean + JdbcOperations customJdbcOperations(DataSource dataSource) { + return new JdbcTemplate(dataSource); + } + + @Bean + NamedParameterJdbcOperations customNamedParameterJdbcOperations(DataSource dataSource) { + return new NamedParameterJdbcTemplate(dataSource); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TestDataSourceConfiguration { + + @Bean + DataSource customDataSource() { + return new TestDataSource(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MultiJdbcTemplateConfiguration { + + @Bean + JdbcTemplate test1Template() { + return mock(JdbcTemplate.class); + } + + @Bean + JdbcTemplate test2Template() { + return mock(JdbcTemplate.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MultiJdbcTemplateUsingPrimaryConfiguration { + + @Bean + @Primary + JdbcTemplate test1Template() { + return mock(JdbcTemplate.class); + } + + @Bean + JdbcTemplate test2Template() { + return mock(JdbcTemplate.class); + } + + } + + static class DataSourceInitializationValidator { + + private final Integer count; + + DataSourceInitializationValidator(JdbcTemplate jdbcTemplate) { + this.count = jdbcTemplate.queryForObject("SELECT COUNT(*) from BAR", Integer.class); + } + + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @WithResource(name = "db/changelog/db.changelog-city.yaml", content = """ + databaseChangeLog: + - changeSet: + id: 1 + author: dsyer + changes: + - createSequence: + sequenceName: city_seq + incrementBy: 50 + - createTable: + tableName: city + columns: + - column: + name: id + type: bigint + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: name + type: varchar(50) + constraints: + nullable: false + """) + @interface WithDbChangelogCityYamlResource { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JndiDataSourceAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JndiDataSourceAutoConfigurationTests.java index b0272f8f370d..d01f6f644b68 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/JndiDataSourceAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.util.Set; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/MultiDataSourceConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/MultiDataSourceConfiguration.java index 9bc0e8a382b6..514a818d9798 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/MultiDataSourceConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceUsingPrimaryConfiguration.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/MultiDataSourceUsingPrimaryConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceUsingPrimaryConfiguration.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/MultiDataSourceUsingPrimaryConfiguration.java index e249969cfbd8..338f8b411731 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceUsingPrimaryConfiguration.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/MultiDataSourceUsingPrimaryConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpDataSourceConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpDataSourceConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpDataSourceConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpDataSourceConfigurationTests.java index 5c5f8ca856f5..384c9dcac082 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpDataSourceConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpDataSourceConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.sql.Connection; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpJdbcConnectionDetailsBeanPostProcessorTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpJdbcConnectionDetailsBeanPostProcessorTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpJdbcConnectionDetailsBeanPostProcessorTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpJdbcConnectionDetailsBeanPostProcessorTests.java index f4affb1f30ba..dcf3668593bf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/OracleUcpJdbcConnectionDetailsBeanPostProcessorTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/OracleUcpJdbcConnectionDetailsBeanPostProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.sql.SQLException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestDataSource.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TestDataSource.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestDataSource.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TestDataSource.java index c03f32e47ce0..6e1097ea56ac 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestDataSource.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TestDataSource.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import java.sql.Connection; import java.sql.SQLException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestJdbcConnectionDetails.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TestJdbcConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestJdbcConnectionDetails.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TestJdbcConnectionDetails.java index fd8b17894389..922ac9cfc2ed 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestJdbcConnectionDetails.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TestJdbcConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.springframework.boot.jdbc.DatabaseDriver; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TomcatDataSourceConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TomcatDataSourceConfigurationTests.java index ac9dbcfdf1ed..75559c38c439 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TomcatDataSourceConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatJdbcConnectionDetailsBeanPostProcessorTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TomcatJdbcConnectionDetailsBeanPostProcessorTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatJdbcConnectionDetailsBeanPostProcessorTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TomcatJdbcConnectionDetailsBeanPostProcessorTests.java index 4e0b4964da9a..002531a88524 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatJdbcConnectionDetailsBeanPostProcessorTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/TomcatJdbcConnectionDetailsBeanPostProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import org.apache.tomcat.jdbc.pool.DataSource; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/XADataSourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/XADataSourceAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/XADataSourceAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/XADataSourceAutoConfigurationTests.java index ed5e99a09c3f..9ab067031c73 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/XADataSourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/XADataSourceAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure; import javax.sql.DataSource; import javax.sql.XADataSource; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthContributorAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthContributorAutoConfigurationTests.java index 71e277016967..77866e1aa29c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/health/DataSourceHealthContributorAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.jdbc; +package org.springframework.boot.jdbc.autoconfigure.health; import java.sql.SQLException; import java.util.HashMap; @@ -29,18 +29,18 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthContributorAutoConfiguration.RoutingDataSourceHealthContributor; -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.NamedContributor; -import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.HealthContributors; import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourcePoolMetadataProvidersConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; +import org.springframework.boot.jdbc.autoconfigure.health.DataSourceHealthContributorAutoConfiguration.RoutingDataSourceHealthContributor; +import org.springframework.boot.jdbc.health.DataSourceHealthIndicator; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -80,7 +80,7 @@ void runWhenMultipleDataSourceBeansShouldCreateCompositeIndicator() { .run((context) -> { assertThat(context).hasSingleBean(CompositeHealthContributor.class); CompositeHealthContributor contributor = context.getBean(CompositeHealthContributor.class); - String[] names = contributor.stream().map(NamedContributor::getName).toArray(String[]::new); + String[] names = contributor.stream().map(HealthContributors.Entry::name).toArray(String[]::new); assertThat(names).containsExactlyInAnyOrder("dataSource", "standardDataSource", "nonDefaultDataSource"); }); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/metrics/DataSourcePoolMetricsAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/metrics/DataSourcePoolMetricsAutoConfigurationTests.java index 63803e77891e..ab93a5bd6863 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/autoconfigure/metrics/DataSourcePoolMetricsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.jdbc; +package org.springframework.boot.jdbc.autoconfigure.metrics; import java.sql.SQLException; import java.util.UUID; @@ -31,12 +31,12 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -58,10 +58,11 @@ class DataSourcePoolMetricsAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.datasource.generate-unique-name=true") - .with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(DataSourcePoolMetricsAutoConfiguration.class)) - .withUserConfiguration(BaseConfiguration.class); + .withPropertyValues("spring.datasource.generate-unique-name=true", + "management.metrics.use-global-registry=false") + .withBean(SimpleMeterRegistry.class) + .withConfiguration( + AutoConfigurations.of(MetricsAutoConfiguration.class, DataSourcePoolMetricsAutoConfiguration.class)); @Test void autoConfiguredDataSourceIsInstrumented() { @@ -125,8 +126,8 @@ void autoConfiguredHikariDataSourceIsInstrumented() { @Test void autoConfiguredHikariDataSourceIsInstrumentedWhenUsingDataSourceInitialization() { this.contextRunner.withPropertyValues("spring.sql.init.schema:db/create-custom-schema.sql") - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class, SqlInitializationAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + DataSourceInitializationAutoConfiguration.class)) .run((context) -> { context.getBean(DataSource.class).getConnection(); MeterRegistry registry = context.getBean(MeterRegistry.class); @@ -244,16 +245,6 @@ private static HikariDataSource createHikariDataSource(String poolName) { return hikariDataSource; } - @Configuration(proxyBeanMethods = false) - static class BaseConfiguration { - - @Bean - SimpleMeterRegistry simpleMeterRegistry() { - return new SimpleMeterRegistry(); - } - - } - @Configuration(proxyBeanMethods = false) static class TwoDataSourcesConfiguration { diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/ClickHouseEnvironmentTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/ClickHouseEnvironmentTests.java new file mode 100644 index 000000000000..c1e256250a5e --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/ClickHouseEnvironmentTests.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link ClickHouseEnvironment}. + * + * @author Stephane Nicoll + */ +class ClickHouseEnvironmentTests { + + @Test + void createWhenNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new ClickHouseEnvironment(Collections.emptyMap())) + .withMessage("No ClickHouse password found"); + } + + @Test + void getPasswordWhenHasPassword() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "true")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPasswordIsYes() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getUsernameWhenNoUser() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("default"); + } + + @Test + void getUsernameWhenHasUser() { + ClickHouseEnvironment environment = new ClickHouseEnvironment( + Map.of("CLICKHOUSE_USER", "me", "CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getDatabaseWhenNoDatabase() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("default"); + } + + @Test + void getDatabaseWhenHasDatabase() { + ClickHouseEnvironment environment = new ClickHouseEnvironment( + Map.of("CLICKHOUSE_DB", "db", "CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/jdbc/JdbcUrlBuilderTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/JdbcUrlBuilderTests.java similarity index 97% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/jdbc/JdbcUrlBuilderTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/JdbcUrlBuilderTests.java index d391125479d7..785d2f5a91b4 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/jdbc/JdbcUrlBuilderTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/JdbcUrlBuilderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.jdbc; +package org.springframework.boot.jdbc.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironmentTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironmentTests.java new file mode 100644 index 000000000000..54d872a6fafd --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironmentTests.java @@ -0,0 +1,176 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link MariaDbEnvironment}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Jinseong Hwang + * @author Scott Frederick + */ +class MariaDbEnvironmentTests { + + @Test + void createWhenHasMariadbRandomRootPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_RANDOM_ROOT_PASSWORD", "true"))) + .withMessage("MARIADB_RANDOM_ROOT_PASSWORD is not supported"); + } + + @Test + void createWhenHasMysqlRandomRootPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new MariaDbEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"))) + .withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported"); + } + + @Test + void createWhenHasMariadbRootPasswordHashThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_ROOT_PASSWORD_HASH", "0FF"))) + .withMessage("MARIADB_ROOT_PASSWORD_HASH is not supported"); + } + + @Test + void createWhenHasNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Collections.emptyMap())) + .withMessage("No MariaDB password found"); + } + + @Test + void createWhenHasNoDatabaseThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_PASSWORD", "secret"))) + .withMessage("No MARIADB_DATABASE defined"); + } + + @Test + void getUsernameWhenHasMariadbUser() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("myself"); + } + + @Test + void getUsernameWhenHasMysqlUser() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MYSQL_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("myself"); + } + + @Test + void getUsernameWhenHasMariadbUserAndMysqlUser() { + MariaDbEnvironment environment = new MariaDbEnvironment(Map.of("MARIADB_USER", "myself", "MYSQL_USER", "me", + "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("myself"); + } + + @Test + void getUsernameWhenHasNoMariadbUserOrMysqlUser() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("root"); + } + + @Test + void getPasswordWhenHasMariadbPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMysqlPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MYSQL_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMysqlRootPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MYSQL_ROOT_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMariadbPasswordAndMysqlPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_PASSWORD", "secret", "MYSQL_PASSWORD", "donttell", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMariadbPasswordAndMysqlRootPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_PASSWORD", "secret", "MYSQL_ROOT_PASSWORD", "donttell", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getDatabaseWhenHasMariadbDatabase() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + + @Test + void getDatabaseWhenHasMysqlDatabase() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + + @Test + void getDatabaseWhenHasMariadbAndMysqlDatabase() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MySqlEnvironmentTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MySqlEnvironmentTests.java new file mode 100644 index 000000000000..86ceace1e344 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MySqlEnvironmentTests.java @@ -0,0 +1,104 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link MySqlEnvironment}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Jinseong Hwang + * @author Scott Frederick + */ +class MySqlEnvironmentTests { + + @Test + void createWhenHasMysqlRandomRootPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"))) + .withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported"); + } + + @Test + void createWhenHasNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Collections.emptyMap())) + .withMessage("No MySQL password found"); + } + + @Test + void createWhenHasNoDatabaseThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret"))) + .withMessage("No MYSQL_DATABASE defined"); + } + + @Test + void getUsernameWhenHasMysqlUser() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("MYSQL_USER", "myself", "MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("myself"); + } + + @Test + void getUsernameWhenHasNoMysqlUser() { + MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("root"); + } + + @Test + void getPasswordWhenHasMysqlPassword() { + MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMysqlRootPassword() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("MYSQL_ROOT_PASSWORD", "secret", "MYSQL_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getDatabaseWhenHasMysqlDatabase() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/OracleEnvironmentTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/OracleEnvironmentTests.java new file mode 100644 index 000000000000..6b0a70dee0ba --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/OracleEnvironmentTests.java @@ -0,0 +1,115 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatNoException; + +/** + * Tests for {@link OracleEnvironment}. + * + * @author Andy Wilkinson + */ +class OracleEnvironmentTests { + + @Test + void getUsernameWhenHasAppUser() { + OracleEnvironment environment = new OracleEnvironment( + Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getUsername()).isEqualTo("alice"); + } + + @Test + void getUsernameWhenHasNoAppUser() { + OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getUsername()).isEqualTo("system"); + } + + @Test + void getPasswordWhenHasAppPassword() { + OracleEnvironment environment = new OracleEnvironment( + Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasOraclePassword() { + OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void createWhenRandomPasswordAndAppPasswordDoesNotThrow() { + assertThatNoException().isThrownBy(() -> new OracleEnvironment( + Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret", "ORACLE_RANDOM_PASSWORD", "true"), + "defaultDb")); + } + + @Test + void createWhenRandomPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new OracleEnvironment(Map.of("ORACLE_RANDOM_PASSWORD", "true"), "defaultDb")) + .withMessage("ORACLE_RANDOM_PASSWORD is not supported without APP_USER and APP_USER_PASSWORD"); + } + + @Test + void createWhenAppUserAndNoAppPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new OracleEnvironment(Map.of("APP_USER", "alice"), "defaultDb")) + .withMessage("No Oracle app password found"); + } + + @Test + void createWhenAppUserAndEmptyAppPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new OracleEnvironment(Map.of("APP_USER", "alice", "APP_USER_PASSWORD", ""), "defaultDb")) + .withMessage("No Oracle app password found"); + } + + @Test + void createWhenHasNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new OracleEnvironment(Collections.emptyMap(), "defaultDb")) + .withMessage("No Oracle password found"); + } + + @Test + void createWhenHasEmptyPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new OracleEnvironment(Map.of("ORACLE_PASSWORD", ""), "defaultDb")) + .withMessage("No Oracle password found"); + } + + @Test + void getDatabaseWhenHasNoOracleDatabase() { + OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getDatabase()).isEqualTo("defaultDb"); + } + + @Test + void getDatabaseWhenHasOracleDatabase() { + OracleEnvironment environment = new OracleEnvironment( + Map.of("ORACLE_PASSWORD", "secret", "ORACLE_DATABASE", "db"), "defaultDb"); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/PostgresEnvironmentTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/PostgresEnvironmentTests.java new file mode 100644 index 000000000000..653ad8dc1cb9 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/PostgresEnvironmentTests.java @@ -0,0 +1,156 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link PostgresEnvironment}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + * @author Sidmar Theodoro + * @author He Zean + */ +class PostgresEnvironmentTests { + + @Test + void createWhenNoPostgresPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new PostgresEnvironment(Collections.emptyMap())) + .withMessage("No PostgreSQL password found"); + } + + @Test + void getUsernameWhenNoPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("postgres"); + } + + @Test + void getUsernameWhenNoPostgresqlUser() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("postgres"); + } + + @Test + void getUsernameWhenHasPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getUsernameWhenHasPostgresqlUser() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_USER", "me", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getUsernameWhenHasPostgresqlUsername() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getPasswordWhenHasPostgresPassword() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasPostgresqlPassword() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasTrustHostAuthMethod() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_HOST_AUTH_METHOD", "trust")); + assertThat(environment.getPassword()).isNull(); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getDatabaseWhenNoPostgresDbOrPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("postgres"); + } + + @Test + void getDatabaseWhenNoPostgresqlDbOrPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("postgres"); + } + + @Test + void getDatabaseWhenNoPostgresDbAndPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("me"); + } + + @Test + void getDatabaseWhenNoPostgresqlDbAndPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_USER", "me", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("me"); + } + + @Test + void getDatabaseWhenNoPostgresqlDatabaseAndPostgresqlUsername() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("me"); + } + + @Test + void getDatabaseWhenHasPostgresDb() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRES_DB", "db", "POSTGRES_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + + @Test + void getDatabaseWhenHasPostgresqlDb() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_DB", "db", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + + @Test + void getDatabaseWhenHasPostgresqlDatabase() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_DATABASE", "db", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java similarity index 97% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java index c4617eb8e460..b74777ce09e2 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/PostgresJdbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.postgres; +package org.springframework.boot.jdbc.docker.compose; import java.util.LinkedHashMap; import java.util.Map; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.core.ConnectionPorts; import org.springframework.boot.docker.compose.core.RunningService; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.mock.env.MockEnvironment; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/SqlServerEnvironmentTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/SqlServerEnvironmentTests.java new file mode 100644 index 000000000000..77370366ff69 --- /dev/null +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/SqlServerEnvironmentTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jdbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link SqlServerEnvironment}. + * + * @author Andy Wilkinson + */ +class SqlServerEnvironmentTests { + + @Test + void createWhenHasNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new SqlServerEnvironment(Collections.emptyMap())) + .withMessage("No MSSQL password found"); + } + + @Test + void getUsernameWhenHasNoMsSqlUser() { + SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("MSSQL_SA_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("SA"); + } + + @Test + void getPasswordWhenHasMsSqlSaPassword() { + SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("MSSQL_SA_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasSaPassword() { + SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("SA_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMsSqlSaPasswordAndSaPasswordPrefersMsSqlSaPassword() { + SqlServerEnvironment environment = new SqlServerEnvironment( + Map.of("MSSQL_SA_PASSWORD", "secret", "SA_PASSWORD", "not used")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicatorTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/health/DataSourceHealthIndicatorTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicatorTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/health/DataSourceHealthIndicatorTests.java index 56f483223b33..55645092e6e9 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/health/DataSourceHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.jdbc; +package org.springframework.boot.jdbc.health; import java.sql.Connection; import java.sql.SQLException; @@ -25,8 +25,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SingleConnectionDataSource; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/init/DataSourceScriptDatabaseInitializerTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolverTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolverTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolverTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/init/PlatformPlaceholderDatabaseDriverResolverTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CompositeDataSourcePoolMetadataProviderTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/CompositeDataSourcePoolMetadataProviderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CompositeDataSourcePoolMetadataProviderTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/CompositeDataSourcePoolMetadataProviderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/OracleUcpDataSourcePoolMetadataTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/OracleUcpDataSourcePoolMetadataTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/OracleUcpDataSourcePoolMetadataTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/OracleUcpDataSourcePoolMetadataTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/jdbc/DataSourcePoolMetricsTests.java b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metrics/DataSourcePoolMetricsTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/jdbc/DataSourcePoolMetricsTests.java rename to spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metrics/DataSourcePoolMetricsTests.java index 21573d8e4844..6179252c60d8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/jdbc/DataSourcePoolMetricsTests.java +++ b/spring-boot-project/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/metrics/DataSourcePoolMetricsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.jdbc; +package org.springframework.boot.jdbc.metrics; import java.util.Collection; import java.util.Collections; @@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-jersey/build.gradle b/spring-boot-project/spring-boot-jersey/build.gradle new file mode 100644 index 000000000000..23bd95396471 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/build.gradle @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "java-test-fixtures" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Jersey" + +dependencies { + api(project(":spring-boot-project:spring-boot-servlet")) + api("org.glassfish.jersey.containers:jersey-container-servlet-core") + api("org.glassfish.jersey.containers:jersey-container-servlet") + api("org.glassfish.jersey.core:jersey-server") + api("org.glassfish.jersey.ext:jersey-spring6") + api("org.glassfish.jersey.media:jersey-media-json-jackson") + compileOnly("jakarta.servlet:jakarta.servlet-api") + + implementation("org.springframework:spring-web") + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-jackson")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-observation")) + optional("io.projectreactor:reactor-core") + optional("org.glassfish.jersey.ext:jersey-micrometer") + + testFixturesApi(testFixtures(project(":spring-boot-project:spring-boot-actuator"))) + testFixturesImplementation(project(":spring-boot-project:spring-boot-tomcat")) + + testImplementation(project(":spring-boot-project:spring-boot-restclient")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-web-server-test")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))) + testImplementation("jakarta.servlet:jakarta.servlet-api") + testImplementation("org.springframework:spring-webflux") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyEndpointResourceFactory.java similarity index 99% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyEndpointResourceFactory.java index af162d97ee1e..4ca788c1f03a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyEndpointResourceFactory.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyEndpointResourceFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.jersey; +package org.springframework.boot.jersey.actuate.endpoint.web; import java.io.IOException; import java.io.InputStream; @@ -67,7 +67,7 @@ * * @author Andy Wilkinson * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ public class JerseyEndpointResourceFactory { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyHealthEndpointAdditionalPathResourceFactory.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyHealthEndpointAdditionalPathResourceFactory.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyHealthEndpointAdditionalPathResourceFactory.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyHealthEndpointAdditionalPathResourceFactory.java index daa4407506dc..a0cb753591ce 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyHealthEndpointAdditionalPathResourceFactory.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyHealthEndpointAdditionalPathResourceFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.jersey; +package org.springframework.boot.jersey.actuate.endpoint.web; import java.util.ArrayList; import java.util.Collection; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyRemainingPathSegmentProvider.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyRemainingPathSegmentProvider.java similarity index 93% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyRemainingPathSegmentProvider.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyRemainingPathSegmentProvider.java index 3c52e0480b73..90a2704f10e5 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyRemainingPathSegmentProvider.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/JerseyRemainingPathSegmentProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.jersey; +package org.springframework.boot.jersey.actuate.endpoint.web; import jakarta.ws.rs.container.ContainerRequestContext; diff --git a/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/package-info.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/package-info.java new file mode 100644 index 000000000000..f32934da0f67 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/actuate/endpoint/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Jersey support for actuator endpoints. + */ +package org.springframework.boot.jersey.actuate.endpoint.web; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DefaultJerseyApplicationPath.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/DefaultJerseyApplicationPath.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DefaultJerseyApplicationPath.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/DefaultJerseyApplicationPath.java index 515bcbf8722c..52c77ae6fe38 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DefaultJerseyApplicationPath.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/DefaultJerseyApplicationPath.java @@ -14,12 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.jersey.autoconfigure; import jakarta.ws.rs.ApplicationPath; import org.glassfish.jersey.server.ResourceConfig; -import org.springframework.boot.autoconfigure.jersey.JerseyProperties; import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; @@ -30,7 +29,7 @@ * {@link JerseyProperties} or the {@code @ApplicationPath} annotation. * * @author Madhura Bhave - * @since 2.1.0 + * @since 4.0.0 */ public class DefaultJerseyApplicationPath implements JerseyApplicationPath { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/JerseyApplicationPath.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyApplicationPath.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/JerseyApplicationPath.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyApplicationPath.java index 1abebb2f79aa..721fd551a971 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/JerseyApplicationPath.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyApplicationPath.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.jersey.autoconfigure; import org.springframework.boot.web.servlet.ServletRegistrationBean; @@ -23,7 +23,7 @@ * application path that serves as the base URI for the application. * * @author Madhura Bhave - * @since 2.0.7 + * @since 4.0.0 */ @FunctionalInterface public interface JerseyApplicationPath { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfiguration.java index 8081eb7d6002..8e3288185bb4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.util.Collections; import java.util.EnumSet; @@ -45,15 +45,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean; -import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.DynamicRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -74,9 +70,9 @@ * @author Andy Wilkinson * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.2.0 + * @since 4.0.0 */ -@AutoConfiguration(before = DispatcherServletAutoConfiguration.class, after = JacksonAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration") @ConditionalOnClass({ SpringComponentProvider.class, ServletRegistration.class }) @ConditionalOnBean(type = "org.glassfish.jersey.server.ResourceConfig") @ConditionalOnWebApplication(type = Type.SERVLET) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyProperties.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyProperties.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyProperties.java index 36d1580f8547..0ba9e5733966 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyProperties.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.util.HashMap; import java.util.Map; @@ -27,7 +27,7 @@ * @author Dave Syer * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.jersey") public class JerseyProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/ResourceConfigCustomizer.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/ResourceConfigCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/ResourceConfigCustomizer.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/ResourceConfigCustomizer.java index 0d9637065d33..050798a2d7da 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/ResourceConfigCustomizer.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/ResourceConfigCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import org.glassfish.jersey.server.ResourceConfig; @@ -23,7 +23,7 @@ * {@link ResourceConfig} before it is used. * * @author Eddú Meléndez - * @since 1.4.0 + * @since 4.0.0 */ @FunctionalInterface public interface ResourceConfigCustomizer { diff --git a/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/HealthEndpointJerseyExtensionAutoConfiguration.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/HealthEndpointJerseyExtensionAutoConfiguration.java new file mode 100644 index 000000000000..70d928c0d580 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/HealthEndpointJerseyExtensionAutoConfiguration.java @@ -0,0 +1,147 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.Resource; +import org.glassfish.jersey.servlet.ServletContainer; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; +import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; +import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.HealthEndpointGroups; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jersey.actuate.endpoint.web.JerseyHealthEndpointAdditionalPathResourceFactory; +import org.springframework.boot.jersey.autoconfigure.DefaultJerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyProperties; +import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Auto-Configuration for {@link HealthEndpoint} Jersey extension. + * + * @author Phillip Webb + * @author Madhura Bhave + * @since 4.0.0 + * @see HealthEndpointAutoConfiguration + */ +@AutoConfiguration +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnBean(HealthEndpoint.class) +@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB) +@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") +public class HealthEndpointJerseyExtensionAutoConfiguration { + + @Bean + JerseyAdditionalHealthEndpointPathsResourcesRegistrar jerseyAdditionalHealthEndpointPathsResourcesRegistrar( + WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups healthEndpointGroups) { + ExposableWebEndpoint health = getHealthEndpoint(webEndpointsSupplier); + return new JerseyAdditionalHealthEndpointPathsResourcesRegistrar(health, healthEndpointGroups); + } + + private static ExposableWebEndpoint getHealthEndpoint(WebEndpointsSupplier webEndpointsSupplier) { + Collection webEndpoints = webEndpointsSupplier.getEndpoints(); + return webEndpoints.stream() + .filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)) + .findFirst() + .orElse(null); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnMissingBean(ResourceConfig.class) + @EnableConfigurationProperties(JerseyProperties.class) + static class JerseyInfrastructureConfiguration { + + @Bean + @ConditionalOnMissingBean + JerseyApplicationPath jerseyApplicationPath(JerseyProperties properties, ResourceConfig config) { + return new DefaultJerseyApplicationPath(properties.getApplicationPath(), config); + } + + @Bean + ResourceConfig resourceConfig(ObjectProvider resourceConfigCustomizers) { + ResourceConfig resourceConfig = new ResourceConfig(); + resourceConfigCustomizers.orderedStream().forEach((customizer) -> customizer.customize(resourceConfig)); + return resourceConfig; + } + + @Bean + ServletRegistrationBean jerseyServletRegistration(JerseyApplicationPath jerseyApplicationPath, + ResourceConfig resourceConfig) { + return new ServletRegistrationBean<>(new ServletContainer(resourceConfig), + jerseyApplicationPath.getUrlMapping()); + } + + } + + static class JerseyAdditionalHealthEndpointPathsResourcesRegistrar implements ResourceConfigCustomizer { + + private final ExposableWebEndpoint endpoint; + + private final HealthEndpointGroups groups; + + JerseyAdditionalHealthEndpointPathsResourcesRegistrar(ExposableWebEndpoint endpoint, + HealthEndpointGroups groups) { + this.endpoint = endpoint; + this.groups = groups; + } + + @Override + public void customize(ResourceConfig config) { + register(config); + } + + private void register(ResourceConfig config) { + EndpointMapping mapping = new EndpointMapping(""); + JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory( + WebServerNamespace.SERVER, this.groups); + Collection endpointResources = resourceFactory + .createEndpointResources(mapping, + (this.endpoint != null) ? Collections.singletonList(this.endpoint) : Collections.emptyList()) + .stream() + .filter(Objects::nonNull) + .toList(); + register(endpointResources, config); + } + + private void register(Collection resources, ResourceConfig config) { + config.registerResources(new HashSet<>(resources)); + } + + } + +} diff --git a/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/package-info.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/package-info.java new file mode 100644 index 000000000000..c14cbc6f3cb3 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Jersey actuator web endpoint support. + */ +package org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfiguration.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyChildManagementContextConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfiguration.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyChildManagementContextConfiguration.java index d8cb2157dcbc..5e941bbd215b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyChildManagementContextConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.jersey; +package org.springframework.boot.jersey.autoconfigure.actuate.web; import org.glassfish.jersey.server.ResourceConfig; @@ -24,7 +24,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -34,12 +34,12 @@ * different port is required. * * @author Madhura Bhave - * @since 2.1.0 + * @since 4.0.0 */ @ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) @Import(JerseyManagementContextConfiguration.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@ConditionalOnClass(ResourceConfig.class) +@ConditionalOnClass({ JerseyApplicationPath.class, ResourceConfig.class }) @ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") public class JerseyChildManagementContextConfiguration { diff --git a/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyEndpointManagementContextConfiguration.java new file mode 100644 index 000000000000..451e2f83b639 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyEndpointManagementContextConfiguration.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure.actuate.web; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jetty + * endpoints. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Madhura Bhave + * @since 4.0.0 + */ +@ManagementContextConfiguration(proxyBeanMethods = false) +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") +public class JerseyEndpointManagementContextConfiguration { + + @Bean + @SuppressWarnings("removal") + public org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar servletEndpointRegistrar( + WebEndpointProperties properties, + org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier servletEndpointsSupplier, + JerseyApplicationPath jerseyApplicationPath, EndpointAccessResolver endpointAccessResolver) { + return new org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar( + jerseyApplicationPath.getRelativePath(properties.getBasePath()), + servletEndpointsSupplier.getEndpoints(), endpointAccessResolver); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementContextConfiguration.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyManagementContextConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementContextConfiguration.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyManagementContextConfiguration.java index 78d039e870d1..0567ed07dfa2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyManagementContextConfiguration.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.jersey; +package org.springframework.boot.jersey.autoconfigure.actuate.web; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfiguration.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseySameManagementContextConfiguration.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfiguration.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseySameManagementContextConfiguration.java index a321f1b93e3a..5b64d37462a8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseySameManagementContextConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.jersey; +package org.springframework.boot.jersey.autoconfigure.actuate.web; import org.glassfish.jersey.server.ResourceConfig; @@ -25,11 +25,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.jersey.JerseyProperties; -import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; -import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jersey.autoconfigure.DefaultJerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyProperties; +import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -39,12 +39,12 @@ * infrastructure when the management context is the same as the main application context. * * @author Madhura Bhave - * @since 2.1.0 + * @since 4.0.0 */ @ManagementContextConfiguration(value = ManagementContextType.SAME, proxyBeanMethods = false) @EnableConfigurationProperties(JerseyProperties.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@ConditionalOnClass(ResourceConfig.class) +@ConditionalOnClass({ JerseyApplicationPath.class, ResourceConfig.class }) @ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") public class JerseySameManagementContextConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java index f481ee980090..e8b3f50a7ba5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey; +package org.springframework.boot.jersey.autoconfigure.actuate.web; import java.util.ArrayList; import java.util.Collection; @@ -34,7 +34,6 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.jersey.ManagementContextResourceConfigCustomizer; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; import org.springframework.boot.actuate.endpoint.EndpointId; @@ -48,8 +47,6 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.endpoint.web.jersey.JerseyEndpointResourceFactory; -import org.springframework.boot.actuate.endpoint.web.jersey.JerseyHealthEndpointAdditionalPathResourceFactory; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -57,7 +54,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; +import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory; +import org.springframework.boot.jersey.actuate.endpoint.web.JerseyHealthEndpointAdditionalPathResourceFactory; +import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; @@ -230,7 +229,12 @@ private EndpointObjectMapperContextResolver(EndpointObjectMapper endpointObjectM @Override public ObjectMapper getContext(Class type) { - return OperationResponseBody.class.isAssignableFrom(type) ? this.endpointObjectMapper.get() : null; + for (Class supportedType : this.endpointObjectMapper.getSupportedTypes()) { + if (supportedType.isAssignableFrom(type)) { + return this.endpointObjectMapper.get(); + } + } + return null; } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/ManagementContextResourceConfigCustomizer.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/ManagementContextResourceConfigCustomizer.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/ManagementContextResourceConfigCustomizer.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/ManagementContextResourceConfigCustomizer.java index d98705d5fefd..f08e9c8d33b6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/ManagementContextResourceConfigCustomizer.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/ManagementContextResourceConfigCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.jersey; +package org.springframework.boot.jersey.autoconfigure.actuate.web; import org.glassfish.jersey.server.ResourceConfig; @@ -23,7 +23,7 @@ * {@link ResourceConfig} in the management context before it is used. * * @author Andy Wilkinson - * @since 2.3.10 + * @since 4.0.0 */ public interface ManagementContextResourceConfigCustomizer { diff --git a/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/package-info.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/package-info.java new file mode 100644 index 000000000000..32896952307b --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Jersey actuator web concerns. + */ +package org.springframework.boot.jersey.autoconfigure.actuate.web; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/metrics/JerseyServerMetricsAutoConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/metrics/JerseyServerMetricsAutoConfiguration.java index 555adbf727ab..a1875362d770 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/metrics/JerseyServerMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.jersey; +package org.springframework.boot.jersey.autoconfigure.metrics; import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.observation.ObservationRegistry; @@ -23,17 +23,16 @@ import org.glassfish.jersey.server.ResourceConfig; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; -import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; +import org.springframework.boot.metrics.OnlyOnceLoggingDenyMeterFilter; +import org.springframework.boot.metrics.autoconfigure.MetricsProperties; +import org.springframework.boot.observation.autoconfigure.ObservationProperties; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; @@ -44,9 +43,9 @@ * @author Michael Simons * @author Andy Wilkinson * @author Moritz Halbritter - * @since 2.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { ObservationAutoConfiguration.class }) +@AutoConfiguration(afterName = "org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass({ ResourceConfig.class, ObservationApplicationEventListener.class }) @ConditionalOnBean({ ResourceConfig.class, ObservationRegistry.class }) diff --git a/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..c59c93782d1a --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Jersey metrics. + */ +package org.springframework.boot.jersey.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/package-info.java b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/package-info.java new file mode 100644 index 000000000000..3cc38ae54b49 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Jersey. + */ +package org.springframework.boot.jersey.autoconfigure; diff --git a/spring-boot-project/spring-boot-jersey/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-jersey/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..fcb89fe94d62 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.jersey.autoconfigure.actuate.web.JerseyChildManagementContextConfiguration +org.springframework.boot.jersey.autoconfigure.actuate.web.JerseyEndpointManagementContextConfiguration +org.springframework.boot.jersey.autoconfigure.actuate.web.JerseySameManagementContextConfiguration +org.springframework.boot.jersey.autoconfigure.actuate.web.JerseyWebEndpointManagementContextConfiguration diff --git a/spring-boot-project/spring-boot-jersey/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-jersey/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..2c4bbf79ba8f --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration +org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web.HealthEndpointJerseyExtensionAutoConfiguration +org.springframework.boot.jersey.autoconfigure.metrics.JerseyServerMetricsAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/JerseyApplicationPathTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyApplicationPathTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/JerseyApplicationPathTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyApplicationPathTests.java index 6ee1b47f8853..b2678e6ad03f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/JerseyApplicationPathTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyApplicationPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.jersey.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomApplicationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomApplicationTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomApplicationTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomApplicationTests.java index b43d01c95c23..a60e47e9feba 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomApplicationTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomApplicationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.GET; @@ -25,10 +25,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -72,7 +72,7 @@ public String message() { } @Configuration(proxyBeanMethods = false) - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) static class TestConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomFilterContextPathTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomFilterContextPathTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomFilterContextPathTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomFilterContextPathTests.java index 079138dc9a4d..67ed83c8c984 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomFilterContextPathTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomFilterContextPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,10 +32,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -91,7 +91,7 @@ static void main(String[] args) { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomFilterPathTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomFilterPathTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomFilterPathTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomFilterPathTests.java index 1ba8f34eb0ed..e318eb8ce6fc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomFilterPathTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomFilterPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,10 +32,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -90,7 +90,7 @@ static void main(String[] args) { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomLoadOnStartupTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomLoadOnStartupTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomLoadOnStartupTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomLoadOnStartupTests.java index a7b20b2d9301..70aed79112ce 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomLoadOnStartupTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomLoadOnStartupTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -27,9 +27,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -67,7 +67,7 @@ static class Application extends ResourceConfig { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ JerseyAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomObjectMapperProviderTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomObjectMapperProviderTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomObjectMapperProviderTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomObjectMapperProviderTests.java index b80879292fcb..ed71b47fffd1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomObjectMapperProviderTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomObjectMapperProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -31,11 +31,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -117,7 +117,7 @@ public void setBody(String body) { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JacksonAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomServletContextPathTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomServletContextPathTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomServletContextPathTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomServletContextPathTests.java index dd2996717da4..4d02a2a9f544 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomServletContextPathTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomServletContextPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,10 +32,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -89,7 +89,7 @@ static void main(String[] args) { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomServletPathTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomServletPathTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomServletPathTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomServletPathTests.java index 083a58f972db..c2da86a63324 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationCustomServletPathTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomServletPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,10 +32,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -89,7 +89,7 @@ static void main(String[] args) { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationDefaultFilterPathTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationDefaultFilterPathTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationDefaultFilterPathTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationDefaultFilterPathTests.java index c2828c5aaa04..6bc3464d5791 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationDefaultFilterPathTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationDefaultFilterPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -31,10 +31,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -88,7 +88,7 @@ static void main(String[] args) { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationDefaultServletPathTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationDefaultServletPathTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationDefaultServletPathTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationDefaultServletPathTests.java index b65983ed8bac..dc4c8472166b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationDefaultServletPathTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationDefaultServletPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -31,10 +31,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -87,7 +87,7 @@ static void main(String[] args) { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationObjectMapperProviderTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationObjectMapperProviderTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationObjectMapperProviderTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationObjectMapperProviderTests.java index c8af1f6420dc..d38c9c3689ca 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationObjectMapperProviderTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationObjectMapperProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,11 +32,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -127,7 +127,7 @@ public String getFoo() { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JacksonAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationServletContainerTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationServletContainerTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationServletContainerTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationServletContainerTests.java index 46854c202b68..5eeab6d99451 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationServletContainerTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationServletContainerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.nio.charset.StandardCharsets; @@ -31,13 +31,13 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfigurationServletContainerTests.Application; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfigurationServletContainerTests.Application; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -62,7 +62,7 @@ void existingJerseyServletIsAmended(CapturedOutput output) { assertThat(output).contains("Servlet " + Application.class.getName() + " was not registered"); } - @ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @ImportAutoConfiguration({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) @Import(ContainerConfiguration.class) @Path("/hello") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationTests.java index d1a852308a5f..475c43df53d4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.util.Collections; @@ -26,8 +26,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration.JerseyWebApplicationInitializer; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration.JerseyWebApplicationInitializer; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationWithoutApplicationPathTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationWithoutApplicationPathTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationWithoutApplicationPathTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationWithoutApplicationPathTests.java index e24fe88c1730..9e29b25a90ca 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationWithoutApplicationPathTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationWithoutApplicationPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jersey; +package org.springframework.boot.jersey.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -31,10 +31,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -87,7 +87,7 @@ static void main(String[] args) { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/HealthEndpointJerseyExtensionAutoConfigurationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/HealthEndpointJerseyExtensionAutoConfigurationTests.java new file mode 100644 index 000000000000..04794f9e1cca --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/HealthEndpointJerseyExtensionAutoConfigurationTests.java @@ -0,0 +1,92 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.WithTestEndpointOutcomeExposureContributor; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.HealthEndpointWebExtension; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; +import org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web.HealthEndpointJerseyExtensionAutoConfiguration.JerseyAdditionalHealthEndpointPathsResourcesRegistrar; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link HealthEndpointJerseyExtensionAutoConfiguration}. + * + * @author Stephane Nicoll + */ +class HealthEndpointJerseyExtensionAutoConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withUserConfiguration(HealthIndicatorsConfiguration.class) + .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + HealthEndpointJerseyExtensionAutoConfiguration.class)); + + @Test + @WithTestEndpointOutcomeExposureContributor + void additionalJerseyHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)) + .withPropertyValues("management.endpoints.web.exposure.exclude=*", + "management.endpoints.test.exposure.include=*") + .run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context).hasSingleBean(HealthEndpoint.class); + assertThat(context).hasSingleBean(HealthEndpointWebExtension.class); + assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty(); + assertThat(context).hasSingleBean(JerseyAdditionalHealthEndpointPathsResourcesRegistrar.class); + }); + } + + @Configuration(proxyBeanMethods = false) + static class HealthIndicatorsConfiguration { + + @Bean + HealthIndicator simpleHealthIndicator() { + return () -> Health.up().withDetail("counter", 42).build(); + } + + @Bean + HealthIndicator additionalHealthIndicator() { + return () -> Health.up().build(); + } + + @Bean + ReactiveHealthIndicator reactiveHealthIndicator() { + return () -> Mono.just(Health.up().build()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyEndpointAccessIntegrationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointAccessIntegrationTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyEndpointAccessIntegrationTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointAccessIntegrationTests.java index 12b74ef899e0..5c55a6ec78e5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JerseyEndpointAccessIntegrationTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointAccessIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integrationtest; +package org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web; import java.io.IOException; import java.time.Duration; @@ -31,20 +31,18 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.EntityExchangeResult; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.reactive.function.client.ExchangeStrategies; -import org.springframework.web.servlet.DispatcherServlet; import static org.assertj.core.api.Assertions.assertThat; @@ -58,10 +56,9 @@ class JerseyEndpointAccessIntegrationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, - EndpointAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class, + EndpointAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(DispatcherServlet.class)) .withUserConfiguration(CustomServletEndpoint.class) .withPropertyValues("server.port:0"); diff --git a/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java new file mode 100644 index 000000000000..a0acedb931a8 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java @@ -0,0 +1,228 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; +import org.glassfish.jersey.server.ResourceConfig; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.web.reactive.server.WebTestClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for the Jersey actuator endpoints. + * + * @author Andy Wilkinson + * @author Madhura Bhave + */ +class JerseyEndpointIntegrationTests { + + @Test + void linksAreProvidedToAllEndpointTypes() { + testJerseyEndpoints(new Class[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class }); + } + + @Test + void linksPageIsNotAvailableWhenDisabled() { + getContextRunner(new Class[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class }) + .withPropertyValues("management.endpoints.web.discovery.enabled:false") + .run((context) -> { + int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) + .getWebServer() + .getPort(); + WebTestClient client = WebTestClient.bindToServer() + .baseUrl("http://localhost:" + port) + .responseTimeout(Duration.ofMinutes(5)) + .build(); + client.get().uri("/actuator").exchange().expectStatus().isNotFound(); + }); + } + + @Test + void actuatorEndpointsWhenUserProvidedResourceConfigBeanNotAvailable() { + testJerseyEndpoints(new Class[] { EndpointsConfiguration.class }); + } + + @Test + void endpointObjectMapperCanBeApplied() { + WebApplicationContextRunner contextRunner = getContextRunner(new Class[] { EndpointsConfiguration.class, + ResourceConfigConfiguration.class, EndpointObjectMapperConfiguration.class }); + contextRunner.run((context) -> { + int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) + .getWebServer() + .getPort(); + WebTestClient client = WebTestClient.bindToServer() + .baseUrl("http://localhost:" + port) + .responseTimeout(Duration.ofMinutes(5)) + .build(); + client.get().uri("/actuator/beans").exchange().expectStatus().isOk().expectBody().consumeWith((result) -> { + String json = new String(result.getResponseBody(), StandardCharsets.UTF_8); + assertThat(json).contains("\"scope\":\"notelgnis\""); + }); + }); + } + + protected void testJerseyEndpoints(Class[] userConfigurations) { + getContextRunner(userConfigurations).run((context) -> { + int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) + .getWebServer() + .getPort(); + WebTestClient client = WebTestClient.bindToServer() + .baseUrl("http://localhost:" + port) + .responseTimeout(Duration.ofMinutes(5)) + .build(); + client.get() + .uri("/actuator") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("_links.beans") + .isNotEmpty() + .jsonPath("_links.restcontroller") + .doesNotExist() + .jsonPath("_links.controller") + .doesNotExist(); + }); + } + + WebApplicationContextRunner getContextRunner(Class[] userConfigurations, + Class... additionalAutoConfigurations) { + return new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(getAutoconfigurations(additionalAutoConfigurations))) + .withUserConfiguration(userConfigurations) + .withPropertyValues("management.endpoints.web.exposure.include:*", "server.port:0"); + } + + private Class[] getAutoconfigurations(Class... additional) { + List> autoconfigurations = new ArrayList<>(Arrays.asList(JacksonAutoConfiguration.class, + JerseyAutoConfiguration.class, EndpointAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, WebEndpointAutoConfiguration.class, + ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)); + autoconfigurations.addAll(Arrays.asList(additional)); + return autoconfigurations.toArray(new Class[0]); + } + + @org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint(id = "controller") + @SuppressWarnings("removal") + static class TestControllerEndpoint { + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "restcontroller") + @SuppressWarnings("removal") + static class TestRestControllerEndpoint { + + } + + @Configuration(proxyBeanMethods = false) + static class EndpointsConfiguration { + + @Bean + TestControllerEndpoint testControllerEndpoint() { + return new TestControllerEndpoint(); + } + + @Bean + TestRestControllerEndpoint testRestControllerEndpoint() { + return new TestRestControllerEndpoint(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ResourceConfigConfiguration { + + @Bean + ResourceConfig testResourceConfig() { + return new ResourceConfig(); + } + + } + + @Configuration + @SuppressWarnings({ "deprecation", "removal" }) + static class EndpointObjectMapperConfiguration { + + @Bean + EndpointObjectMapper endpointObjectMapper() { + SimpleModule module = new SimpleModule(); + module.addSerializer(String.class, new ReverseStringSerializer()); + ObjectMapper objectMapper = org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.json() + .modules(module) + .build(); + return () -> objectMapper; + } + + static class ReverseStringSerializer extends StdScalarSerializer { + + ReverseStringSerializer() { + super(String.class, false); + } + + @Override + public boolean isEmpty(SerializerProvider prov, Object value) { + return ((String) value).isEmpty(); + } + + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException { + serialize(value, gen); + } + + @Override + public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, + TypeSerializer typeSer) throws IOException { + serialize(value, gen); + } + + private void serialize(Object value, JsonGenerator gen) throws IOException { + StringBuilder builder = new StringBuilder((String) value); + gen.writeString(builder.reverse().toString()); + } + + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyChildManagementContextConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfigurationTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyChildManagementContextConfigurationTests.java index 01f3667b3a19..c9722f9d1e1a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyChildManagementContextConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.jersey; +package org.springframework.boot.jersey.autoconfigure.actuate.web; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyEndpointManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyEndpointManagementContextConfigurationTests.java new file mode 100644 index 000000000000..a7c3cd17a83d --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyEndpointManagementContextConfigurationTests.java @@ -0,0 +1,86 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure.actuate.web; + +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; +import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar; +import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JerseyEndpointManagementContextConfiguration}. + * + * @author Stephane Nicoll + */ +@SuppressWarnings("removal") +class JerseyEndpointManagementContextConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withUserConfiguration(TestConfig.class); + + @Test + void contextShouldContainServletEndpointRegistrar() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ServletEndpointRegistrar.class); + ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class); + assertThat(bean).hasFieldOrPropertyWithValue("basePath", "/test/actuator"); + }); + } + + @Test + void contextWhenNotServletBasedShouldNotContainServletEndpointRegistrar() { + new ApplicationContextRunner().withUserConfiguration(TestConfig.class) + .run((context) -> assertThat(context).doesNotHaveBean(ServletEndpointRegistrar.class)); + } + + @Configuration(proxyBeanMethods = false) + @Import(JerseyEndpointManagementContextConfiguration.class) + @EnableConfigurationProperties(WebEndpointProperties.class) + static class TestConfig { + + @Bean + ServletEndpointsSupplier servletEndpointsSupplier() { + return Collections::emptyList; + } + + @Bean + JerseyApplicationPath jerseyApplicationPath() { + return () -> "/test"; + } + + @Bean + EndpointAccessResolver endpointAccessResolver() { + return (endpointId, defaultAccess) -> Access.UNRESTRICTED; + } + + } + +} diff --git a/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyHealthEndpointAdditionalPathIntegrationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyHealthEndpointAdditionalPathIntegrationTests.java new file mode 100644 index 000000000000..59f3f3e607d4 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyHealthEndpointAdditionalPathIntegrationTests.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure.actuate.web; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.integrationtest.AbstractHealthEndpointAdditionalPathIntegrationTests; +import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web.HealthEndpointJerseyExtensionAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatServletManagementContextAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.web.context.ConfigurableWebApplicationContext; + +/** + * Integration tests for health groups on an additional path on Jersey. + * + * @author Madhura Bhave + */ +class JerseyHealthEndpointAdditionalPathIntegrationTests extends + AbstractHealthEndpointAdditionalPathIntegrationTests { + + JerseyHealthEndpointAdditionalPathIntegrationTests() { + super(new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, + EndpointAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, + TomcatServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, + JerseyAutoConfiguration.class, ManagementContextAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, + HealthEndpointJerseyExtensionAutoConfiguration.class, + DiskSpaceHealthContributorAutoConfiguration.class)) + .withInitializer(new ServerPortInfoApplicationContextInitializer()) + .withPropertyValues("server.port=0")); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseySameManagementContextConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfigurationTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseySameManagementContextConfigurationTests.java index 32987db46212..88be8c9858bc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseySameManagementContextConfigurationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.jersey; +package org.springframework.boot.jersey.autoconfigure.actuate.web; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.DefaultJerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointIntegrationTests.java new file mode 100644 index 000000000000..225ab84227a9 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointIntegrationTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure.actuate.web; + +import java.util.Set; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.Resource; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for web endpoints running on Jersey. + * + * @author Andy Wilkinson + */ +class JerseyWebEndpointIntegrationTests { + + @Test + void whenJerseyIsConfiguredToUseAFilterThenResourceRegistrationSucceeds() { + new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration( + AutoConfigurations.of(JerseySameManagementContextConfiguration.class, JerseyAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, EndpointAutoConfiguration.class, + WebEndpointAutoConfiguration.class, JerseyWebEndpointManagementContextConfiguration.class)) + .withUserConfiguration(ResourceConfigConfiguration.class) + .withPropertyValues("spring.jersey.type=filter", "server.port=0") + .run((context) -> { + assertThat(context).hasNotFailed(); + Set resources = context.getBean(ResourceConfig.class).getResources(); + assertThat(resources).hasSize(1); + Resource resource = resources.iterator().next(); + assertThat(resource.getPath()).isEqualTo("/actuator"); + }); + } + + @Configuration(proxyBeanMethods = false) + static class ResourceConfigConfiguration { + + @Bean + ResourceConfig resourceConfig() { + return new ResourceConfig(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfigurationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfigurationTests.java rename to spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfigurationTests.java index a1960b85af96..972dfadb32f3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey; +package org.springframework.boot.jersey.autoconfigure.actuate.web; import java.util.Collections; @@ -22,12 +22,11 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration.JerseyWebEndpointsResourcesRegistrar; -import org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration; import org.springframework.boot.actuate.endpoint.Access; import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jersey.autoconfigure.actuate.web.JerseyWebEndpointManagementContextConfiguration.JerseyWebEndpointsResourcesRegistrar; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/metrics/JerseyServerMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/metrics/JerseyServerMetricsAutoConfigurationTests.java new file mode 100644 index 000000000000..fea7960bd320 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/metrics/JerseyServerMetricsAutoConfigurationTests.java @@ -0,0 +1,143 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure.metrics; + +import java.net.URI; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Timer; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.Observation.Context; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import org.glassfish.jersey.micrometer.server.ObservationApplicationEventListener; +import org.glassfish.jersey.server.ResourceConfig; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JerseyServerMetricsAutoConfiguration}. + * + * @author Michael Weirauch + * @author Michael Simons + * @author Moritz Halbritter + */ +class JerseyServerMetricsAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(JerseyServerMetricsAutoConfiguration.class)); + + private final WebApplicationContextRunner webContextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(JerseyAutoConfiguration.class, + JerseyServerMetricsAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class, + ObservationAutoConfiguration.class, MetricsAutoConfiguration.class)) + .withUserConfiguration(ResourceConfiguration.class) + .withPropertyValues("server.port:0"); + + @Test + void shouldOnlyBeActiveInWebApplicationContext() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ResourceConfigCustomizer.class)); + } + + @Test + void shouldProvideAllNecessaryBeans() { + this.webContextRunner.run((context) -> assertThat(context).hasBean("jerseyMetricsUriTagFilter") + .hasSingleBean(ResourceConfigCustomizer.class)); + } + + @Test + void httpRequestsAreTimed() { + this.webContextRunner.withUserConfiguration(MetricsConfiguration.class).run((context) -> { + doRequest(context); + Thread.sleep(500); + MeterRegistry registry = context.getBean(MeterRegistry.class); + Timer timer = registry.get("http.server.requests").tag("uri", "/users/{id}").timer(); + assertThat(timer.count()).isOne(); + }); + } + + @Test + void noHttpRequestsTimedWhenJerseyInstrumentationMissingFromClasspath() { + this.webContextRunner.withClassLoader(new FilteredClassLoader(ObservationApplicationEventListener.class)) + .run((context) -> { + doRequest(context); + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry.find("http.server.requests").timer()).isNull(); + }); + } + + private static void doRequest(AssertableWebApplicationContext context) { + int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) + .getWebServer() + .getPort(); + RestTemplate restTemplate = new RestTemplate(); + restTemplate.getForEntity(URI.create("http://localhost:" + port + "/users/3"), String.class); + } + + @Configuration(proxyBeanMethods = false) + static class ResourceConfiguration { + + @Bean + ResourceConfig resourceConfig() { + return new ResourceConfig().register(new TestResource()); + } + + @Path("/users") + public static class TestResource { + + @GET + @Path("/{id}") + public String getUser(@PathParam("id") String id) { + return id; + } + + } + + } + + @Configuration(proxyBeanMethods = false) + static class MetricsConfiguration { + + @Bean + MeterObservationHandler meterObservationHandler(MeterRegistry registry) { + return new DefaultMeterObservationHandler(registry); + } + + } + +} diff --git a/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java b/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java new file mode 100644 index 000000000000..5725622984d1 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.actuate.endpoint.web.test; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.Resource; + +import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; +import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Endpoint configuration for Jersey. + * + * @author Andy Wilkinson + * @author Stephane Nicoll + */ +@Configuration(proxyBeanMethods = false) +@ImportAutoConfiguration({ JacksonAutoConfiguration.class, JerseyAutoConfiguration.class }) +class JerseyEndpointConfiguration { + + private final ApplicationContext applicationContext; + + JerseyEndpointConfiguration(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Bean + TomcatServletWebServerFactory tomcat() { + return new TomcatServletWebServerFactory(0); + } + + @Bean + ResourceConfig resourceConfig() { + return new ResourceConfig(); + } + + @Bean + ResourceConfigCustomizer webEndpointRegistrar() { + return this::customize; + } + + private void customize(ResourceConfig config) { + EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; + WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, + new ConversionServiceParameterValueMapper(), endpointMediaTypes, null, Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( + new EndpointMapping("/actuator"), discoverer.getEndpoints(), endpointMediaTypes, + new EndpointLinksResolver(discoverer.getEndpoints()), true); + config.registerResources(new HashSet<>(resources)); + } + +} diff --git a/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyWebEndpointInfrastructureProvider.java b/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyWebEndpointInfrastructureProvider.java new file mode 100644 index 000000000000..8458d64032cf --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyWebEndpointInfrastructureProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.actuate.endpoint.web.test; + +import java.util.List; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider; +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; + +/** + * {@link WebEndpointInfrastructureProvider} for Jersey. + * + * @author Stephane Nicoll + */ +class JerseyWebEndpointInfrastructureProvider implements WebEndpointInfrastructureProvider { + + @Override + public boolean supports(Infrastructure infrastructure) { + return infrastructure == Infrastructure.JERSEY; + } + + @Override + public List> getInfrastructureConfiguration(Infrastructure infrastructure) { + return List.of(JerseyEndpointConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-jersey/src/testFixtures/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-jersey/src/testFixtures/resources/META-INF/spring.factories new file mode 100644 index 000000000000..7163b1dad5d3 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/testFixtures/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider=\ +org.springframework.boot.jersey.actuate.endpoint.web.test.JerseyWebEndpointInfrastructureProvider diff --git a/spring-boot-project/spring-boot-jetty/build.gradle b/spring-boot-project/spring-boot-jetty/build.gradle new file mode 100644 index 000000000000..dfbf4536b968 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/build.gradle @@ -0,0 +1,61 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Jetty" + +dependencies { + api(project(":spring-boot-project:spring-boot-web-server")) + api("org.eclipse.jetty.ee10:jetty-ee10-servlets") + api("org.eclipse.jetty.ee10:jetty-ee10-webapp") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional("org.apache.tomcat.embed:tomcat-embed-jasper") + optional("org.eclipse.jetty:jetty-alpn-conscrypt-server") + optional("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server") + optional("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server") + optional("org.eclipse.jetty.http2:jetty-http2-server") + optional("org.springframework:spring-webflux") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("org.apache.httpcomponents.client5:httpclient5") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("io.projectreactor:reactor-test") + testRuntimeOnly("io.projectreactor.netty:reactor-netty-http") + testRuntimeOnly("org.eclipse.jetty:jetty-client") + testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client") + testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client-transport") + testRuntimeOnly("org.springframework:spring-webmvc") +} + +test { + jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" +} + diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ConfigurableJettyWebServerFactory.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/ConfigurableJettyWebServerFactory.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ConfigurableJettyWebServerFactory.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/ConfigurableJettyWebServerFactory.java index 9f47fc52c21a..ffcc3d07f1f4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ConfigurableJettyWebServerFactory.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/ConfigurableJettyWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.thread.ThreadPool; @@ -26,9 +26,7 @@ * * @author Brian Clozel * @author Moritz Halbritter - * @since 2.0.0 - * @see JettyServletWebServerFactory - * @see JettyReactiveWebServerFactory + * @since 4.0.0 */ public interface ConfigurableJettyWebServerFactory extends ConfigurableWebServerFactory { @@ -67,7 +65,7 @@ public interface ConfigurableJettyWebServerFactory extends ConfigurableWebServer /** * Sets the maximum number of concurrent connections. * @param maxConnections the maximum number of concurrent connections - * @since 3.2.0 + * @since 4.0.0 */ void setMaxConnections(int maxConnections); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ForwardHeadersCustomizer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/ForwardHeadersCustomizer.java similarity index 91% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ForwardHeadersCustomizer.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/ForwardHeadersCustomizer.java index 40a0c3fbe1db..c1394ddcd061 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ForwardHeadersCustomizer.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/ForwardHeadersCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty; import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; @@ -26,8 +26,9 @@ * {@link JettyServerCustomizer} to add {@link ForwardedRequestCustomizer}. * * @author Phillip Webb + * @since 4.0.0 */ -class ForwardHeadersCustomizer implements JettyServerCustomizer { +public class ForwardHeadersCustomizer implements JettyServerCustomizer { @Override public void customize(Server server) { diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/GracefulShutdown.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/GracefulShutdown.java new file mode 100644 index 000000000000..da378e38ff3d --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/GracefulShutdown.java @@ -0,0 +1,124 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty; + +import java.lang.reflect.Method; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.function.Supplier; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Server; + +import org.springframework.boot.web.server.GracefulShutdownCallback; +import org.springframework.boot.web.server.GracefulShutdownResult; +import org.springframework.util.ReflectionUtils; + +/** + * Handles Jetty graceful shutdown. + * + * @author Andy Wilkinson + * @author Onur Kagan Ozcan + */ +final class GracefulShutdown { + + private static final Log logger = LogFactory.getLog(GracefulShutdown.class); + + private final Server server; + + private final Supplier activeRequests; + + private volatile boolean aborted = false; + + GracefulShutdown(Server server, Supplier activeRequests) { + this.server = server; + this.activeRequests = activeRequests; + } + + void shutDownGracefully(GracefulShutdownCallback callback) { + logger.info("Commencing graceful shutdown. Waiting for active requests to complete"); + new Thread(() -> awaitShutdown(callback), "jetty-shutdown").start(); + boolean jetty10 = isJetty10(); + for (Connector connector : this.server.getConnectors()) { + shutdown(connector, !jetty10); + } + + } + + @SuppressWarnings("unchecked") + private void shutdown(Connector connector, boolean getResult) { + Future result; + try { + result = connector.shutdown(); + } + catch (NoSuchMethodError ex) { + Method shutdown = ReflectionUtils.findMethod(connector.getClass(), "shutdown"); + result = (Future) ReflectionUtils.invokeMethod(shutdown, connector); + } + if (getResult) { + try { + result.get(); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + catch (ExecutionException ex) { + // Continue + } + } + } + + private boolean isJetty10() { + try { + return CompletableFuture.class.equals(Connector.class.getMethod("shutdown").getReturnType()); + } + catch (Exception ex) { + return false; + } + } + + private void awaitShutdown(GracefulShutdownCallback callback) { + while (!this.aborted && this.activeRequests.get() > 0) { + sleep(100); + } + if (this.aborted) { + logger.info("Graceful shutdown aborted with one or more requests still active"); + callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE); + } + else { + logger.info("Graceful shutdown complete"); + callback.shutdownComplete(GracefulShutdownResult.IDLE); + } + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + + void abort() { + this.aborted = true; + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyHandlerWrappers.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyHandlerWrappers.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyHandlerWrappers.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyHandlerWrappers.java index c8f20ba67058..7866924af091 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyHandlerWrappers.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyHandlerWrappers.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty; import org.eclipse.jetty.http.HttpFields.Mutable; import org.eclipse.jetty.http.HttpMethod; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServerCustomizer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyServerCustomizer.java similarity index 88% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServerCustomizer.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyServerCustomizer.java index 207129a02b33..c310dce5a039 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServerCustomizer.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyServerCustomizer.java @@ -14,15 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty; import org.eclipse.jetty.server.Server; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; + /** * Callback interface that can be used to customize a Jetty {@link Server}. * * @author Dave Syer - * @since 2.0.0 + * @since 4.0.0 * @see JettyServletWebServerFactory */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyWebServer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyWebServer.java similarity index 85% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyWebServer.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyWebServer.java index 966007dd5d88..480bc46c49a1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyWebServer.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyWebServer.java @@ -14,15 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.ServletHolder; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.NetworkConnector; @@ -30,12 +33,13 @@ import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.StatisticsHandler; +import org.springframework.boot.jetty.reactive.JettyReactiveWebServerFactory; import org.springframework.boot.web.server.GracefulShutdownCallback; import org.springframework.boot.web.server.GracefulShutdownResult; import org.springframework.boot.web.server.PortInUseException; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.WebServerException; -import org.springframework.boot.web.server.WebServerFactory; +import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -48,7 +52,7 @@ * @author Eddú Meléndez * @author Brian Clozel * @author Kristine Jetzke - * @since 2.0.0 + * @since 4.0.0 * @see JettyReactiveWebServerFactory */ public class JettyWebServer implements WebServer { @@ -150,9 +154,7 @@ public void start() throws WebServerException { } try { this.server.start(); - for (Handler handler : this.server.getHandlers()) { - handleDeferredInitialize(handler); - } + handleDeferredInitialize(this.server); Connector[] connectors = this.server.getConnectors(); for (Connector connector : connectors) { try { @@ -208,15 +210,16 @@ private String getProtocols(Connector connector) { } private String getContextPath() { - if (JettyReactiveWebServerFactory.class.equals(this.server.getAttribute(WebServerFactory.class.getName()))) { - return null; - } - return this.server.getHandlers() + List imperativeContextHandlers = this.server.getHandlers() .stream() .map(this::findContextHandler) .filter(Objects::nonNull) - .map(ContextHandler::getContextPath) - .collect(Collectors.joining(" ")); + .filter(this::isImperative) + .toList(); + if (imperativeContextHandlers.isEmpty()) { + return null; + } + return imperativeContextHandlers.stream().map(ContextHandler::getContextPath).collect(Collectors.joining(" ")); } private ContextHandler findContextHandler(Handler handler) { @@ -229,22 +232,26 @@ private ContextHandler findContextHandler(Handler handler) { return null; } - private void handleDeferredInitialize(List handlers) throws Exception { - for (Handler handler : handlers) { - handleDeferredInitialize(handler); + private boolean isImperative(ContextHandler contextHandler) { + if (contextHandler instanceof ServletContextHandler servletContextHandler) { + Collection servletHolders = servletContextHandler.getServletHandler() + .getBeans(ServletHolder.class); + for (ServletHolder servletHolder : servletHolders) { + if (ServletHttpHandlerAdapter.class.getName().equals(servletHolder.getClassName())) { + return false; + } + } } + return true; } - private void handleDeferredInitialize(Handler handler) throws Exception { - if (handler instanceof JettyEmbeddedWebAppContext jettyEmbeddedWebAppContext) { - jettyEmbeddedWebAppContext.deferredInitialize(); - } - else if (handler instanceof Handler.Wrapper handlerWrapper) { - handleDeferredInitialize(handlerWrapper.getHandler()); - } - else if (handler instanceof Handler.Collection handlerCollection) { - handleDeferredInitialize(handlerCollection.getHandlers()); - } + /** + * Performs any necessary handling of deferred initialization. + * @param server the server that has been started + * @throws Exception if a failure occurs during the deferred initialization + */ + protected void handleDeferredInitialize(Server server) throws Exception { + } @Override diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyWebServerFactory.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyWebServerFactory.java new file mode 100644 index 000000000000..eb5e3dff8fcb --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyWebServerFactory.java @@ -0,0 +1,222 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executor; + +import org.eclipse.jetty.ee10.webapp.Configuration; +import org.eclipse.jetty.ee10.webapp.WebAppContext; +import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.server.AbstractConnector; +import org.eclipse.jetty.server.ConnectionFactory; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.ThreadPool; + +import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Base class for factories that produce a {@link JettyWebServer}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class JettyWebServerFactory extends AbstractConfigurableWebServerFactory + implements ConfigurableJettyWebServerFactory { + + private int acceptors = -1; + + private ThreadPool threadPool; + + private int selectors = -1; + + private List configurations = new ArrayList<>(); + + private boolean useForwardHeaders; + + private Set jettyServerCustomizers = new LinkedHashSet<>(); + + private int maxConnections = -1; + + public JettyWebServerFactory() { + + } + + public JettyWebServerFactory(int port) { + super(port); + } + + public int getAcceptors() { + return this.acceptors; + } + + @Override + public void setAcceptors(int acceptors) { + this.acceptors = acceptors; + } + + public int getSelectors() { + return this.selectors; + } + + @Override + public void setSelectors(int selectors) { + this.selectors = selectors; + } + + public int getMaxConnections() { + return this.maxConnections; + } + + @Override + public void setMaxConnections(int maxConnections) { + this.maxConnections = maxConnections; + } + + /** + * Returns a mutable collection of Jetty {@link JettyServerCustomizer}s that will be + * applied to the {@link Server} before it is created. + * @return the {@link JettyServerCustomizer}s + */ + public Collection getServerCustomizers() { + return this.jettyServerCustomizers; + } + + /** + * Sets {@link JettyServerCustomizer}s that will be applied to the {@link Server} + * before it is started. Calling this method will replace any existing customizers. + * @param customizers the Jetty customizers to apply + */ + public void setServerCustomizers(Collection customizers) { + Assert.notNull(customizers, "'customizers' must not be null"); + this.jettyServerCustomizers = new LinkedHashSet<>(customizers); + } + + @Override + public void addServerCustomizers(JettyServerCustomizer... customizers) { + Assert.notNull(customizers, "'customizers' must not be null"); + this.jettyServerCustomizers.addAll(Arrays.asList(customizers)); + } + + /** + * Returns a mutable collection of Jetty {@link Configuration}s that will be applied + * to the {@link WebAppContext} before the server is created. + * @return the Jetty {@link Configuration}s + */ + public Collection getConfigurations() { + return this.configurations; + } + + /** + * Sets Jetty {@link Configuration}s that will be applied to the {@link WebAppContext} + * before the server is created. Calling this method will replace any existing + * configurations. + * @param configurations the Jetty configurations to apply + */ + public void setConfigurations(Collection configurations) { + Assert.notNull(configurations, "'configurations' must not be null"); + this.configurations = new ArrayList<>(configurations); + } + + /** + * Add {@link Configuration}s that will be applied to the {@link WebAppContext} before + * the server is started. + * @param configurations the configurations to add + */ + public void addConfigurations(Configuration... configurations) { + Assert.notNull(configurations, "'configurations' must not be null"); + this.configurations.addAll(Arrays.asList(configurations)); + } + + /** + * Returns a Jetty {@link ThreadPool} that should be used by the {@link Server}. + * @return a Jetty {@link ThreadPool} or {@code null} + */ + public ThreadPool getThreadPool() { + return this.threadPool; + } + + @Override + public void setThreadPool(ThreadPool threadPool) { + this.threadPool = threadPool; + } + + public boolean isUseForwardHeaders() { + return this.useForwardHeaders; + } + + @Override + public void setUseForwardHeaders(boolean useForwardHeaders) { + this.useForwardHeaders = useForwardHeaders; + } + + protected AbstractConnector createConnector(InetSocketAddress address, Server server) { + return this.createConnector(address, server, null, null, null); + } + + protected AbstractConnector createConnector(InetSocketAddress address, Server server, Executor executor, + Scheduler scheduler, ByteBufferPool pool) { + HttpConfiguration httpConfiguration = new HttpConfiguration(); + httpConfiguration.setSendServerVersion(false); + List connectionFactories = new ArrayList<>(); + connectionFactories.add(new HttpConnectionFactory(httpConfiguration)); + if (getHttp2() != null && getHttp2().isEnabled()) { + connectionFactories.add(new HTTP2CServerConnectionFactory(httpConfiguration)); + } + ServerConnector connector = new ServerConnector(server, executor, scheduler, pool, this.getAcceptors(), + this.getSelectors(), connectionFactories.toArray(new ConnectionFactory[0])); + + connector.setHost(address.getHostString()); + connector.setPort(address.getPort()); + return connector; + } + + protected void customizeSsl(Server server, InetSocketAddress address) { + Assert.state(getSsl().getServerNameBundles().isEmpty(), "Server name SSL bundles are not supported with Jetty"); + new SslServerCustomizer(getHttp2(), address, getSsl().getClientAuth(), getSslBundle()).customize(server); + } + + protected Handler addHandlerWrappers(Handler handler) { + if (getCompression() != null && getCompression().getEnabled()) { + handler = applyWrapper(handler, JettyHandlerWrappers.createGzipHandlerWrapper(getCompression())); + } + if (StringUtils.hasText(getServerHeader())) { + handler = applyWrapper(handler, JettyHandlerWrappers.createServerHeaderHandlerWrapper(getServerHeader())); + } + return handler; + } + + protected Handler applyWrapper(Handler handler, Handler.Wrapper wrapper) { + wrapper.setHandler(handler); + return wrapper; + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/SslServerCustomizer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/SslServerCustomizer.java new file mode 100644 index 000000000000..8cf0287434a8 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/SslServerCustomizer.java @@ -0,0 +1,225 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty; + +import java.net.InetSocketAddress; + +import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http2.HTTP2Cipher; +import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; +import org.eclipse.jetty.server.ConnectionFactory; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.SecureRequestCustomizer; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.util.ssl.SslContextFactory; + +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.ssl.SslBundleKey; +import org.springframework.boot.ssl.SslOptions; +import org.springframework.boot.ssl.SslStoreBundle; +import org.springframework.boot.web.server.Http2; +import org.springframework.boot.web.server.Ssl.ClientAuth; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +/** + * {@link JettyServerCustomizer} that configures SSL on the given Jetty server instance. + * + * @author Brian Clozel + * @author Olivier Lamy + * @author Chris Bono + * @author Cyril Dangerville + * @author Scott Frederick + */ +class SslServerCustomizer implements JettyServerCustomizer { + + private final Http2 http2; + + private final InetSocketAddress address; + + private final ClientAuth clientAuth; + + private final SslBundle sslBundle; + + SslServerCustomizer(Http2 http2, InetSocketAddress address, ClientAuth clientAuth, SslBundle sslBundle) { + this.address = address; + this.clientAuth = clientAuth; + this.sslBundle = sslBundle; + this.http2 = http2; + } + + @Override + public void customize(Server server) { + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setEndpointIdentificationAlgorithm(null); + configureSsl(sslContextFactory, this.clientAuth); + ServerConnector connector = createConnector(server, sslContextFactory); + server.setConnectors(new Connector[] { connector }); + } + + private ServerConnector createConnector(Server server, SslContextFactory.Server sslContextFactory) { + HttpConfiguration config = new HttpConfiguration(); + config.setSendServerVersion(false); + config.setSecureScheme("https"); + config.setSecurePort(this.address.getPort()); + config.addCustomizer(new SecureRequestCustomizer()); + ServerConnector connector = createServerConnector(server, sslContextFactory, config); + connector.setPort(this.address.getPort()); + connector.setHost(this.address.getHostString()); + return connector; + } + + private ServerConnector createServerConnector(Server server, SslContextFactory.Server sslContextFactory, + HttpConfiguration config) { + if (this.http2 == null || !this.http2.isEnabled()) { + return createHttp11ServerConnector(config, sslContextFactory, server); + } + Assert.state(isJettyAlpnPresent(), + () -> "An 'org.eclipse.jetty:jetty-alpn-*-server' dependency is required for HTTP/2 support."); + Assert.state(isJettyHttp2Present(), + () -> "The 'org.eclipse.jetty.http2:jetty-http2-server' dependency is required for HTTP/2 support."); + return createHttp2ServerConnector(config, sslContextFactory, server); + } + + private ServerConnector createHttp11ServerConnector(HttpConfiguration config, + SslContextFactory.Server sslContextFactory, Server server) { + SslConnectionFactory sslConnectionFactory = createSslConnectionFactory(sslContextFactory, + HttpVersion.HTTP_1_1.asString()); + HttpConnectionFactory connectionFactory = new HttpConnectionFactory(config); + return new SslValidatingServerConnector(this.sslBundle.getKey(), sslContextFactory, server, + sslConnectionFactory, connectionFactory); + } + + private SslConnectionFactory createSslConnectionFactory(SslContextFactory.Server sslContextFactory, + String protocol) { + return new SslConnectionFactory(sslContextFactory, protocol); + } + + private boolean isJettyAlpnPresent() { + return ClassUtils.isPresent("org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory", null); + } + + private boolean isJettyHttp2Present() { + return ClassUtils.isPresent("org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory", null); + } + + private ServerConnector createHttp2ServerConnector(HttpConfiguration config, + SslContextFactory.Server sslContextFactory, Server server) { + HttpConnectionFactory http = new HttpConnectionFactory(config); + HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(config); + ALPNServerConnectionFactory alpn = createAlpnServerConnectionFactory(); + sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); + if (isConscryptPresent()) { + sslContextFactory.setProvider("Conscrypt"); + } + SslConnectionFactory sslConnectionFactory = createSslConnectionFactory(sslContextFactory, alpn.getProtocol()); + return new SslValidatingServerConnector(this.sslBundle.getKey(), sslContextFactory, server, + sslConnectionFactory, alpn, h2, http); + } + + private ALPNServerConnectionFactory createAlpnServerConnectionFactory() { + try { + return new ALPNServerConnectionFactory(); + } + catch (IllegalStateException ex) { + throw new IllegalStateException( + "An 'org.eclipse.jetty:jetty-alpn-*-server' dependency is required for HTTP/2 support.", ex); + } + } + + private boolean isConscryptPresent() { + return ClassUtils.isPresent("org.conscrypt.Conscrypt", null) + && ClassUtils.isPresent("org.eclipse.jetty.alpn.conscrypt.server.ConscryptServerALPNProcessor", null); + } + + /** + * Configure the SSL connection. + * @param factory the Jetty {@link Server SslContextFactory.Server}. + * @param clientAuth the client authentication mode + */ + protected void configureSsl(SslContextFactory.Server factory, ClientAuth clientAuth) { + SslBundleKey key = this.sslBundle.getKey(); + SslOptions options = this.sslBundle.getOptions(); + SslStoreBundle stores = this.sslBundle.getStores(); + factory.setProtocol(this.sslBundle.getProtocol()); + configureSslClientAuth(factory, clientAuth); + if (stores.getKeyStorePassword() != null) { + factory.setKeyStorePassword(stores.getKeyStorePassword()); + } + factory.setCertAlias(key.getAlias()); + if (options.getCiphers() != null) { + factory.setIncludeCipherSuites(options.getCiphers()); + factory.setExcludeCipherSuites(); + } + if (options.getEnabledProtocols() != null) { + factory.setIncludeProtocols(options.getEnabledProtocols()); + factory.setExcludeProtocols(); + } + try { + if (key.getPassword() != null) { + factory.setKeyManagerPassword(key.getPassword()); + } + factory.setKeyStore(stores.getKeyStore()); + factory.setTrustStore(stores.getTrustStore()); + } + catch (Exception ex) { + throw new IllegalStateException("Unable to set SSL store: " + ex.getMessage(), ex); + } + } + + private void configureSslClientAuth(SslContextFactory.Server factory, ClientAuth clientAuth) { + factory.setWantClientAuth(clientAuth == ClientAuth.WANT || clientAuth == ClientAuth.NEED); + factory.setNeedClientAuth(clientAuth == ClientAuth.NEED); + } + + /** + * A {@link ServerConnector} that validates the ssl key alias on server startup. + */ + static class SslValidatingServerConnector extends ServerConnector { + + private final SslBundleKey key; + + private final SslContextFactory sslContextFactory; + + SslValidatingServerConnector(SslBundleKey key, SslContextFactory sslContextFactory, Server server, + SslConnectionFactory sslConnectionFactory, HttpConnectionFactory connectionFactory) { + super(server, sslConnectionFactory, connectionFactory); + this.key = key; + this.sslContextFactory = sslContextFactory; + } + + SslValidatingServerConnector(SslBundleKey keyAlias, SslContextFactory sslContextFactory, Server server, + ConnectionFactory... factories) { + super(server, factories); + this.key = keyAlias; + this.sslContextFactory = sslContextFactory; + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + this.key.assertContainsAlias(this.sslContextFactory.getKeyStore()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyServerProperties.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyServerProperties.java new file mode 100644 index 000000000000..0ac0d02d8beb --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyServerProperties.java @@ -0,0 +1,359 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure; + +import java.time.Duration; +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.unit.DataSize; + +/** + * Jetty server properties. + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Ivan Sopov + * @author Marcos Barbero + * @author Eddú Meléndez + * @author Quinten De Swaef + * @author Venil Noronha + * @author Aurélien Leboulanger + * @author Brian Clozel + * @author Olivier Lamy + * @author Chentao Qu + * @author Artsiom Yudovin + * @author Andrew McGhie + * @author Rafiullah Hamedy + * @author Dirk Deyne + * @author HaiTao Zhang + * @author Victor Mandujano + * @author Chris Bono + * @author Parviz Rozikov + * @author Florian Storz + * @author Michael Weidmann + * @author Lasse Wulff + * @since 4.0.0 + */ +@ConfigurationProperties("server.jetty") +public class JettyServerProperties { + + /** + * Maximum size of the form content in any HTTP post request. + */ + private DataSize maxHttpFormPostSize = DataSize.ofBytes(200000); + + /** + * Maximum number of form keys. + */ + private int maxFormKeys = 1000; + + /** + * Time that the connection can be idle before it is closed. + */ + private Duration connectionIdleTimeout; + + /** + * Maximum size of the HTTP response header. + */ + private DataSize maxHttpResponseHeaderSize = DataSize.ofKilobytes(8); + + /** + * Maximum number of connections that the server accepts and processes at any given + * time. + */ + private int maxConnections = -1; + + /** + * Access log configuration. + */ + private final Accesslog accesslog = new Accesslog(); + + /** + * Thread related configuration. + */ + private final Threads threads = new Threads(); + + public Accesslog getAccesslog() { + return this.accesslog; + } + + public Threads getThreads() { + return this.threads; + } + + public DataSize getMaxHttpFormPostSize() { + return this.maxHttpFormPostSize; + } + + public void setMaxHttpFormPostSize(DataSize maxHttpFormPostSize) { + this.maxHttpFormPostSize = maxHttpFormPostSize; + } + + public int getMaxFormKeys() { + return this.maxFormKeys; + } + + public void setMaxFormKeys(int maxFormKeys) { + this.maxFormKeys = maxFormKeys; + } + + public Duration getConnectionIdleTimeout() { + return this.connectionIdleTimeout; + } + + public void setConnectionIdleTimeout(Duration connectionIdleTimeout) { + this.connectionIdleTimeout = connectionIdleTimeout; + } + + public DataSize getMaxHttpResponseHeaderSize() { + return this.maxHttpResponseHeaderSize; + } + + public void setMaxHttpResponseHeaderSize(DataSize maxHttpResponseHeaderSize) { + this.maxHttpResponseHeaderSize = maxHttpResponseHeaderSize; + } + + public int getMaxConnections() { + return this.maxConnections; + } + + public void setMaxConnections(int maxConnections) { + this.maxConnections = maxConnections; + } + + /** + * Jetty access log properties. + */ + public static class Accesslog { + + /** + * Enable access log. + */ + private boolean enabled = false; + + /** + * Log format. + */ + private Accesslog.Format format = Format.NCSA; + + /** + * Custom log format, see org.eclipse.jetty.server.CustomRequestLog. If defined, + * overrides the "format" configuration key. + */ + private String customFormat; + + /** + * Log filename. If not specified, logs redirect to "System.err". + */ + private String filename; + + /** + * Date format to place in log file name. + */ + private String fileDateFormat; + + /** + * Number of days before rotated log files are deleted. + */ + private int retentionPeriod = 31; // no days + + /** + * Append to log. + */ + private boolean append; + + /** + * Request paths that should not be logged. + */ + private List ignorePaths; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Accesslog.Format getFormat() { + return this.format; + } + + public void setFormat(Accesslog.Format format) { + this.format = format; + } + + public String getCustomFormat() { + return this.customFormat; + } + + public void setCustomFormat(String customFormat) { + this.customFormat = customFormat; + } + + public String getFilename() { + return this.filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getFileDateFormat() { + return this.fileDateFormat; + } + + public void setFileDateFormat(String fileDateFormat) { + this.fileDateFormat = fileDateFormat; + } + + public int getRetentionPeriod() { + return this.retentionPeriod; + } + + public void setRetentionPeriod(int retentionPeriod) { + this.retentionPeriod = retentionPeriod; + } + + public boolean isAppend() { + return this.append; + } + + public void setAppend(boolean append) { + this.append = append; + } + + public List getIgnorePaths() { + return this.ignorePaths; + } + + public void setIgnorePaths(List ignorePaths) { + this.ignorePaths = ignorePaths; + } + + /** + * Log format for Jetty access logs. + */ + public enum Format { + + /** + * NCSA format, as defined in CustomRequestLog#NCSA_FORMAT. + */ + NCSA, + + /** + * Extended NCSA format, as defined in CustomRequestLog#EXTENDED_NCSA_FORMAT. + */ + EXTENDED_NCSA + + } + + } + + /** + * Jetty thread properties. + */ + public static class Threads { + + /** + * Number of acceptor threads to use. When the value is -1, the default, the + * number of acceptors is derived from the operating environment. + */ + private Integer acceptors = -1; + + /** + * Number of selector threads to use. When the value is -1, the default, the + * number of selectors is derived from the operating environment. + */ + private Integer selectors = -1; + + /** + * Maximum number of threads. Doesn't have an effect if virtual threads are + * enabled. + */ + private Integer max = 200; + + /** + * Minimum number of threads. Doesn't have an effect if virtual threads are + * enabled. + */ + private Integer min = 8; + + /** + * Maximum capacity of the thread pool's backing queue. A default is computed + * based on the threading configuration. + */ + private Integer maxQueueCapacity; + + /** + * Maximum thread idle time. + */ + private Duration idleTimeout = Duration.ofMillis(60000); + + public Integer getAcceptors() { + return this.acceptors; + } + + public void setAcceptors(Integer acceptors) { + this.acceptors = acceptors; + } + + public Integer getSelectors() { + return this.selectors; + } + + public void setSelectors(Integer selectors) { + this.selectors = selectors; + } + + public void setMin(Integer min) { + this.min = min; + } + + public Integer getMin() { + return this.min; + } + + public void setMax(Integer max) { + this.max = max; + } + + public Integer getMax() { + return this.max; + } + + public Integer getMaxQueueCapacity() { + return this.maxQueueCapacity; + } + + public void setMaxQueueCapacity(Integer maxQueueCapacity) { + this.maxQueueCapacity = maxQueueCapacity; + } + + public void setIdleTimeout(Duration idleTimeout) { + this.idleTimeout = idleTimeout; + } + + public Duration getIdleTimeout() { + return this.idleTimeout; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyThreadPool.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyThreadPool.java similarity index 86% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyThreadPool.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyThreadPool.java index 4f25e61a6cec..8671dd15000f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyThreadPool.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyThreadPool.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.jetty.autoconfigure; import java.util.concurrent.BlockingQueue; import java.util.concurrent.SynchronousQueue; @@ -23,11 +23,9 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ThreadPool; -import org.springframework.boot.autoconfigure.web.ServerProperties; - /** * Creates a {@link ThreadPool} for Jetty, applying - * {@link org.springframework.boot.autoconfigure.web.ServerProperties.Jetty.Threads + * {@link org.springframework.boot.jetty.autoconfigure.JettyServerProperties.Threads * ServerProperties.Jetty.Threads Jetty thread properties}. * * @author Moritz Halbritter @@ -37,7 +35,7 @@ final class JettyThreadPool { private JettyThreadPool() { } - static QueuedThreadPool create(ServerProperties.Jetty.Threads properties) { + static QueuedThreadPool create(JettyServerProperties.Threads properties) { BlockingQueue queue = determineBlockingQueue(properties.getMaxQueueCapacity()); int maxThreadCount = (properties.getMax() > 0) ? properties.getMax() : 200; int minThreadCount = (properties.getMin() > 0) ? properties.getMin() : 8; diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..99641e1efe19 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure; + +import org.eclipse.jetty.util.VirtualThreads; +import org.eclipse.jetty.util.thread.QueuedThreadPool; + +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.Ordered; +import org.springframework.core.env.Environment; +import org.springframework.util.Assert; + +/** + * Activates virtual threads on the {@link ConfigurableJettyWebServerFactory}. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +public class JettyVirtualThreadsWebServerFactoryCustomizer + implements WebServerFactoryCustomizer, Ordered, EnvironmentAware { + + private final JettyServerProperties jettyProperties; + + private final boolean bind; + + public JettyVirtualThreadsWebServerFactoryCustomizer(JettyServerProperties jettyProperties) { + this.jettyProperties = jettyProperties; + this.bind = false; + } + + @Override + public void customize(ConfigurableJettyWebServerFactory factory) { + Assert.state(VirtualThreads.areSupported(), "Virtual threads are not supported"); + QueuedThreadPool threadPool = JettyThreadPool.create(this.jettyProperties.getThreads()); + threadPool.setVirtualThreadsExecutor(VirtualThreads.getNamedVirtualThreadsExecutor("jetty-")); + factory.setThreadPool(threadPool); + } + + @Override + public int getOrder() { + return JettyWebServerFactoryCustomizer.ORDER + 1; + } + + @Override + public void setEnvironment(Environment environment) { + if (this.bind) { + Binder.get(environment).bind("server.jetty", Bindable.ofInstance(this.jettyProperties)); + } + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java new file mode 100644 index 000000000000..dcf7d8656d54 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; +import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; +import org.springframework.boot.autoconfigure.thread.Threading; +import org.springframework.boot.jetty.autoconfigure.reactive.JettyReactiveWebServerAutoConfiguration; +import org.springframework.boot.jetty.autoconfigure.servlet.JettyServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * {@link Configuration Configuration} for a Jetty-based reactive or servlet web server. + * + * @author Andy Wilkinson + * @since 4.0.0 + * @see JettyReactiveWebServerAutoConfiguration + * @see JettyServletWebServerAutoConfiguration + */ +@ConditionalOnNotWarDeployment +@Configuration(proxyBeanMethods = false) +public class JettyWebServerConfiguration { + + private final JettyServerProperties jettyProperties; + + public JettyWebServerConfiguration(JettyServerProperties jettyProperties) { + this.jettyProperties = jettyProperties; + } + + @Bean + JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment, + ServerProperties serverProperties) { + return new JettyWebServerFactoryCustomizer(environment, serverProperties, this.jettyProperties); + } + + @Bean + @ConditionalOnThreading(Threading.VIRTUAL) + JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer() { + return new JettyVirtualThreadsWebServerFactoryCustomizer(this.jettyProperties); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerFactoryCustomizer.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyWebServerFactoryCustomizer.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerFactoryCustomizer.java index 385e7400211e..9b0abed2ef17 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.jetty.autoconfigure; import java.time.Duration; import java.util.Arrays; @@ -32,12 +32,12 @@ import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.RequestLogWriter; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties.Jetty.Accesslog.Format; import org.springframework.boot.cloud.CloudPlatform; import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.jetty.autoconfigure.JettyServerProperties.Accesslog; import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.core.Ordered; import org.springframework.core.env.Environment; import org.springframework.util.CollectionUtils; @@ -52,7 +52,7 @@ * @author Rafiullah Hamedy * @author Florian Storz * @author Michael Weidmann - * @since 2.0.0 + * @since 4.0.0 */ public class JettyWebServerFactoryCustomizer implements WebServerFactoryCustomizer, Ordered { @@ -63,9 +63,13 @@ public class JettyWebServerFactoryCustomizer private final ServerProperties serverProperties; - public JettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { + private final JettyServerProperties jettyProperties; + + public JettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties, + JettyServerProperties jettyProperties) { this.environment = environment; this.serverProperties = serverProperties; + this.jettyProperties = jettyProperties; } @Override @@ -75,34 +79,33 @@ public int getOrder() { @Override public void customize(ConfigurableJettyWebServerFactory factory) { - ServerProperties.Jetty properties = this.serverProperties.getJetty(); factory.setUseForwardHeaders(getOrDeduceUseForwardHeaders()); - ServerProperties.Jetty.Threads threadProperties = properties.getThreads(); - factory.setThreadPool(JettyThreadPool.create(properties.getThreads())); + JettyServerProperties.Threads threadProperties = this.jettyProperties.getThreads(); + factory.setThreadPool(JettyThreadPool.create(this.jettyProperties.getThreads())); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(properties::getMaxConnections).to(factory::setMaxConnections); + map.from(this.jettyProperties::getMaxConnections).to(factory::setMaxConnections); map.from(threadProperties::getAcceptors).to(factory::setAcceptors); map.from(threadProperties::getSelectors).to(factory::setSelectors); map.from(this.serverProperties::getMaxHttpRequestHeaderSize) .asInt(DataSize::toBytes) .when(this::isPositive) .to(customizeHttpConfigurations(factory, HttpConfiguration::setRequestHeaderSize)); - map.from(properties::getMaxHttpResponseHeaderSize) + map.from(this.jettyProperties::getMaxHttpResponseHeaderSize) .asInt(DataSize::toBytes) .when(this::isPositive) .to(customizeHttpConfigurations(factory, HttpConfiguration::setResponseHeaderSize)); - map.from(properties::getMaxHttpFormPostSize) + map.from(this.jettyProperties::getMaxHttpFormPostSize) .asInt(DataSize::toBytes) .when(this::isPositive) .to(customizeServletContextHandler(factory, ServletContextHandler::setMaxFormContentSize)); - map.from(properties::getMaxFormKeys) + map.from(this.jettyProperties::getMaxFormKeys) .when(this::isPositive) .to(customizeServletContextHandler(factory, ServletContextHandler::setMaxFormKeys)); - map.from(properties::getConnectionIdleTimeout) + map.from(this.jettyProperties::getConnectionIdleTimeout) .as(Duration::toMillis) .to(customizeAbstractConnectors(factory, AbstractConnector::setIdleTimeout)); - map.from(properties::getAccesslog) - .when(ServerProperties.Jetty.Accesslog::isEnabled) + map.from(this.jettyProperties::getAccesslog) + .when(JettyServerProperties.Accesslog::isEnabled) .to((accesslog) -> customizeAccessLog(factory, accesslog)); } @@ -178,7 +181,7 @@ private void forEach(Stream elements, Class type, BiConsumer } private void customizeAccessLog(ConfigurableJettyWebServerFactory factory, - ServerProperties.Jetty.Accesslog properties) { + JettyServerProperties.Accesslog properties) { factory.addServerCustomizers((server) -> { RequestLogWriter logWriter = new RequestLogWriter(); String format = getLogFormat(properties); @@ -198,11 +201,11 @@ private void customizeAccessLog(ConfigurableJettyWebServerFactory factory, }); } - private String getLogFormat(ServerProperties.Jetty.Accesslog properties) { + private String getLogFormat(JettyServerProperties.Accesslog properties) { if (properties.getCustomFormat() != null) { return properties.getCustomFormat(); } - if (Format.EXTENDED_NCSA.equals(properties.getFormat())) { + if (Accesslog.Format.EXTENDED_NCSA.equals(properties.getFormat())) { return CustomRequestLog.EXTENDED_NCSA_FORMAT; } return CustomRequestLog.NCSA_FORMAT; diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyAccessLogCustomizer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyAccessLogCustomizer.java new file mode 100644 index 000000000000..fab395188db2 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyAccessLogCustomizer.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.actuate.web; + +import java.io.File; + +import org.eclipse.jetty.server.CustomRequestLog; +import org.eclipse.jetty.server.RequestLog; +import org.eclipse.jetty.server.RequestLogWriter; +import org.eclipse.jetty.server.Server; + +import org.springframework.boot.actuate.autoconfigure.web.server.AccessLogCustomizer; +import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.util.StringUtils; + +/** + * {@link AccessLogCustomizer} for Jetty. + * + * @author Andy Wilkinson + */ +class JettyAccessLogCustomizer extends AccessLogCustomizer + implements WebServerFactoryCustomizer { + + JettyAccessLogCustomizer(JettyManagementServerProperties properties) { + super(properties.getAccesslog().getPrefix()); + } + + @Override + public void customize(ConfigurableJettyWebServerFactory factory) { + factory.addServerCustomizers(this::customizeServer); + } + + private void customizeServer(Server server) { + RequestLog requestLog = server.getRequestLog(); + if (requestLog instanceof CustomRequestLog customRequestLog) { + customizeRequestLog(customRequestLog); + } + } + + private void customizeRequestLog(CustomRequestLog requestLog) { + if (requestLog.getWriter() instanceof RequestLogWriter requestLogWriter) { + customizeRequestLogWriter(requestLogWriter); + } + } + + private void customizeRequestLogWriter(RequestLogWriter writer) { + String filename = writer.getFileName(); + if (StringUtils.hasLength(filename)) { + File file = new File(filename); + file = new File(file.getParentFile(), customizePrefix(file.getName())); + writer.setFilename(file.getPath()); + } + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyManagementServerProperties.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyManagementServerProperties.java new file mode 100644 index 000000000000..f6bdaf02f37c --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyManagementServerProperties.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.actuate.web; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Properties for a Jetty-based management server. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +@ConfigurationProperties("management.server.jetty") +public class JettyManagementServerProperties { + + private final Accesslog accesslog = new Accesslog(); + + public Accesslog getAccesslog() { + return this.accesslog; + } + + public static class Accesslog { + + /** + * Management log file name prefix. + */ + private String prefix = "management_"; + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyReactiveManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyReactiveManagementChildContextConfiguration.java new file mode 100644 index 000000000000..0ee200dac63c --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyReactiveManagementChildContextConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.actuate.web; + +import org.eclipse.jetty.server.Server; + +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jetty-based + * reactive web endpoint infrastructure when a separate management context running on a + * different port is required. + * + * @author Andy Wilkinson + */ +@ConditionalOnClass(Server.class) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@EnableConfigurationProperties(JettyManagementServerProperties.class) +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +class JettyReactiveManagementChildContextConfiguration { + + @Bean + JettyAccessLogCustomizer jettyManagementAccessLogCustomizer(JettyManagementServerProperties properties) { + return new JettyAccessLogCustomizer(properties); + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyReactiveManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyReactiveManagementContextAutoConfiguration.java new file mode 100644 index 000000000000..e64ffb3d8f65 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyReactiveManagementContextAutoConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.actuate.web; + +import org.eclipse.jetty.server.Server; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.jetty.autoconfigure.reactive.JettyReactiveWebServerAutoConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * Auto-configuration for a Jetty-based reactive management context. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ Server.class, ManagementContextFactory.class }) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) +public class JettyReactiveManagementContextAutoConfiguration { + + @Bean + static ManagementContextFactory reactiveWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, + JettyReactiveWebServerAutoConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyServletManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyServletManagementChildContextConfiguration.java new file mode 100644 index 000000000000..ecd9caf9c652 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyServletManagementChildContextConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.actuate.web; + +import org.eclipse.jetty.server.Server; + +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jetty-based + * servlet web endpoint infrastructure when a separate management context running on a + * different port is required. + * + * @author Andy Wilkinson + */ +@ConditionalOnClass(Server.class) +@ConditionalOnWebApplication(type = Type.SERVLET) +@EnableConfigurationProperties(JettyManagementServerProperties.class) +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +class JettyServletManagementChildContextConfiguration { + + @Bean + JettyAccessLogCustomizer jettyManagementAccessLogCustomizer(JettyManagementServerProperties properties) { + return new JettyAccessLogCustomizer(properties); + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyServletManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyServletManagementContextAutoConfiguration.java new file mode 100644 index 000000000000..a92a50eb2775 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyServletManagementContextAutoConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.actuate.web; + +import org.eclipse.jetty.server.Server; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.jetty.autoconfigure.servlet.JettyServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * Auto-configuration for a Jetty-based servlet management context. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ Server.class, ManagementContextFactory.class }) +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) +public class JettyServletManagementContextAutoConfiguration { + + @Bean + static ManagementContextFactory servletWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.SERVLET, ServletWebServerFactory.class, + JettyServletWebServerAutoConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/package-info.java new file mode 100644 index 000000000000..2713dd3934e8 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/actuate/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Jetty actuator web concerns. + */ +package org.springframework.boot.jetty.autoconfigure.actuate.web; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/metrics/JettyMetricsAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/metrics/JettyMetricsAutoConfiguration.java index e25419e1881f..d3b5d07ae97a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/metrics/JettyMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.web.jetty; +package org.springframework.boot.jetty.autoconfigure.metrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.jetty.JettyConnectionMetrics; @@ -22,10 +22,6 @@ import io.micrometer.core.instrument.binder.jetty.JettySslHandshakeMetrics; import org.eclipse.jetty.server.Server; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.metrics.web.jetty.JettyConnectionMetricsBinder; -import org.springframework.boot.actuate.metrics.web.jetty.JettyServerThreadPoolMetricsBinder; -import org.springframework.boot.actuate.metrics.web.jetty.JettySslHandshakeMetricsBinder; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -33,6 +29,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.jetty.metrics.JettyConnectionMetricsBinder; +import org.springframework.boot.jetty.metrics.JettyServerThreadPoolMetricsBinder; +import org.springframework.boot.jetty.metrics.JettySslHandshakeMetricsBinder; import org.springframework.context.annotation.Bean; /** @@ -40,11 +39,11 @@ * * @author Andy Wilkinson * @author Chris Bono - * @since 2.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = CompositeMeterRegistryAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") @ConditionalOnWebApplication -@ConditionalOnClass({ JettyServerThreadPoolMetrics.class, Server.class }) +@ConditionalOnClass({ JettyServerThreadPoolMetrics.class, Server.class, MeterRegistry.class }) @ConditionalOnBean(MeterRegistry.class) public class JettyMetricsAutoConfiguration { diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..2e4ea7c7d12b --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Jetty metrics. + */ +package org.springframework.boot.jetty.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/package-info.java new file mode 100644 index 000000000000..8e295626c9aa --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Jetty. + */ +package org.springframework.boot.jetty.autoconfigure; diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/JettyReactiveWebServerAutoConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/JettyReactiveWebServerAutoConfiguration.java new file mode 100644 index 000000000000..8e193df12187 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/JettyReactiveWebServerAutoConfiguration.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.reactive; + +import org.eclipse.jetty.ee10.servlet.ServletHolder; +import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer; +import org.eclipse.jetty.server.Server; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.autoconfigure.JettyServerProperties; +import org.springframework.boot.jetty.autoconfigure.JettyWebServerConfiguration; +import org.springframework.boot.jetty.reactive.JettyReactiveWebServerFactory; +import org.springframework.boot.web.server.autoconfigure.reactive.ReactiveWebServerConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.http.ReactiveHttpInputMessage; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for a Jetty-based reactive web + * server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ Server.class, ServletHolder.class, ReactiveHttpInputMessage.class }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +@EnableConfigurationProperties(JettyServerProperties.class) +@Import({ JettyWebServerConfiguration.class, ReactiveWebServerConfiguration.class }) +public class JettyReactiveWebServerAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(ReactiveWebServerFactory.class) + JettyReactiveWebServerFactory jettyReactiveWebServerFactory( + ObjectProvider serverCustomizers) { + JettyReactiveWebServerFactory serverFactory = new JettyReactiveWebServerFactory(); + serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList()); + return serverFactory; + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(JakartaWebSocketServletContainerInitializer.class) + static class JettyWebSocketConfiguration { + + @Bean + @ConditionalOnMissingBean(name = "websocketReactiveWebServerCustomizer") + WebSocketJettyReactiveWebServerFactoryCustomizer websocketServletWebServerCustomizer() { + return new WebSocketJettyReactiveWebServerFactoryCustomizer(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/WebSocketJettyReactiveWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/WebSocketJettyReactiveWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..f4b698887889 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/WebSocketJettyReactiveWebServerFactoryCustomizer.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.reactive; + +import jakarta.servlet.ServletContext; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.websocket.jakarta.server.JakartaWebSocketServerContainer; +import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer; +import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.websocket.core.server.WebSocketMappings; +import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents; + +import org.springframework.boot.jetty.reactive.JettyReactiveWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.core.Ordered; + +/** + * WebSocket customizer for {@link JettyReactiveWebServerFactory}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class WebSocketJettyReactiveWebServerFactoryCustomizer + implements WebServerFactoryCustomizer, Ordered { + + @Override + public void customize(JettyReactiveWebServerFactory factory) { + factory.addServerCustomizers((server) -> { + ServletContextHandler servletContextHandler = findServletContextHandler(server); + if (servletContextHandler != null) { + ServletContext servletContext = servletContextHandler.getServletContext(); + if (JettyWebSocketServerContainer.getContainer(servletContext) == null) { + WebSocketServerComponents.ensureWebSocketComponents(server, servletContextHandler); + JettyWebSocketServerContainer.ensureContainer(servletContext); + } + if (JakartaWebSocketServerContainer.getContainer(servletContext) == null) { + WebSocketServerComponents.ensureWebSocketComponents(server, servletContextHandler); + WebSocketUpgradeFilter.ensureFilter(servletContext); + WebSocketMappings.ensureMappings(servletContextHandler); + JakartaWebSocketServerContainer.ensureContainer(servletContext); + } + } + }); + } + + private ServletContextHandler findServletContextHandler(Handler handler) { + if (handler instanceof ServletContextHandler servletContextHandler) { + return servletContextHandler; + } + if (handler instanceof Handler.Wrapper handlerWrapper) { + return findServletContextHandler(handlerWrapper.getHandler()); + } + if (handler instanceof Handler.Collection handlerCollection) { + for (Handler contained : handlerCollection.getHandlers()) { + ServletContextHandler servletContextHandler = findServletContextHandler(contained); + if (servletContextHandler != null) { + return servletContextHandler; + } + } + } + return null; + } + + @Override + public int getOrder() { + return 0; + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..0721179b5033 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a reactive web server using Jetty. + */ +package org.springframework.boot.jetty.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerAutoConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerAutoConfiguration.java new file mode 100644 index 000000000000..2e7f32536b2f --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerAutoConfiguration.java @@ -0,0 +1,102 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.servlet; + +import java.util.EnumSet; + +import jakarta.servlet.DispatcherType; +import jakarta.servlet.FilterRegistration.Dynamic; +import jakarta.servlet.ServletRequest; +import org.eclipse.jetty.ee10.webapp.WebAppContext; +import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer; +import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.Loader; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.autoconfigure.condition.SearchStrategy; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.autoconfigure.JettyServerProperties; +import org.springframework.boot.jetty.autoconfigure.JettyWebServerConfiguration; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.servlet.ServletWebServerConfiguration; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for a Jetty-based servlet web + * server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ServletRequest.class, Server.class, Loader.class, WebAppContext.class }) +@ConditionalOnWebApplication(type = Type.SERVLET) +@EnableConfigurationProperties(JettyServerProperties.class) +@Import({ JettyWebServerConfiguration.class, ServletWebServerConfiguration.class }) +public class JettyServletWebServerAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT) + JettyServletWebServerFactory jettyServletWebServerFactory(ObjectProvider serverCustomizers) { + JettyServletWebServerFactory factory = new JettyServletWebServerFactory(); + factory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList()); + return factory; + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(JakartaWebSocketServletContainerInitializer.class) + static class JettyWebSocketConfiguration { + + @Bean + @ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer") + WebSocketJettyServletWebServerFactoryCustomizer websocketServletWebServerCustomizer() { + return new WebSocketJettyServletWebServerFactoryCustomizer(); + } + + @Bean + @ConditionalOnNotWarDeployment + @Order(Ordered.LOWEST_PRECEDENCE) + @ConditionalOnMissingBean(name = "websocketUpgradeFilterWebServerCustomizer") + WebServerFactoryCustomizer websocketUpgradeFilterWebServerCustomizer() { + return (factory) -> { + factory.addInitializers((servletContext) -> { + Dynamic registration = servletContext.addFilter(WebSocketUpgradeFilter.class.getName(), + new WebSocketUpgradeFilter()); + registration.setAsyncSupported(true); + registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*"); + }); + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/WebSocketJettyServletWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/WebSocketJettyServletWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..03d65d0d9acb --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/WebSocketJettyServletWebServerFactoryCustomizer.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.servlet; + +import org.eclipse.jetty.ee10.webapp.AbstractConfiguration; +import org.eclipse.jetty.ee10.webapp.WebAppContext; +import org.eclipse.jetty.ee10.websocket.jakarta.server.JakartaWebSocketServerContainer; +import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer; +import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter; +import org.eclipse.jetty.websocket.core.server.WebSocketMappings; +import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents; + +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.core.Ordered; + +/** + * WebSocket customizer for {@link JettyServletWebServerFactory}. + * + * @author Dave Syer + * @author Phillip Webb + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class WebSocketJettyServletWebServerFactoryCustomizer + implements WebServerFactoryCustomizer, Ordered { + + @Override + public void customize(JettyServletWebServerFactory factory) { + factory.addConfigurations(new AbstractConfiguration(new AbstractConfiguration.Builder()) { + + @Override + public void configure(WebAppContext context) throws Exception { + if (JettyWebSocketServerContainer.getContainer(context.getServletContext()) == null) { + WebSocketServerComponents.ensureWebSocketComponents(context.getServer(), + context.getContext().getContextHandler()); + JettyWebSocketServerContainer.ensureContainer(context.getServletContext()); + } + if (JakartaWebSocketServerContainer.getContainer(context.getServletContext()) == null) { + WebSocketServerComponents.ensureWebSocketComponents(context.getServer(), + context.getContext().getContextHandler()); + WebSocketUpgradeFilter.ensureFilter(context.getServletContext()); + WebSocketMappings.ensureMappings(context.getContext().getContextHandler()); + JakartaWebSocketServerContainer.ensureContainer(context.getServletContext()); + } + } + + }); + } + + @Override + public int getOrder() { + return 0; + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..e8da927e49cc --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a servlet web server using Jetty. + */ +package org.springframework.boot.jetty.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/AbstractJettyMetricsBinder.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/AbstractJettyMetricsBinder.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/AbstractJettyMetricsBinder.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/AbstractJettyMetricsBinder.java index fbbf27d3f2ee..a868d799e18d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/AbstractJettyMetricsBinder.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/AbstractJettyMetricsBinder.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.jetty; +package org.springframework.boot.jetty.metrics; import org.eclipse.jetty.server.Server; import org.springframework.boot.context.event.ApplicationStartedEvent; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.boot.web.embedded.jetty.JettyWebServer; +import org.springframework.boot.jetty.JettyWebServer; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; @@ -29,7 +29,7 @@ * Base class for binding Jetty metrics in response to an {@link ApplicationStartedEvent}. * * @author Andy Wilkinson - * @since 2.6.0 + * @since 4.0.0 */ public abstract class AbstractJettyMetricsBinder implements ApplicationListener { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettyConnectionMetricsBinder.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettyConnectionMetricsBinder.java index 50de05ad9a97..41a7b0a7ae6c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettyConnectionMetricsBinder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.jetty; +package org.springframework.boot.jetty.metrics; import java.util.Collections; @@ -27,7 +27,7 @@ * {@link AbstractJettyMetricsBinder} for {@link JettyConnectionMetrics}. * * @author Chris Bono - * @since 2.6.0 + * @since 4.0.0 */ public class JettyConnectionMetricsBinder extends AbstractJettyMetricsBinder { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettyServerThreadPoolMetricsBinder.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettyServerThreadPoolMetricsBinder.java index ec9b9ff2fae9..c67813b49bd3 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettyServerThreadPoolMetricsBinder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.jetty; +package org.springframework.boot.jetty.metrics; import java.util.Collections; @@ -28,7 +28,7 @@ * {@link AbstractJettyMetricsBinder} for {@link JettyServerThreadPoolMetrics}. * * @author Andy Wilkinson - * @since 2.1.0 + * @since 4.0.0 */ public class JettyServerThreadPoolMetricsBinder extends AbstractJettyMetricsBinder { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettySslHandshakeMetricsBinder.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettySslHandshakeMetricsBinder.java index 2659a00e7c9a..a6e2f40085f8 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/JettySslHandshakeMetricsBinder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.jetty; +package org.springframework.boot.jetty.metrics; import java.util.Collections; @@ -27,7 +27,7 @@ * {@link AbstractJettyMetricsBinder} for {@link JettySslHandshakeMetrics}. * * @author Chris Bono - * @since 2.6.0 + * @since 4.0.0 */ public class JettySslHandshakeMetricsBinder extends AbstractJettyMetricsBinder { diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/package-info.java new file mode 100644 index 000000000000..89d338ae74a9 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator support for Jetty metrics. + */ +package org.springframework.boot.jetty.metrics; diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/package-info.java new file mode 100644 index 000000000000..79021863cfc7 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive and servlet web server implementations backed by Jetty. + * + * @see org.springframework.boot.jetty.servlet.JettyServletWebServerFactory + * @see org.springframework.boot.jetty.reactive.JettyReactiveWebServerFactory + */ +package org.springframework.boot.jetty; diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/reactive/JettyReactiveWebServerFactory.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/reactive/JettyReactiveWebServerFactory.java new file mode 100644 index 000000000000..5698f1f3de1c --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/reactive/JettyReactiveWebServerFactory.java @@ -0,0 +1,130 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.reactive; + +import java.net.InetSocketAddress; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.ServletHolder; +import org.eclipse.jetty.server.ConnectionLimit; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.StatisticsHandler; + +import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.jetty.ForwardHeadersCustomizer; +import org.springframework.boot.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.JettyWebServer; +import org.springframework.boot.jetty.JettyWebServerFactory; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; +import org.springframework.boot.web.server.Shutdown; +import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.http.client.reactive.JettyResourceFactory; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; + +/** + * {@link ReactiveWebServerFactory} that can be used to create {@link JettyWebServer}s. + * + * @author Brian Clozel + * @author Moritz Halbritter + * @since 4.0.0 + */ +public class JettyReactiveWebServerFactory extends JettyWebServerFactory + implements ConfigurableJettyWebServerFactory, ConfigurableReactiveWebServerFactory { + + private static final Log logger = LogFactory.getLog(JettyReactiveWebServerFactory.class); + + private JettyResourceFactory resourceFactory; + + /** + * Create a new {@link JettyServletWebServerFactory} instance. + */ + public JettyReactiveWebServerFactory() { + } + + /** + * Create a new {@link JettyServletWebServerFactory} that listens for requests using + * the specified port. + * @param port the port to listen on + */ + public JettyReactiveWebServerFactory(int port) { + super(port); + } + + @Override + public WebServer getWebServer(HttpHandler httpHandler) { + ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler); + Server server = createJettyServer(servlet); + return new JettyWebServer(server, getPort() >= 0); + } + + /** + * Set the {@link JettyResourceFactory} to get the shared resources from. + * @param resourceFactory the server resources + */ + public void setResourceFactory(JettyResourceFactory resourceFactory) { + this.resourceFactory = resourceFactory; + } + + protected JettyResourceFactory getResourceFactory() { + return this.resourceFactory; + } + + protected Server createJettyServer(ServletHttpHandlerAdapter servlet) { + int port = Math.max(getPort(), 0); + InetSocketAddress address = new InetSocketAddress(getAddress(), port); + Server server = new Server(getThreadPool()); + if (this.resourceFactory == null) { + server.addConnector(createConnector(address, server)); + } + else { + server.addConnector(createConnector(address, server, this.resourceFactory.getExecutor(), + this.resourceFactory.getScheduler(), this.resourceFactory.getByteBufferPool())); + } + server.setStopTimeout(0); + ServletHolder servletHolder = new ServletHolder(servlet); + servletHolder.setAsyncSupported(true); + ServletContextHandler contextHandler = new ServletContextHandler("/", false, false); + contextHandler.addServlet(servletHolder, "/"); + server.setHandler(addHandlerWrappers(contextHandler)); + logger.info("Server initialized with port: " + port); + if (this.getMaxConnections() > -1) { + server.addBean(new ConnectionLimit(this.getMaxConnections(), server)); + } + if (Ssl.isEnabled(getSsl())) { + customizeSsl(server, address); + } + for (JettyServerCustomizer customizer : getServerCustomizers()) { + customizer.customize(server); + } + if (this.isUseForwardHeaders()) { + new ForwardHeadersCustomizer().customize(server); + } + if (getShutdown() == Shutdown.GRACEFUL) { + StatisticsHandler statisticsHandler = new StatisticsHandler(); + statisticsHandler.setHandler(server.getHandler()); + server.setHandler(statisticsHandler); + } + return server; + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/reactive/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/reactive/package-info.java new file mode 100644 index 000000000000..c1000188baac --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/reactive/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive web server implementation backed by Jetty. + * + */ +package org.springframework.boot.jetty.reactive; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JasperInitializer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JasperInitializer.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JasperInitializer.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JasperInitializer.java index 5c6fe0bf81b7..db005b569f58 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JasperInitializer.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JasperInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty.servlet; import java.io.IOException; import java.io.InputStream; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedErrorHandler.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedErrorHandler.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedErrorHandler.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedErrorHandler.java index fa04c8ef4867..b1263a98e7f6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedErrorHandler.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedErrorHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty.servlet; import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler; import org.eclipse.jetty.http.HttpMethod; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedWebAppContext.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedWebAppContext.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedWebAppContext.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedWebAppContext.java index ecd09ee4890b..862185a72f43 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedWebAppContext.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyEmbeddedWebAppContext.java @@ -14,12 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty.servlet; import org.eclipse.jetty.ee10.servlet.ServletHandler; import org.eclipse.jetty.ee10.webapp.WebAppContext; import org.eclipse.jetty.util.ClassMatcher; +import org.springframework.boot.jetty.JettyWebServer; + /** * Jetty {@link WebAppContext} used by {@link JettyWebServer} to support deferred * initialization. diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyServletWebServer.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyServletWebServer.java new file mode 100644 index 000000000000..4dc3321bbb6b --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyServletWebServer.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.servlet; + +import java.util.List; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; + +import org.springframework.boot.jetty.JettyWebServer; + +/** + * Servlet-specific {@link JettyWebServer}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class JettyServletWebServer extends JettyWebServer { + + public JettyServletWebServer(Server server) { + super(server); + } + + public JettyServletWebServer(Server server, boolean autoStart) { + super(server, autoStart); + } + + @Override + protected void handleDeferredInitialize(Server server) throws Exception { + handleDeferredInitialize(server.getHandlers()); + } + + protected void handleDeferredInitialize(List handlers) throws Exception { + for (Handler handler : handlers) { + handleDeferredInitialize(handler); + } + } + + private void handleDeferredInitialize(Handler handler) throws Exception { + if (handler instanceof JettyEmbeddedWebAppContext jettyEmbeddedWebAppContext) { + jettyEmbeddedWebAppContext.deferredInitialize(); + } + else if (handler instanceof Handler.Wrapper handlerWrapper) { + handleDeferredInitialize(handlerWrapper.getHandler()); + } + else if (handler instanceof Handler.Collection handlerCollection) { + handleDeferredInitialize(handlerCollection.getHandlers()); + } + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyServletWebServerFactory.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyServletWebServerFactory.java new file mode 100644 index 000000000000..bcd1dd43be44 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/JettyServletWebServerFactory.java @@ -0,0 +1,616 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.servlet; + +import java.io.File; +import java.net.InetSocketAddress; +import java.net.URL; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EventListener; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; + +import jakarta.servlet.http.Cookie; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.jetty.ee10.servlet.ErrorHandler; +import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler; +import org.eclipse.jetty.ee10.servlet.ListenerHolder; +import org.eclipse.jetty.ee10.servlet.ServletHandler; +import org.eclipse.jetty.ee10.servlet.ServletHolder; +import org.eclipse.jetty.ee10.servlet.ServletMapping; +import org.eclipse.jetty.ee10.servlet.SessionHandler; +import org.eclipse.jetty.ee10.servlet.Source; +import org.eclipse.jetty.ee10.webapp.AbstractConfiguration; +import org.eclipse.jetty.ee10.webapp.Configuration; +import org.eclipse.jetty.ee10.webapp.WebAppContext; +import org.eclipse.jetty.ee10.webapp.WebInfConfiguration; +import org.eclipse.jetty.http.CookieCompliance; +import org.eclipse.jetty.http.HttpCookie; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpFields.Mutable; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.http.MimeTypes.Wrapper; +import org.eclipse.jetty.http.SetCookieParser; +import org.eclipse.jetty.server.ConnectionLimit; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpCookieUtils; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.StatisticsHandler; +import org.eclipse.jetty.session.DefaultSessionCache; +import org.eclipse.jetty.session.FileSessionDataStore; +import org.eclipse.jetty.session.SessionConfig; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.eclipse.jetty.util.resource.URLResourceFactory; + +import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.jetty.ForwardHeadersCustomizer; +import org.springframework.boot.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.JettyWebServer; +import org.springframework.boot.jetty.JettyWebServerFactory; +import org.springframework.boot.web.error.ErrorPage; +import org.springframework.boot.web.server.Cookie.SameSite; +import org.springframework.boot.web.server.MimeMappings; +import org.springframework.boot.web.server.Shutdown; +import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ContextPath; +import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier; +import org.springframework.boot.web.server.servlet.DocumentRoot; +import org.springframework.boot.web.server.servlet.ServletContextInitializers; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerSettings; +import org.springframework.boot.web.servlet.ServletContextInitializer; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +/** + * {@link ServletWebServerFactory} that can be used to create a {@link JettyWebServer}. + * Can be initialized using Spring's {@link ServletContextInitializer}s or Jetty + * {@link Configuration}s. + *

+ * Unless explicitly configured otherwise this factory will create servers that listen for + * HTTP requests on port 8080. + * + * @author Phillip Webb + * @author Dave Syer + * @author Andrey Hihlovskiy + * @author Andy Wilkinson + * @author Eddú Meléndez + * @author Venil Noronha + * @author Henri Kerola + * @author Moritz Halbritter + * @author Onur Kagan Ozcan + * @since 4.0.0 + * @see #setPort(int) + * @see #setConfigurations(Collection) + * @see JettyWebServer + */ +public class JettyServletWebServerFactory extends JettyWebServerFactory + implements ConfigurableJettyWebServerFactory, ConfigurableServletWebServerFactory, ResourceLoaderAware { + + private static final Log logger = LogFactory.getLog(JettyServletWebServerFactory.class); + + private final ServletWebServerSettings settings = new ServletWebServerSettings(); + + private ResourceLoader resourceLoader; + + /** + * Create a new {@link JettyServletWebServerFactory} instance. + */ + public JettyServletWebServerFactory() { + } + + /** + * Create a new {@link JettyServletWebServerFactory} that listens for requests using + * the specified port. + * @param port the port to listen on + */ + public JettyServletWebServerFactory(int port) { + super(port); + } + + /** + * Create a new {@link JettyServletWebServerFactory} with the specified context path + * and port. + * @param contextPath the root context path + * @param port the port to listen on + */ + public JettyServletWebServerFactory(String contextPath, int port) { + super(port); + getSettings().setContextPath(ContextPath.of(contextPath)); + } + + @Override + public WebServer getWebServer(ServletContextInitializer... initializers) { + JettyEmbeddedWebAppContext context = new JettyEmbeddedWebAppContext(); + context.getContext().getServletContext().setExtendedListenerTypes(true); + int port = Math.max(getPort(), 0); + InetSocketAddress address = new InetSocketAddress(getAddress(), port); + Server server = createServer(address); + context.setServer(server); + configureWebAppContext(context, initializers); + server.setHandler(addHandlerWrappers(context)); + logger.info("Server initialized with port: " + port); + if (this.getMaxConnections() > -1) { + server.addBean(new ConnectionLimit(this.getMaxConnections(), server.getConnectors())); + } + if (Ssl.isEnabled(getSsl())) { + customizeSsl(server, address); + } + for (JettyServerCustomizer customizer : getServerCustomizers()) { + customizer.customize(server); + } + if (this.isUseForwardHeaders()) { + new ForwardHeadersCustomizer().customize(server); + } + if (getShutdown() == Shutdown.GRACEFUL) { + StatisticsHandler statisticsHandler = new StatisticsHandler(); + statisticsHandler.setHandler(server.getHandler()); + server.setHandler(statisticsHandler); + } + return getJettyWebServer(server); + } + + private Server createServer(InetSocketAddress address) { + Server server = new Server(getThreadPool()); + server.setConnectors(new Connector[] { createConnector(address, server) }); + server.setStopTimeout(0); + MimeTypes.Mutable mimeTypes = server.getMimeTypes(); + for (MimeMappings.Mapping mapping : getSettings().getMimeMappings()) { + mimeTypes.addMimeMapping(mapping.getExtension(), mapping.getMimeType()); + } + return server; + } + + @Override + protected Handler addHandlerWrappers(Handler handler) { + handler = super.addHandlerWrappers(handler); + if (!CollectionUtils.isEmpty(getSettings().getCookieSameSiteSuppliers())) { + handler = applyWrapper(handler, new SuppliedSameSiteCookieHandlerWrapper(getSessionCookieName(), + getSettings().getCookieSameSiteSuppliers())); + } + return handler; + } + + private String getSessionCookieName() { + String name = getSettings().getSession().getCookie().getName(); + return (name != null) ? name : SessionConfig.__DefaultSessionCookie; + } + + /** + * Configure the given Jetty {@link WebAppContext} for use. + * @param context the context to configure + * @param initializers the set of initializers to apply + */ + protected final void configureWebAppContext(WebAppContext context, ServletContextInitializer... initializers) { + Assert.notNull(context, "'context' must not be null"); + context.clearAliasChecks(); + if (this.resourceLoader != null) { + context.setClassLoader(this.resourceLoader.getClassLoader()); + } + String contextPath = getSettings().getContextPath().toString(); + context.setContextPath(StringUtils.hasLength(contextPath) ? contextPath : "/"); + context.setDisplayName(getSettings().getDisplayName()); + configureDocumentRoot(context); + if (getSettings().isRegisterDefaultServlet()) { + addDefaultServlet(context); + } + if (shouldRegisterJspServlet()) { + addJspServlet(context); + context.addBean(new JasperInitializer(context), true); + } + addLocaleMappings(context); + ServletContextInitializers initializersToUse = ServletContextInitializers.from(this.settings, initializers); + Configuration[] configurations = getWebAppContextConfigurations(context, initializersToUse); + context.setConfigurations(configurations); + context.setThrowUnavailableOnStartupException(true); + configureSession(context); + context.setTempDirectory(getTempDirectory(context)); + postProcessWebAppContext(context); + } + + private boolean shouldRegisterJspServlet() { + return this.settings.getJsp() != null && this.settings.getJsp().getRegistered() + && ClassUtils.isPresent(this.settings.getJsp().getClassName(), getClass().getClassLoader()); + } + + private void configureSession(WebAppContext context) { + SessionHandler handler = context.getSessionHandler(); + SameSite sessionSameSite = getSettings().getSession().getCookie().getSameSite(); + if (sessionSameSite != null && sessionSameSite != SameSite.OMITTED) { + handler.setSameSite(HttpCookie.SameSite.valueOf(sessionSameSite.name())); + } + Duration sessionTimeout = getSettings().getSession().getTimeout(); + handler.setMaxInactiveInterval(isNegative(sessionTimeout) ? -1 : (int) sessionTimeout.getSeconds()); + if (getSettings().getSession().isPersistent()) { + DefaultSessionCache cache = new DefaultSessionCache(handler); + FileSessionDataStore store = new FileSessionDataStore(); + store.setStoreDir(getSettings().getSession().getSessionStoreDirectory().getValidDirectory(true)); + cache.setSessionDataStore(store); + handler.setSessionCache(cache); + } + } + + private boolean isNegative(Duration sessionTimeout) { + return sessionTimeout == null || sessionTimeout.isNegative(); + } + + private void addLocaleMappings(WebAppContext context) { + getSettings().getLocaleCharsetMappings() + .forEach((locale, charset) -> context.addLocaleEncoding(locale.toString(), charset.toString())); + } + + private File getTempDirectory(WebAppContext context) { + String temp = System.getProperty("java.io.tmpdir"); + return (temp != null) ? new File(temp, getTempDirectoryPrefix(context) + UUID.randomUUID()) : null; + } + + @SuppressWarnings("removal") + private String getTempDirectoryPrefix(WebAppContext context) { + try { + return ((JettyEmbeddedWebAppContext) context).getCanonicalNameForTmpDir(); + } + catch (Throwable ex) { + return WebInfConfiguration.getCanonicalNameForWebAppTmpDir(context); + } + } + + private void configureDocumentRoot(WebAppContext handler) { + DocumentRoot documentRoot = new DocumentRoot(logger); + documentRoot.setDirectory(this.settings.getDocumentRoot()); + File root = documentRoot.getValidDirectory(); + File docBase = (root != null) ? root : createTempDir("jetty-docbase"); + try { + ResourceFactory resourceFactory = handler.getResourceFactory(); + List resources = new ArrayList<>(); + Resource rootResource = (docBase.isDirectory() + ? resourceFactory.newResource(docBase.getCanonicalFile().toURI()) + : resourceFactory.newJarFileResource(docBase.toURI())); + resources.add((root != null) ? new LoaderHidingResource(rootResource, rootResource) : rootResource); + URLResourceFactory urlResourceFactory = new URLResourceFactory(); + for (URL resourceJarUrl : getSettings().getStaticResourceUrls()) { + Resource resource = createResource(resourceJarUrl, resourceFactory, urlResourceFactory); + if (resource != null) { + resources.add(resource); + } + } + handler.setBaseResource(ResourceFactory.combine(resources)); + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + private Resource createResource(URL url, ResourceFactory resourceFactory, URLResourceFactory urlResourceFactory) + throws Exception { + if ("file".equals(url.getProtocol())) { + File file = new File(url.toURI()); + if (file.isFile()) { + return resourceFactory.newResource("jar:" + url + "!/META-INF/resources/"); + } + if (file.isDirectory()) { + return resourceFactory.newResource(url).resolve("META-INF/resources/"); + } + } + return urlResourceFactory.newResource(url + "META-INF/resources/"); + } + + /** + * Add Jetty's {@code DefaultServlet} to the given {@link WebAppContext}. + * @param context the jetty {@link WebAppContext} + */ + protected final void addDefaultServlet(WebAppContext context) { + Assert.notNull(context, "'context' must not be null"); + ServletHolder holder = new ServletHolder(); + holder.setName("default"); + holder.setClassName("org.eclipse.jetty.ee10.servlet.DefaultServlet"); + holder.setInitParameter("dirAllowed", "false"); + holder.setInitOrder(1); + context.getServletHandler().addServletWithMapping(holder, "/"); + ServletMapping servletMapping = context.getServletHandler().getServletMapping("/"); + servletMapping.setFromDefaultDescriptor(true); + } + + /** + * Add Jetty's {@code JspServlet} to the given {@link WebAppContext}. + * @param context the jetty {@link WebAppContext} + */ + protected final void addJspServlet(WebAppContext context) { + Assert.notNull(context, "'context' must not be null"); + ServletHolder holder = new ServletHolder(); + holder.setName("jsp"); + holder.setClassName(this.settings.getJsp().getClassName()); + holder.setInitParameter("fork", "false"); + holder.setInitParameters(this.settings.getJsp().getInitParameters()); + holder.setInitOrder(3); + context.getServletHandler().addServlet(holder); + ServletMapping mapping = new ServletMapping(); + mapping.setServletName("jsp"); + mapping.setPathSpecs(new String[] { "*.jsp", "*.jspx" }); + context.getServletHandler().addServletMapping(mapping); + } + + /** + * Return the Jetty {@link Configuration}s that should be applied to the server. + * @param webAppContext the Jetty {@link WebAppContext} + * @param initializers the {@link ServletContextInitializer}s to apply + * @return configurations to apply + */ + protected Configuration[] getWebAppContextConfigurations(WebAppContext webAppContext, + ServletContextInitializers initializers) { + List configurations = new ArrayList<>(); + configurations.add(getServletContextInitializerConfiguration(webAppContext, initializers)); + configurations.add(getErrorPageConfiguration()); + configurations.add(getMimeTypeConfiguration()); + configurations.add(new WebListenersConfiguration(getSettings().getWebListenerClassNames())); + configurations.addAll(getConfigurations()); + return configurations.toArray(new Configuration[0]); + } + + /** + * Create a configuration object that adds error handlers. + * @return a configuration object for adding error pages + */ + private Configuration getErrorPageConfiguration() { + return new AbstractConfiguration(new AbstractConfiguration.Builder()) { + + @Override + public void configure(WebAppContext context) throws Exception { + JettyEmbeddedErrorHandler errorHandler = new JettyEmbeddedErrorHandler(); + context.setErrorHandler(errorHandler); + addJettyErrorPages(errorHandler, getErrorPages()); + } + + }; + } + + /** + * Create a configuration object that adds mime type mappings. + * @return a configuration object for adding mime type mappings + */ + private Configuration getMimeTypeConfiguration() { + return new AbstractConfiguration(new AbstractConfiguration.Builder()) { + + @Override + public void configure(WebAppContext context) throws Exception { + MimeTypes.Wrapper mimeTypes = (Wrapper) context.getMimeTypes(); + mimeTypes.setWrapped(new MimeTypes(null)); + for (MimeMappings.Mapping mapping : getSettings().getMimeMappings()) { + mimeTypes.addMimeMapping(mapping.getExtension(), mapping.getMimeType()); + } + } + + }; + } + + /** + * Return a Jetty {@link Configuration} that will invoke the specified + * {@link ServletContextInitializer}s. By default this method will return a + * {@link ServletContextInitializerConfiguration}. + * @param webAppContext the Jetty {@link WebAppContext} + * @param initializers the {@link ServletContextInitializer}s to apply + * @return the {@link Configuration} instance + */ + protected Configuration getServletContextInitializerConfiguration(WebAppContext webAppContext, + ServletContextInitializers initializers) { + return new ServletContextInitializerConfiguration(initializers); + } + + /** + * Post process the Jetty {@link WebAppContext} before it's used with the Jetty + * Server. Subclasses can override this method to apply additional processing to the + * {@link WebAppContext}. + * @param webAppContext the Jetty {@link WebAppContext} + */ + protected void postProcessWebAppContext(WebAppContext webAppContext) { + } + + /** + * Factory method called to create the {@link JettyWebServer}. Subclasses can override + * this method to return a different {@link JettyWebServer} or apply additional + * processing to the Jetty server. + * @param server the Jetty server. + * @return a new {@link JettyWebServer} instance + */ + protected JettyWebServer getJettyWebServer(Server server) { + return new JettyServletWebServer(server, getPort() >= 0); + } + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + private void addJettyErrorPages(ErrorHandler errorHandler, Collection errorPages) { + if (errorHandler instanceof ErrorPageErrorHandler handler) { + for (ErrorPage errorPage : errorPages) { + if (errorPage.isGlobal()) { + handler.addErrorPage(ErrorPageErrorHandler.GLOBAL_ERROR_PAGE, errorPage.getPath()); + } + else { + if (errorPage.getExceptionName() != null) { + handler.addErrorPage(errorPage.getExceptionName(), errorPage.getPath()); + } + else { + handler.addErrorPage(errorPage.getStatusCode(), errorPage.getPath()); + } + } + } + } + } + + @Override + public ServletWebServerSettings getSettings() { + return this.settings; + } + + /** + * {@link AbstractConfiguration} to apply {@code @WebListener} classes. + */ + private static class WebListenersConfiguration extends AbstractConfiguration { + + private final Set classNames; + + WebListenersConfiguration(Set webListenerClassNames) { + super(new AbstractConfiguration.Builder()); + this.classNames = webListenerClassNames; + } + + @Override + public void configure(WebAppContext context) throws Exception { + ServletHandler servletHandler = context.getServletHandler(); + for (String className : this.classNames) { + configure(context, servletHandler, className); + } + } + + private void configure(WebAppContext context, ServletHandler servletHandler, String className) + throws ClassNotFoundException { + ListenerHolder holder = servletHandler.newListenerHolder(new Source(Source.Origin.ANNOTATION, className)); + holder.setHeldClass(loadClass(context, className)); + servletHandler.addListener(holder); + } + + @SuppressWarnings("unchecked") + private Class loadClass(WebAppContext context, String className) + throws ClassNotFoundException { + ClassLoader classLoader = context.getClassLoader(); + classLoader = (classLoader != null) ? classLoader : getClass().getClassLoader(); + return (Class) classLoader.loadClass(className); + } + + } + + /** + * {@link Handler.Wrapper} to apply {@link CookieSameSiteSupplier supplied} + * {@link SameSite} cookie values. + */ + private static class SuppliedSameSiteCookieHandlerWrapper extends Handler.Wrapper { + + private static final SetCookieParser setCookieParser = SetCookieParser.newInstance(); + + private final String sessionCookieName; + + private final List suppliers; + + SuppliedSameSiteCookieHandlerWrapper(String sessionCookieName, + List suppliers) { + this.sessionCookieName = sessionCookieName; + this.suppliers = suppliers; + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception { + SuppliedSameSiteCookieResponse wrappedResponse = new SuppliedSameSiteCookieResponse(request, response); + return super.handle(request, wrappedResponse, callback); + } + + private class SuppliedSameSiteCookieResponse extends Response.Wrapper { + + private final HttpFields.Mutable wrappedHeaders; + + SuppliedSameSiteCookieResponse(Request request, Response wrapped) { + super(request, wrapped); + this.wrappedHeaders = new SuppliedSameSiteCookieHeaders( + request.getConnectionMetaData().getHttpConfiguration().getResponseCookieCompliance(), + wrapped.getHeaders()); + } + + @Override + public Mutable getHeaders() { + return this.wrappedHeaders; + } + + } + + private class SuppliedSameSiteCookieHeaders extends HttpFields.Mutable.Wrapper { + + private final CookieCompliance compliance; + + SuppliedSameSiteCookieHeaders(CookieCompliance compliance, HttpFields.Mutable fields) { + super(fields); + this.compliance = compliance; + } + + @Override + public HttpField onAddField(HttpField field) { + return (field.getHeader() != HttpHeader.SET_COOKIE) ? field : onAddSetCookieField(field); + } + + private HttpField onAddSetCookieField(HttpField field) { + HttpCookie cookie = setCookieParser.parse(field.getValue()); + if (cookie == null || isSessionCookie(cookie)) { + return field; + } + SameSite sameSite = getSameSite(cookie); + if (sameSite == null) { + return field; + } + HttpCookie updatedCookie = buildCookieWithUpdatedSameSite(cookie, sameSite); + return new HttpCookieUtils.SetCookieHttpField(updatedCookie, this.compliance); + } + + private boolean isSessionCookie(HttpCookie cookie) { + return SuppliedSameSiteCookieHandlerWrapper.this.sessionCookieName.equals(cookie.getName()); + } + + private HttpCookie buildCookieWithUpdatedSameSite(HttpCookie cookie, SameSite sameSite) { + return HttpCookie.build(cookie) + .sameSite(org.eclipse.jetty.http.HttpCookie.SameSite.from(sameSite.name())) + .build(); + } + + private SameSite getSameSite(HttpCookie cookie) { + return getSameSite(asServletCookie(cookie)); + } + + private SameSite getSameSite(Cookie cookie) { + return SuppliedSameSiteCookieHandlerWrapper.this.suppliers.stream() + .map((supplier) -> supplier.getSameSite(cookie)) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); + } + + private Cookie asServletCookie(HttpCookie cookie) { + Cookie servletCookie = new Cookie(cookie.getName(), cookie.getValue()); + cookie.getAttributes().forEach(servletCookie::setAttribute); + return servletCookie; + } + + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/LoaderHidingResource.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/LoaderHidingResource.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/LoaderHidingResource.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/LoaderHidingResource.java index 9e6dcfed611a..8169e1cf16ab 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/LoaderHidingResource.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/LoaderHidingResource.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty.servlet; import java.io.IOException; import java.io.InputStream; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ServletContextInitializerConfiguration.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/ServletContextInitializerConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ServletContextInitializerConfiguration.java rename to spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/ServletContextInitializerConfiguration.java index 81b6afa4b3da..2042b992eaa8 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/ServletContextInitializerConfiguration.java +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/ServletContextInitializerConfiguration.java @@ -14,13 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty.servlet; import jakarta.servlet.ServletException; import org.eclipse.jetty.ee10.webapp.AbstractConfiguration; import org.eclipse.jetty.ee10.webapp.Configuration; import org.eclipse.jetty.ee10.webapp.WebAppContext; +import org.springframework.boot.web.server.servlet.ServletContextInitializers; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.util.Assert; @@ -29,18 +30,16 @@ * * @author Phillip Webb * @author Andy Wilkinson - * @since 2.0.0 */ -public class ServletContextInitializerConfiguration extends AbstractConfiguration { +class ServletContextInitializerConfiguration extends AbstractConfiguration { - private final ServletContextInitializer[] initializers; + private final ServletContextInitializers initializers; /** * Create a new {@link ServletContextInitializerConfiguration}. * @param initializers the initializers that should be invoked - * @since 1.2.1 */ - public ServletContextInitializerConfiguration(ServletContextInitializer... initializers) { + ServletContextInitializerConfiguration(ServletContextInitializers initializers) { super(new AbstractConfiguration.Builder()); Assert.notNull(initializers, "'initializers' must not be null"); this.initializers = initializers; diff --git a/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/package-info.java b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/package-info.java new file mode 100644 index 000000000000..67911f859fe6 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Servlet web server implementation backed by Jetty. + */ +package org.springframework.boot.jetty.servlet; diff --git a/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..51c6d7bdd719 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,62 @@ +{ + "groups": [], + "properties": [ + { + "name": "server.jetty.accesslog.date-format", + "deprecation": { + "replacement": "server.jetty.accesslog.custom-format", + "level": "error" + } + }, + { + "name": "server.jetty.accesslog.extended-format", + "deprecation": { + "replacement": "server.jetty.accesslog.format", + "level": "error" + } + }, + { + "name": "server.jetty.accesslog.locale", + "deprecation": { + "replacement": "server.jetty.accesslog.custom-format", + "level": "error" + } + }, + { + "name": "server.jetty.accesslog.log-cookies", + "deprecation": { + "replacement": "server.jetty.accesslog.custom-format", + "level": "error" + } + }, + { + "name": "server.jetty.accesslog.log-latency", + "deprecation": { + "replacement": "server.jetty.accesslog.custom-format", + "level": "error" + } + }, + { + "name": "server.jetty.accesslog.log-server", + "deprecation": { + "replacement": "server.jetty.accesslog.custom-format", + "level": "error" + } + }, + { + "name": "server.jetty.accesslog.time-zone", + "deprecation": { + "replacement": "server.jetty.accesslog.custom-format", + "level": "error" + } + }, + { + "name": "server.jetty.max-http-post-size", + "type": "org.springframework.util.unit.DataSize", + "deprecation": { + "replacement": "server.jetty.max-http-form-post-size", + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..d91f4a4ba0e3 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.jetty.autoconfigure.actuate.web.JettyReactiveManagementChildContextConfiguration +org.springframework.boot.jetty.autoconfigure.actuate.web.JettyServletManagementChildContextConfiguration diff --git a/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..5ac74036017f --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,5 @@ +org.springframework.boot.jetty.autoconfigure.actuate.web.JettyReactiveManagementContextAutoConfiguration +org.springframework.boot.jetty.autoconfigure.actuate.web.JettyServletManagementContextAutoConfiguration +org.springframework.boot.jetty.autoconfigure.metrics.JettyMetricsAutoConfiguration +org.springframework.boot.jetty.autoconfigure.reactive.JettyReactiveWebServerAutoConfiguration +org.springframework.boot.jetty.autoconfigure.servlet.JettyServletWebServerAutoConfiguration diff --git a/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/JettyAccess.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/JettyAccess.java new file mode 100644 index 000000000000..2b6ccfa27a55 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/JettyAccess.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty; + +/** + * Helper class to provide public access to package-private methods for testing purposes. + * + * @author Andy Wilkinson + */ +public final class JettyAccess { + + private JettyAccess() { + + } + + public static String getStartedLogMessage(JettyWebServer jettyWebServer) { + return jettyWebServer.getStartedLogMessage(); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizerTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/SslServerCustomizerTests.java similarity index 99% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizerTests.java rename to spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/SslServerCustomizerTests.java index efb48a1ac58f..32ec00ff73ae 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizerTests.java +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/SslServerCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty; import java.net.InetSocketAddress; import java.util.ArrayList; diff --git a/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyServerPropertiesTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyServerPropertiesTests.java new file mode 100644 index 000000000000..5369cc634a16 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyServerPropertiesTests.java @@ -0,0 +1,144 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure; + +import java.time.Duration; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.context.properties.source.ConfigurationPropertySource; +import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; +import org.springframework.boot.jetty.JettyWebServer; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JettyServerProperties}. + * + * @author Andy Wilkinson + */ +class JettyServerPropertiesTests { + + private final JettyServerProperties properties = new JettyServerProperties(); + + @Test + void testCustomizeJettyAcceptors() { + bind("server.jetty.threads.acceptors", "10"); + assertThat(this.properties.getThreads().getAcceptors()).isEqualTo(10); + } + + @Test + void testCustomizeJettySelectors() { + bind("server.jetty.threads.selectors", "10"); + assertThat(this.properties.getThreads().getSelectors()).isEqualTo(10); + } + + @Test + void testCustomizeJettyMaxThreads() { + bind("server.jetty.threads.max", "10"); + assertThat(this.properties.getThreads().getMax()).isEqualTo(10); + } + + @Test + void testCustomizeJettyMinThreads() { + bind("server.jetty.threads.min", "10"); + assertThat(this.properties.getThreads().getMin()).isEqualTo(10); + } + + @Test + void testCustomizeJettyIdleTimeout() { + bind("server.jetty.threads.idle-timeout", "10s"); + assertThat(this.properties.getThreads().getIdleTimeout()).isEqualTo(Duration.ofSeconds(10)); + } + + @Test + void testCustomizeJettyMaxQueueCapacity() { + bind("server.jetty.threads.max-queue-capacity", "5150"); + assertThat(this.properties.getThreads().getMaxQueueCapacity()).isEqualTo(5150); + } + + @Test + void testCustomizeJettyAccessLog() { + Map map = new HashMap<>(); + map.put("server.jetty.accesslog.enabled", "true"); + map.put("server.jetty.accesslog.filename", "foo.txt"); + map.put("server.jetty.accesslog.file-date-format", "yyyymmdd"); + map.put("server.jetty.accesslog.retention-period", "4"); + map.put("server.jetty.accesslog.append", "true"); + map.put("server.jetty.accesslog.custom-format", "{client}a - %u %t \"%r\" %s %O"); + map.put("server.jetty.accesslog.ignore-paths", "/a/path,/b/path"); + bind(map); + assertThat(this.properties.getAccesslog().isEnabled()).isTrue(); + assertThat(this.properties.getAccesslog().getFilename()).isEqualTo("foo.txt"); + assertThat(this.properties.getAccesslog().getFileDateFormat()).isEqualTo("yyyymmdd"); + assertThat(this.properties.getAccesslog().getRetentionPeriod()).isEqualTo(4); + assertThat(this.properties.getAccesslog().isAppend()).isTrue(); + assertThat(this.properties.getAccesslog().getCustomFormat()).isEqualTo("{client}a - %u %t \"%r\" %s %O"); + assertThat(this.properties.getAccesslog().getIgnorePaths()).containsExactly("/a/path", "/b/path"); + } + + @Test + void jettyThreadPoolPropertyDefaultsShouldMatchServerDefault() { + JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0); + JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer(); + Server server = jetty.getServer(); + QueuedThreadPool threadPool = (QueuedThreadPool) server.getThreadPool(); + int idleTimeout = threadPool.getIdleTimeout(); + int maxThreads = threadPool.getMaxThreads(); + int minThreads = threadPool.getMinThreads(); + assertThat(this.properties.getThreads().getIdleTimeout().toMillis()).isEqualTo(idleTimeout); + assertThat(this.properties.getThreads().getMax()).isEqualTo(maxThreads); + assertThat(this.properties.getThreads().getMin()).isEqualTo(minThreads); + } + + @Test + void jettyMaxHttpFormPostSizeMatchesDefault() { + JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0); + JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer(); + Server server = jetty.getServer(); + assertThat(this.properties.getMaxHttpFormPostSize().toBytes()) + .isEqualTo(((ServletContextHandler) server.getHandler()).getMaxFormContentSize()); + } + + @Test + void jettyMaxFormKeysMatchesDefault() { + JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0); + JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer(); + Server server = jetty.getServer(); + assertThat(this.properties.getMaxFormKeys()) + .isEqualTo(((ServletContextHandler) server.getHandler()).getMaxFormKeys()); + } + + private void bind(String name, String value) { + bind(Collections.singletonMap(name, value)); + } + + private void bind(Map map) { + ConfigurationPropertySource source = new MapConfigurationPropertySource(map); + new Binder(source).bind("server.jetty", Bindable.ofInstance(this.properties)); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/JettyVirtualThreadsWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/JettyVirtualThreadsWebServerFactoryCustomizerTests.java rename to spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java index 0a8da9b207ab..935493da00f2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/JettyVirtualThreadsWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.jetty.autoconfigure; import java.time.Duration; import java.util.concurrent.Executor; @@ -27,8 +27,7 @@ import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.JRE; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.assertArg; @@ -45,7 +44,7 @@ class JettyVirtualThreadsWebServerFactoryCustomizerTests { @Test @EnabledForJreRange(min = JRE.JAVA_21) void shouldConfigureVirtualThreads() { - ServerProperties properties = new ServerProperties(); + JettyServerProperties properties = new JettyServerProperties(); JettyVirtualThreadsWebServerFactoryCustomizer customizer = new JettyVirtualThreadsWebServerFactoryCustomizer( properties); ConfigurableJettyWebServerFactory factory = mock(ConfigurableJettyWebServerFactory.class); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/JettyWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerFactoryCustomizerTests.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/JettyWebServerFactoryCustomizerTests.java rename to spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerFactoryCustomizerTests.java index 2e8ae8c94a1e..19ab90209c16 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/JettyWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerFactoryCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.jetty.autoconfigure; import java.io.File; import java.io.IOException; @@ -41,16 +41,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy; -import org.springframework.boot.autoconfigure.web.ServerProperties.Jetty; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.jetty.JettyWebServer; +import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.jetty.JettyWebServer; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties.ForwardHeadersStrategy; import org.springframework.mock.env.MockEnvironment; import org.springframework.test.context.support.TestPropertySourceUtils; import org.springframework.test.util.ReflectionTestUtils; @@ -66,21 +64,22 @@ * @author Phillip Webb * @author HaiTao Zhang */ -@DirtiesUrlFactories +// @DirtiesUrlFactories class JettyWebServerFactoryCustomizerTests { - private MockEnvironment environment; + private final MockEnvironment environment = new MockEnvironment(); - private ServerProperties serverProperties; + private final ServerProperties serverProperties = new ServerProperties(); + + private final JettyServerProperties jettyProperties = new JettyServerProperties(); private JettyWebServerFactoryCustomizer customizer; @BeforeEach void setup() { - this.environment = new MockEnvironment(); - this.serverProperties = new ServerProperties(); ConfigurationPropertySources.attach(this.environment); - this.customizer = new JettyWebServerFactoryCustomizer(this.environment, this.serverProperties); + this.customizer = new JettyWebServerFactoryCustomizer(this.environment, this.serverProperties, + this.jettyProperties); } @Test @@ -235,7 +234,7 @@ void threadPoolWithMaxQueueCapacityPositiveCustomizesThreadPool() { private void assertDefaultThreadPoolSettings(ThreadPool threadPool) { assertThat(threadPool).isInstanceOf(QueuedThreadPool.class); QueuedThreadPool queuedThreadPool = (QueuedThreadPool) threadPool; - Jetty defaultProperties = new Jetty(); + JettyServerProperties defaultProperties = new JettyServerProperties(); assertThat(queuedThreadPool.getMinThreads()).isEqualTo(defaultProperties.getThreads().getMin()); assertThat(queuedThreadPool.getMaxThreads()).isEqualTo(defaultProperties.getThreads().getMax()); assertThat(queuedThreadPool.getIdleTimeout()) @@ -384,8 +383,9 @@ private BlockingQueue getQueue(ThreadPool threadPool) { private void bind(String... inlinedProperties) { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, inlinedProperties); - new Binder(ConfigurationPropertySources.get(this.environment)).bind("server", - Bindable.ofInstance(this.serverProperties)); + Binder binder = new Binder(ConfigurationPropertySources.get(this.environment)); + binder.bind("server", Bindable.ofInstance(this.serverProperties)); + binder.bind("server.jetty", Bindable.ofInstance(this.jettyProperties)); } private JettyWebServer customizeAndGetServer() { diff --git a/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyManagementServerPropertiesTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyManagementServerPropertiesTests.java new file mode 100644 index 000000000000..e6d6a74ee2ab --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/actuate/web/JettyManagementServerPropertiesTests.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.actuate.web; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JettyManagementServerProperties}. + * + * @author Andy Wilkinson + */ +class JettyManagementServerPropertiesTests { + + @Test + void accessLogsArePrefixedByDefault() { + JettyManagementServerProperties properties = new JettyManagementServerProperties(); + assertThat(properties.getAccesslog().getPrefix()).isEqualTo("management_"); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/metrics/JettyMetricsAutoConfigurationTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/metrics/JettyMetricsAutoConfigurationTests.java index 99275563ad7e..bcc972861f32 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/metrics/JettyMetricsAutoConfigurationTests.java @@ -14,28 +14,29 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.web.jetty; +package org.springframework.boot.jetty.autoconfigure.metrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.boot.SpringApplication; -import org.springframework.boot.actuate.metrics.web.jetty.JettyConnectionMetricsBinder; -import org.springframework.boot.actuate.metrics.web.jetty.JettyServerThreadPoolMetricsBinder; -import org.springframework.boot.actuate.metrics.web.jetty.JettySslHandshakeMetricsBinder; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.boot.jetty.autoconfigure.reactive.JettyReactiveWebServerAutoConfiguration; +import org.springframework.boot.jetty.autoconfigure.servlet.JettyServletWebServerAutoConfiguration; +import org.springframework.boot.jetty.metrics.JettyConnectionMetricsBinder; +import org.springframework.boot.jetty.metrics.JettyServerThreadPoolMetricsBinder; +import org.springframework.boot.jetty.metrics.JettySslHandshakeMetricsBinder; +import org.springframework.boot.jetty.reactive.JettyReactiveWebServerFactory; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; -import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -56,13 +57,13 @@ class JettyMetricsAutoConfigurationTests { void autoConfiguresThreadPoolMetricsWithEmbeddedServletJetty() { new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + JettyServletWebServerAutoConfiguration.class)) .withUserConfiguration(ServletWebServerConfiguration.class, MeterRegistryConfiguration.class) .run((context) -> { context.publishEvent(createApplicationStartedEvent(context.getSourceApplicationContext())); assertThat(context).hasSingleBean(JettyServerThreadPoolMetricsBinder.class); SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class); - assertThat(registry.find("jetty.threads.config.min").meter()).isNotNull(); + Assertions.assertThat(registry.find("jetty.threads.config.min").meter()).isNotNull(); }); } @@ -70,12 +71,12 @@ void autoConfiguresThreadPoolMetricsWithEmbeddedServletJetty() { void autoConfiguresThreadPoolMetricsWithEmbeddedReactiveJetty() { new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ReactiveWebServerFactoryAutoConfiguration.class)) + JettyReactiveWebServerAutoConfiguration.class)) .withUserConfiguration(ReactiveWebServerConfiguration.class, MeterRegistryConfiguration.class) .run((context) -> { context.publishEvent(createApplicationStartedEvent(context.getSourceApplicationContext())); SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class); - assertThat(registry.find("jetty.threads.config.min").meter()).isNotNull(); + Assertions.assertThat(registry.find("jetty.threads.config.min").meter()).isNotNull(); }); } @@ -91,13 +92,13 @@ void allowsCustomJettyServerThreadPoolMetricsBinderToBeUsed() { void autoConfiguresConnectionMetricsWithEmbeddedServletJetty() { new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + JettyServletWebServerAutoConfiguration.class)) .withUserConfiguration(ServletWebServerConfiguration.class, MeterRegistryConfiguration.class) .run((context) -> { context.publishEvent(createApplicationStartedEvent(context.getSourceApplicationContext())); assertThat(context).hasSingleBean(JettyConnectionMetricsBinder.class); SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class); - assertThat(registry.find("jetty.connections.messages.in").meter()).isNotNull(); + Assertions.assertThat(registry.find("jetty.connections.messages.in").meter()).isNotNull(); }); } @@ -105,12 +106,12 @@ void autoConfiguresConnectionMetricsWithEmbeddedServletJetty() { void autoConfiguresConnectionMetricsWithEmbeddedReactiveJetty() { new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ReactiveWebServerFactoryAutoConfiguration.class)) + JettyReactiveWebServerAutoConfiguration.class)) .withUserConfiguration(ReactiveWebServerConfiguration.class, MeterRegistryConfiguration.class) .run((context) -> { context.publishEvent(createApplicationStartedEvent(context.getSourceApplicationContext())); SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class); - assertThat(registry.find("jetty.connections.messages.in").meter()).isNotNull(); + Assertions.assertThat(registry.find("jetty.connections.messages.in").meter()).isNotNull(); }); } @@ -118,7 +119,7 @@ void autoConfiguresConnectionMetricsWithEmbeddedReactiveJetty() { void allowsCustomJettyConnectionMetricsBinderToBeUsed() { new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + JettyServletWebServerAutoConfiguration.class)) .withUserConfiguration(ServletWebServerConfiguration.class, CustomJettyConnectionMetricsBinder.class, MeterRegistryConfiguration.class) .run((context) -> { @@ -126,9 +127,11 @@ void allowsCustomJettyConnectionMetricsBinderToBeUsed() { assertThat(context).hasSingleBean(JettyConnectionMetricsBinder.class) .hasBean("customJettyConnectionMetricsBinder"); SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class); - assertThat(registry.find("jetty.connections.messages.in") - .tag("custom-tag-name", "custom-tag-value") - .meter()).isNotNull(); + Assertions + .assertThat(registry.find("jetty.connections.messages.in") + .tag("custom-tag-name", "custom-tag-value") + .meter()) + .isNotNull(); }); } @@ -137,7 +140,7 @@ void allowsCustomJettyConnectionMetricsBinderToBeUsed() { void autoConfiguresSslHandshakeMetricsWithEmbeddedServletJetty() { new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + JettyServletWebServerAutoConfiguration.class)) .withUserConfiguration(ServletWebServerConfiguration.class, MeterRegistryConfiguration.class) .withPropertyValues("server.ssl.enabled=true", "server.ssl.key-store=classpath:test.jks", "server.ssl.key-store-password=secret", "server.ssl.key-password=password") @@ -145,7 +148,7 @@ void autoConfiguresSslHandshakeMetricsWithEmbeddedServletJetty() { context.publishEvent(createApplicationStartedEvent(context.getSourceApplicationContext())); assertThat(context).hasSingleBean(JettySslHandshakeMetricsBinder.class); SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class); - assertThat(registry.find("jetty.ssl.handshakes").meter()).isNotNull(); + Assertions.assertThat(registry.find("jetty.ssl.handshakes").meter()).isNotNull(); }); } @@ -154,14 +157,14 @@ void autoConfiguresSslHandshakeMetricsWithEmbeddedServletJetty() { void autoConfiguresSslHandshakeMetricsWithEmbeddedReactiveJetty() { new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ReactiveWebServerFactoryAutoConfiguration.class)) + JettyReactiveWebServerAutoConfiguration.class)) .withUserConfiguration(ReactiveWebServerConfiguration.class, MeterRegistryConfiguration.class) .withPropertyValues("server.ssl.enabled=true", "server.ssl.key-store=classpath:test.jks", "server.ssl.key-store-password=secret", "server.ssl.key-password=password") .run((context) -> { context.publishEvent(createApplicationStartedEvent(context.getSourceApplicationContext())); SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class); - assertThat(registry.find("jetty.ssl.handshakes").meter()).isNotNull(); + Assertions.assertThat(registry.find("jetty.ssl.handshakes").meter()).isNotNull(); }); } @@ -170,7 +173,7 @@ void autoConfiguresSslHandshakeMetricsWithEmbeddedReactiveJetty() { void allowsCustomJettySslHandshakeMetricsBinderToBeUsed() { new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + JettyServletWebServerAutoConfiguration.class)) .withUserConfiguration(ServletWebServerConfiguration.class, CustomJettySslHandshakeMetricsBinder.class, MeterRegistryConfiguration.class) .withPropertyValues("server.ssl.enabled=true", "server.ssl.key-store=classpath:test.jks", @@ -180,7 +183,9 @@ void allowsCustomJettySslHandshakeMetricsBinderToBeUsed() { assertThat(context).hasSingleBean(JettySslHandshakeMetricsBinder.class) .hasBean("customJettySslHandshakeMetricsBinder"); SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class); - assertThat(registry.find("jetty.ssl.handshakes").tag("custom-tag-name", "custom-tag-value").meter()) + Assertions + .assertThat( + registry.find("jetty.ssl.handshakes").tag("custom-tag-name", "custom-tag-value").meter()) .isNotNull(); }); @@ -196,7 +201,7 @@ void allowsCustomJettySslHandshakeMetricsBinderToBeUsed() { void doesNotAutoConfigureSslHandshakeMetricsWhenSslEnabledPropertyNotSpecified() { new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + JettyServletWebServerAutoConfiguration.class)) .withUserConfiguration(ServletWebServerConfiguration.class, MeterRegistryConfiguration.class) .run((context) -> assertThat(context).doesNotHaveBean(JettySslHandshakeMetricsBinder.class)); } @@ -205,7 +210,7 @@ void doesNotAutoConfigureSslHandshakeMetricsWhenSslEnabledPropertyNotSpecified() void doesNotAutoConfigureSslHandshakeMetricsWhenSslEnabledPropertySetToFalse() { new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(JettyMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + JettyServletWebServerAutoConfiguration.class)) .withUserConfiguration(ServletWebServerConfiguration.class, MeterRegistryConfiguration.class) .withPropertyValues("server.ssl.enabled: false") .run((context) -> assertThat(context).doesNotHaveBean(JettySslHandshakeMetricsBinder.class)); diff --git a/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/reactive/JettyReactiveWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/reactive/JettyReactiveWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..10e4c06f5ccf --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/reactive/JettyReactiveWebServerAutoConfigurationTests.java @@ -0,0 +1,116 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.reactive; + +import jakarta.websocket.server.ServerContainer; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.StatisticsHandler; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.JettyWebServer; +import org.springframework.boot.jetty.reactive.JettyReactiveWebServerFactory; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.reactive.AbstractReactiveWebServerAutoConfigurationTests; +import org.springframework.boot.web.server.reactive.context.ReactiveWebServerApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link JettyReactiveWebServerAutoConfiguration}. + * + * @author Brian Clozel + * @author Raheela Aslam + * @author Madhura Bhave + * @author Scott Frederick + */ +class JettyReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests { + + JettyReactiveWebServerAutoConfigurationTests() { + super(JettyReactiveWebServerAutoConfiguration.class); + } + + @Test + void jettyServerCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(JettyServerCustomizerConfiguration.class).run((context) -> { + JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class); + assertThat(factory.getServerCustomizers()) + .contains(context.getBean("serverCustomizer", JettyServerCustomizer.class)); + }); + } + + @Test + void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class) + .run((context) -> { + JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class); + JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class); + assertThat(factory.getServerCustomizers()).contains(customizer); + then(customizer).should().customize(any(Server.class)); + }); + } + + @Test + void webSocketServerContainerIsAvailableFromServletContext() { + this.serverRunner.run((context) -> { + WebServer webServer = ((ReactiveWebServerApplicationContext) context.getSourceApplicationContext()) + .getWebServer(); + ServletContextHandler servletContextHandler = (ServletContextHandler) ((StatisticsHandler) ((JettyWebServer) webServer) + .getServer() + .getHandler()).getHandler(); + Object serverContainer = servletContextHandler.getContext() + .getAttribute("jakarta.websocket.server.ServerContainer"); + assertThat(serverContainer).isInstanceOf(ServerContainer.class); + }); + } + + @Configuration(proxyBeanMethods = false) + static class JettyServerCustomizerConfiguration { + + @Bean + JettyServerCustomizer serverCustomizer() { + return (server) -> { + }; + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationJettyServerCustomizerConfiguration { + + private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class); + + @Bean + JettyServerCustomizer serverCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer jettyCustomizer() { + return (jetty) -> jetty.addServerCustomizers(this.customizer); + } + + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..70eaaabaee93 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerAutoConfigurationTests.java @@ -0,0 +1,148 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.servlet; + +import java.util.Map; + +import jakarta.servlet.Filter; +import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter; +import org.eclipse.jetty.server.Server; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.boot.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.servlet.AbstractServletWebServerAutoConfigurationTests; +import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletContextInitializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Base class for testing sub-classes of {@link JettyServletWebServerAutoConfiguration}. + * + * @author Dave Syer + * @author Phillip Webb + * @author Stephane Nicoll + * @author Raheela Aslam + * @author Madhura Bhave + */ +class JettyServletWebServerAutoConfigurationTests extends AbstractServletWebServerAutoConfigurationTests { + + protected JettyServletWebServerAutoConfigurationTests() { + super(JettyServletWebServerAutoConfiguration.class); + } + + @Test + void jettyServerCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(JettyServerCustomizerConfiguration.class).run((context) -> { + JettyServletWebServerFactory factory = context.getBean(JettyServletWebServerFactory.class); + assertThat(factory.getServerCustomizers()) + .contains(context.getBean("serverCustomizer", JettyServerCustomizer.class)); + }); + } + + @Test + void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class) + .run((context) -> { + JettyServletWebServerFactory factory = context.getBean(JettyServletWebServerFactory.class); + JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class); + assertThat(factory.getServerCustomizers()).contains(customizer); + then(customizer).should().customize(any(Server.class)); + }); + } + + @Test + void jettyWebSocketUpgradeFilterIsAddedToServletContex() { + this.serverRunner.run((context) -> assertThat( + context.getServletContext().getFilterRegistration(WebSocketUpgradeFilter.class.getName())) + .isNotNull()); + } + + @Test + @SuppressWarnings("rawtypes") + void jettyWebSocketUpgradeFilterIsNotExposedAsABean() { + this.serverRunner.run((context) -> { + Map filters = context.getBeansOfType(Filter.class); + assertThat(filters.values()).noneMatch(WebSocketUpgradeFilter.class::isInstance); + Map filterRegistrations = context + .getBeansOfType(AbstractFilterRegistrationBean.class); + assertThat(filterRegistrations.values()).extracting(AbstractFilterRegistrationBean::getFilter) + .noneMatch(WebSocketUpgradeFilter.class::isInstance); + }); + } + + @Test + void jettyWebSocketUpgradeFilterServletContextInitializerBacksOffWhenBeanWithSameNameIsDefined() { + this.serverRunner + .withUserConfiguration(CustomWebSocketUpgradeFilterServletContextInitializerConfiguration.class) + .run((context) -> { + BeanDefinition definition = context.getBeanFactory() + .getBeanDefinition("websocketUpgradeFilterServletContextInitializer"); + assertThat(definition.getFactoryBeanName()) + .contains("CustomWebSocketUpgradeFilterServletContextInitializerConfiguration"); + }); + } + + @Configuration(proxyBeanMethods = false) + static class JettyServerCustomizerConfiguration { + + @Bean + JettyServerCustomizer serverCustomizer() { + return (server) -> { + }; + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationJettyServerCustomizerConfiguration { + + private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class); + + @Bean + JettyServerCustomizer serverCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer jettyCustomizer() { + return (jetty) -> jetty.addServerCustomizers(this.customizer); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomWebSocketUpgradeFilterServletContextInitializerConfiguration { + + @Bean + ServletContextInitializer websocketUpgradeFilterServletContextInitializer() { + return (servletContext) -> { + + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerServletContextListenerTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerServletContextListenerTests.java new file mode 100644 index 000000000000..c75a0d30ad6e --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/servlet/JettyServletWebServerServletContextListenerTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.autoconfigure.servlet; + +import jakarta.servlet.ServletContextListener; + +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; +import org.springframework.boot.web.server.servlet.AbstractServletWebServerServletContextListenerTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Tests for Jetty driving {@link ServletContextListener}s correctly. + * + * @author Andy Wilkinson + */ +class JettyServletWebServerServletContextListenerTests extends AbstractServletWebServerServletContextListenerTests { + + JettyServletWebServerServletContextListenerTests() { + super(JettyConfiguration.class); + } + + @Configuration(proxyBeanMethods = false) + static class JettyConfiguration { + + @Bean + JettyServletWebServerFactory webServerFactory() { + return new JettyServletWebServerFactory(0); + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/reactive/JettyReactiveWebServerFactoryTests.java similarity index 92% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactoryTests.java rename to spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/reactive/JettyReactiveWebServerFactoryTests.java index c02b568a2984..bddbf14c10dc 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/reactive/JettyReactiveWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty.reactive; import java.net.ConnectException; import java.net.InetAddress; @@ -31,11 +31,14 @@ import org.junit.jupiter.api.Test; import org.mockito.InOrder; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests; +import org.springframework.boot.jetty.JettyAccess; +import org.springframework.boot.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.JettyWebServer; import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl.ServerNameSslBundle; +import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactoryTests; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.web.reactive.function.client.WebClient; @@ -165,11 +168,11 @@ void sslServerNameBundlesConfigurationThrowsException() { @Override protected String startedLogMessage() { - return ((JettyWebServer) this.webServer).getStartedLogMessage(); + return JettyAccess.getStartedLogMessage((JettyWebServer) this.webServer); } @Override - protected void addConnector(int port, AbstractReactiveWebServerFactory factory) { + protected void addConnector(int port, ConfigurableReactiveWebServerFactory factory) { ((JettyReactiveWebServerFactory) factory).addServerCustomizers((server) -> { ServerConnector connector = new ServerConnector(server); connector.setPort(port); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/JettyServletWebServerFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java rename to spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/JettyServletWebServerFactoryTests.java index e1d6da2bdff7..e155e639e132 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/JettyServletWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty.servlet; import java.lang.reflect.Method; import java.net.InetAddress; @@ -62,6 +62,9 @@ import org.junit.jupiter.api.Test; import org.mockito.InOrder; +import org.springframework.boot.jetty.JettyAccess; +import org.springframework.boot.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.JettyWebServer; import org.springframework.boot.testsupport.classpath.resources.ResourcePath; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; import org.springframework.boot.testsupport.system.CapturedOutput; @@ -72,8 +75,8 @@ import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl.ServerNameSslBundle; import org.springframework.boot.web.server.WebServerException; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests; +import org.springframework.boot.web.server.servlet.AbstractServletWebServerFactoryTests; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -111,7 +114,7 @@ protected JettyServletWebServerFactory getFactory() { } @Override - protected void addConnector(int port, AbstractServletWebServerFactory factory) { + protected void addConnector(int port, ConfigurableServletWebServerFactory factory) { ((JettyServletWebServerFactory) factory).addServerCustomizers((server) -> { ServerConnector connector = new ServerConnector(server); connector.setPort(port); @@ -170,7 +173,7 @@ protected void sslSessionTracking() { @Test void contextPathIsLoggedOnStartupWhenCompressionIsEnabled(CapturedOutput output) { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setContextPath("/custom"); Compression compression = new Compression(); compression.setEnabled(true); @@ -219,15 +222,15 @@ void jettyCustomizations() { @Test void sessionTimeout() { - JettyServletWebServerFactory factory = getFactory(); - factory.getSession().setTimeout(Duration.ofSeconds(10)); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getSession().setTimeout(Duration.ofSeconds(10)); assertTimeout(factory, 10); } @Test void sessionTimeoutInMinutes() { - JettyServletWebServerFactory factory = getFactory(); - factory.getSession().setTimeout(Duration.ofMinutes(1)); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getSession().setTimeout(Duration.ofMinutes(1)); assertTimeout(factory, 60); } @@ -317,7 +320,7 @@ private SslContextFactory extractSslContextFactory(SslConnectionFactory connecti @Test void whenServerIsShuttingDownGracefullyThenNewConnectionsCannotBeMade() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory.getWebServer((context) -> { @@ -342,7 +345,7 @@ void whenServerIsShuttingDownGracefullyThenNewConnectionsCannotBeMade() throws E @Test void whenServerIsShuttingDownGracefullyThenResponseToRequestOnIdleConnectionWillHaveAConnectionCloseHeader() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory.getWebServer((context) -> { @@ -377,7 +380,7 @@ void whenServerIsShuttingDownGracefullyThenResponseToRequestOnIdleConnectionWill @Test void whenARequestCompletesAfterGracefulShutdownHasBegunThenItHasAConnectionCloseHeader() throws InterruptedException, ExecutionException { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory.getWebServer((context) -> { @@ -408,7 +411,7 @@ private Ssl getSslSettings(String keyStore, String... enabledProtocols) { return ssl; } - private void assertTimeout(JettyServletWebServerFactory factory, int expected) { + private void assertTimeout(ConfigurableServletWebServerFactory factory, int expected) { this.webServer = factory.getWebServer(); JettyWebServer jettyWebServer = (JettyWebServer) this.webServer; WebAppContext webAppContext = findWebAppContext(jettyWebServer); @@ -582,7 +585,7 @@ void shouldApplyMaxConnectionsToConnectors() { @Override protected String startedLogMessage() { - return ((JettyWebServer) this.webServer).getStartedLogMessage(); + return JettyAccess.getStartedLogMessage((JettyWebServer) this.webServer); } private WebAppContext findWebAppContext(JettyWebServer webServer) { diff --git a/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/JettyServletWebServerMvcIntegrationTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/JettyServletWebServerMvcIntegrationTests.java new file mode 100644 index 000000000000..92d005283842 --- /dev/null +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/JettyServletWebServerMvcIntegrationTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jetty.servlet; + +import org.springframework.boot.jetty.JettyWebServer; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.context.AbstractServletWebServerMvcIntegrationTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Integration tests for {@link ServletWebServerApplicationContext} and + * {@link JettyWebServer} running Spring MVC. + */ +class JettyServletWebServerMvcIntegrationTests extends AbstractServletWebServerMvcIntegrationTests { + + protected JettyServletWebServerMvcIntegrationTests() { + super(JettyConfig.class); + } + + @Configuration(proxyBeanMethods = false) + static class JettyConfig { + + @Bean + JettyServletWebServerFactory webServerFactory() { + return new JettyServletWebServerFactory(0); + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/LoaderHidingResourceTests.java b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/LoaderHidingResourceTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/LoaderHidingResourceTests.java rename to spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/LoaderHidingResourceTests.java index 387b4fede544..2fcb8939d428 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/LoaderHidingResourceTests.java +++ b/spring-boot-project/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/servlet/LoaderHidingResourceTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.jetty; +package org.springframework.boot.jetty.servlet; import java.io.File; import java.io.FileOutputStream; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/test.jks b/spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/autoconfigure/metrics/test.jks similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/test.jks rename to spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/autoconfigure/metrics/test.jks diff --git a/spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/autoconfigure/test.jks b/spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/autoconfigure/test.jks new file mode 100644 index 000000000000..cc0d7081c2e2 Binary files /dev/null and b/spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/autoconfigure/test.jks differ diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/rsocket/netty/test.jks b/spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/servlet/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/rsocket/netty/test.jks rename to spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/servlet/test.jks diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/client/test.jks b/spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/client/test.jks rename to spring-boot-project/spring-boot-jetty/src/test/resources/org/springframework/boot/jetty/test.jks diff --git a/spring-boot-project/spring-boot-jms/build.gradle b/spring-boot-project/spring-boot-jms/build.gradle new file mode 100644 index 000000000000..20fa0e3eb940 --- /dev/null +++ b/spring-boot-project/spring-boot-jms/build.gradle @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot JMS" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-tx")) + api("jakarta.jms:jakarta.jms-api") + api("org.springframework:spring-jms") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-health")) + optional("jakarta.transaction:jakarta.transaction-api") + optional("org.messaginghub:pooled-jms") { + exclude group: "org.apache.geronimo.specs", module: "geronimo-jms_2.0_spec" + } + optional("org.springframework:spring-jdbc") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/ConnectionFactoryUnwrapper.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/ConnectionFactoryUnwrapper.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/ConnectionFactoryUnwrapper.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/ConnectionFactoryUnwrapper.java index 5f4c987d6dcf..72f061346bc4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/ConnectionFactoryUnwrapper.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/ConnectionFactoryUnwrapper.java @@ -26,7 +26,7 @@ * pooling. * * @author Stephane Nicoll - * @since 3.4.0 + * @since 4.0.0 */ public final class ConnectionFactoryUnwrapper { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/XAConnectionFactoryWrapper.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/XAConnectionFactoryWrapper.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/XAConnectionFactoryWrapper.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/XAConnectionFactoryWrapper.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/AcknowledgeMode.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/AcknowledgeMode.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/AcknowledgeMode.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/AcknowledgeMode.java index 3bf714ef52ab..d32245ad0731 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/AcknowledgeMode.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/AcknowledgeMode.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import java.util.HashMap; import java.util.Map; @@ -32,7 +32,7 @@ * handled through a call to {@link JmsAccessor#setSessionTransacted(boolean)}. * * @author Andy Wilkinson - * @since 3.2.0 + * @since 4.0.0 */ public final class AcknowledgeMode { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/DefaultJmsListenerContainerFactoryConfigurer.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/DefaultJmsListenerContainerFactoryConfigurer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/DefaultJmsListenerContainerFactoryConfigurer.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/DefaultJmsListenerContainerFactoryConfigurer.java index abed33d745f8..02eaeb1f8f75 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/DefaultJmsListenerContainerFactoryConfigurer.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/DefaultJmsListenerContainerFactoryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import java.time.Duration; @@ -22,8 +22,8 @@ import jakarta.jms.ConnectionFactory; import jakarta.jms.ExceptionListener; -import org.springframework.boot.autoconfigure.jms.JmsProperties.Listener.Session; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.jms.autoconfigure.JmsProperties.Listener.Session; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.destination.DestinationResolver; @@ -42,7 +42,7 @@ * @author Eddú Meléndez * @author Vedran Pavic * @author Lasse Wulff - * @since 1.3.3 + * @since 4.0.0 */ public final class DefaultJmsListenerContainerFactoryConfigurer { @@ -105,12 +105,8 @@ void setJmsProperties(JmsProperties jmsProperties) { /** * Set the {@link ObservationRegistry} to use. * @param observationRegistry the {@link ObservationRegistry} - * @since 3.2.1 - * @deprecated since 3.3.10 for removal in 4.0.0 as this should have been package - * private */ - @Deprecated(since = "3.3.10", forRemoval = true) - public void setObservationRegistry(ObservationRegistry observationRegistry) { + void setObservationRegistry(ObservationRegistry observationRegistry) { this.observationRegistry = observationRegistry; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAnnotationDrivenConfiguration.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsAnnotationDrivenConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAnnotationDrivenConfiguration.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsAnnotationDrivenConfiguration.java index 55b9dab80f88..d0587784796a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAnnotationDrivenConfiguration.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsAnnotationDrivenConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import io.micrometer.observation.ObservationRegistry; import jakarta.jms.ConnectionFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfiguration.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfiguration.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsAutoConfiguration.java index a291bca657d1..b0e85b5e9833 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import java.time.Duration; import java.util.List; @@ -34,11 +34,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration.JmsRuntimeHints; -import org.springframework.boot.autoconfigure.jms.JmsProperties.DeliveryMode; -import org.springframework.boot.autoconfigure.jms.JmsProperties.Template; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration.JmsRuntimeHints; +import org.springframework.boot.jms.autoconfigure.JmsProperties.DeliveryMode; +import org.springframework.boot.jms.autoconfigure.JmsProperties.Template; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -56,7 +56,7 @@ * @author Greg Turnquist * @author Stephane Nicoll * @author Vedran Pavic - * @since 1.0.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ Message.class, JmsTemplate.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryFactory.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsPoolConnectionFactoryFactory.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryFactory.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsPoolConnectionFactoryFactory.java index 9e3ea5d7a305..117db17549cf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryFactory.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsPoolConnectionFactoryFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import jakarta.jms.ConnectionFactory; import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; @@ -24,7 +24,7 @@ * {@link JmsPoolConnectionFactoryProperties}. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ public class JmsPoolConnectionFactoryFactory { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryProperties.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsPoolConnectionFactoryProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryProperties.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsPoolConnectionFactoryProperties.java index d87a759ed5d3..f617263e180d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryProperties.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsPoolConnectionFactoryProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import java.time.Duration; @@ -22,7 +22,7 @@ * Configuration properties for connection factory pooling. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ public class JmsPoolConnectionFactoryProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsProperties.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsProperties.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsProperties.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsProperties.java index a8792375da23..983ce4d35938 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsProperties.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JmsProperties.java @@ -14,12 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import java.time.Duration; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; /** * Configuration properties for JMS. @@ -29,7 +28,7 @@ * @author Stephane Nicoll * @author Lasse Wulff * @author Vedran Pavic - * @since 1.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.jms") public class JmsProperties { @@ -203,28 +202,6 @@ public void setAutoStartup(boolean autoStartup) { this.autoStartup = autoStartup; } - @Deprecated(since = "3.2.0", forRemoval = true) - @DeprecatedConfigurationProperty(replacement = "spring.jms.listener.session.acknowledge-mode", since = "3.2.0") - public AcknowledgeMode getAcknowledgeMode() { - return this.session.getAcknowledgeMode(); - } - - @Deprecated(since = "3.2.0", forRemoval = true) - public void setAcknowledgeMode(AcknowledgeMode acknowledgeMode) { - this.session.setAcknowledgeMode(acknowledgeMode); - } - - @DeprecatedConfigurationProperty(replacement = "spring.jms.listener.min-concurrency", since = "3.2.0") - @Deprecated(since = "3.2.0", forRemoval = true) - public Integer getConcurrency() { - return this.minConcurrency; - } - - @Deprecated(since = "3.2.0", forRemoval = true) - public void setConcurrency(Integer concurrency) { - this.minConcurrency = concurrency; - } - public Integer getMinConcurrency() { return this.minConcurrency; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JndiConnectionFactoryAutoConfiguration.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JndiConnectionFactoryAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JndiConnectionFactoryAutoConfiguration.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JndiConnectionFactoryAutoConfiguration.java index cb77c6d6a072..9279e438cc1c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JndiConnectionFactoryAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/JndiConnectionFactoryAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import java.util.Arrays; @@ -29,8 +29,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnJndi; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration.JndiOrPropertyCondition; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jms.autoconfigure.JndiConnectionFactoryAutoConfiguration.JndiOrPropertyCondition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.jms.core.JmsTemplate; @@ -41,7 +41,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for JMS provided from JNDI. * * @author Phillip Webb - * @since 1.2.0 + * @since 4.0.0 */ @AutoConfiguration(before = JmsAutoConfiguration.class) @ConditionalOnClass(JmsTemplate.class) diff --git a/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/health/JmsHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/health/JmsHealthContributorAutoConfiguration.java new file mode 100644 index 000000000000..aed24ab99779 --- /dev/null +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/health/JmsHealthContributorAutoConfiguration.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jms.autoconfigure.health; + +import jakarta.jms.ConnectionFactory; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration; +import org.springframework.boot.jms.health.JmsHealthIndicator; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for {@link JmsHealthIndicator}. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration(after = JmsAutoConfiguration.class) +@ConditionalOnClass({ ConnectionFactory.class, JmsHealthIndicator.class }) +@ConditionalOnBean(ConnectionFactory.class) +@ConditionalOnEnabledHealthIndicator("jms") +public class JmsHealthContributorAutoConfiguration + extends CompositeHealthContributorConfiguration { + + public JmsHealthContributorAutoConfiguration() { + super(JmsHealthIndicator::new); + } + + @Bean + @ConditionalOnMissingBean(name = { "jmsHealthIndicator", "jmsHealthContributor" }) + public HealthContributor jmsHealthContributor(ConfigurableListableBeanFactory beanFactory) { + return createContributor(beanFactory, ConnectionFactory.class); + } + +} diff --git a/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..329a5a0399e5 --- /dev/null +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JMS health. + */ +package org.springframework.boot.jms.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/package-info.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/package-info.java new file mode 100644 index 000000000000..4d7d4a8b980d --- /dev/null +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JMS. + */ +package org.springframework.boot.jms.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jms/JmsHealthIndicator.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/health/JmsHealthIndicator.java similarity index 90% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jms/JmsHealthIndicator.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/health/JmsHealthIndicator.java index b968e9d7d407..ac3681de69bd 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jms/JmsHealthIndicator.java +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/health/JmsHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.jms; +package org.springframework.boot.jms.health; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -25,15 +25,15 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; /** * {@link HealthIndicator} for a JMS {@link ConnectionFactory}. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public class JmsHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/health/package-info.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/health/package-info.java new file mode 100644 index 000000000000..9ce57fb93adf --- /dev/null +++ b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for JMS. + */ +package org.springframework.boot.jms.health; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/package-info.java b/spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/package-info.java rename to spring-boot-project/spring-boot-jms/src/main/java/org/springframework/boot/jms/package-info.java diff --git a/spring-boot-project/spring-boot-jms/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-jms/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..c47305a65f32 --- /dev/null +++ b/spring-boot-project/spring-boot-jms/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,62 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.health.jms.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable JMS health check.", + "defaultValue": true + }, + { + "name": "spring.jms.listener.acknowledge-mode", + "deprecation": { + "replacement": "spring.jms.listener.session.acknowledge-mode", + "since": "3.2.0" + } + }, + { + "name": "spring.jms.listener.concurrency", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.jms.listener.min-concurrency", + "since": "3.2.0" + } + } + ], + "hints": [ + { + "name": "spring.jms.listener.session.acknowledge-mode", + "values": [ + { + "value": "auto", + "description": "Messages sent or received from the session are automatically acknowledged. This is the simplest mode and enables once-only message delivery guarantee." + }, + { + "value": "client", + "description": "Messages are acknowledged once the message listener implementation has called \"jakarta.jms.Message#acknowledge()\". This mode gives the application (rather than the JMS provider) complete control over message acknowledgement." + }, + { + "value": "dups_ok", + "description": "Similar to auto acknowledgment except that said acknowledgment is lazy. As a consequence, the messages might be delivered more than once. This mode enables at-least-once message delivery guarantee." + } + ] + }, + { + "name": "spring.jms.template.session.acknowledge-mode", + "values": [ + { + "value": "auto", + "description": "Messages sent or received from the session are automatically acknowledged. This is the simplest mode and enables once-only message delivery guarantee." + }, + { + "value": "client", + "description": "Messages are acknowledged once the message listener implementation has called \"jakarta.jms.Message#acknowledge()\". This mode gives the application (rather than the JMS provider) complete control over message acknowledgement." + }, + { + "value": "dups_ok", + "description": "Similar to auto acknowledgment except that said acknowledgment is lazy. As a consequence, the messages might be delivered more than once. This mode enables at-least-once message delivery guarantee." + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-jms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-jms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..ca77e5b914f8 --- /dev/null +++ b/spring-boot-project/spring-boot-jms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration +org.springframework.boot.jms.autoconfigure.JndiConnectionFactoryAutoConfiguration +org.springframework.boot.jms.autoconfigure.health.JmsHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jms/ConnectionFactoryUnwrapperTests.java b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/ConnectionFactoryUnwrapperTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jms/ConnectionFactoryUnwrapperTests.java rename to spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/ConnectionFactoryUnwrapperTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/AcknowledgeModeTests.java b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/AcknowledgeModeTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/AcknowledgeModeTests.java rename to spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/AcknowledgeModeTests.java index a20afe9adcf5..e1060567dfd3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/AcknowledgeModeTests.java +++ b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/AcknowledgeModeTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import jakarta.jms.Session; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JmsAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JmsAutoConfigurationTests.java index f90fde2a912a..8f73fcbd1b7a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JmsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import io.micrometer.observation.ObservationRegistry; import jakarta.jms.ConnectionFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsPropertiesTests.java b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JmsPropertiesTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsPropertiesTests.java rename to spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JmsPropertiesTests.java index 650c6a0c401b..f51a0abcb9d0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsPropertiesTests.java +++ b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JmsPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JndiConnectionFactoryAutoConfigurationTests.java b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JndiConnectionFactoryAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JndiConnectionFactoryAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JndiConnectionFactoryAutoConfigurationTests.java index 3e5c4e3cc87f..fb1f43c25bf0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JndiConnectionFactoryAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/JndiConnectionFactoryAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms; +package org.springframework.boot.jms.autoconfigure; import javax.naming.Context; diff --git a/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/health/JmsHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/health/JmsHealthContributorAutoConfigurationTests.java new file mode 100644 index 000000000000..43795bff614f --- /dev/null +++ b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/autoconfigure/health/JmsHealthContributorAutoConfigurationTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jms.autoconfigure.health; + +import jakarta.jms.ConnectionFactory; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.jms.health.JmsHealthIndicator; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link JmsHealthContributorAutoConfiguration}. + * + * @author Phillip Webb + */ +class JmsHealthContributorAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(JmsHealthContributorAutoConfiguration.class, + HealthContributorAutoConfiguration.class)) + .withBean(ConnectionFactory.class, () -> mock(ConnectionFactory.class)); + + @Test + void runShouldCreateIndicator() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(JmsHealthIndicator.class)); + } + + @Test + void runWhenDisabledShouldNotCreateIndicator() { + this.contextRunner.withPropertyValues("management.health.jms.enabled:false") + .run((context) -> assertThat(context).doesNotHaveBean(JmsHealthIndicator.class)); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/jms/JmsHealthIndicatorTests.java b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/health/JmsHealthIndicatorTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/jms/JmsHealthIndicatorTests.java rename to spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/health/JmsHealthIndicatorTests.java index be3f9a5b341a..c454945b5df5 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/jms/JmsHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-jms/src/test/java/org/springframework/boot/jms/health/JmsHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.jms; +package org.springframework.boot.jms.health; import jakarta.jms.Connection; import jakarta.jms.ConnectionFactory; @@ -24,8 +24,8 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-jooq/build.gradle b/spring-boot-project/spring-boot-jooq/build.gradle new file mode 100644 index 000000000000..2cafbacc2def --- /dev/null +++ b/spring-boot-project/spring-boot-jooq/build.gradle @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot jOOQ" + +dependencies { + api(project(":spring-boot-project:spring-boot-jdbc")) + api(project(":spring-boot-project:spring-boot-tx")) + api("org.jooq:jooq") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-r2dbc")) + optional("jakarta.xml.bind:jakarta.xml.bind-api") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") + testRuntimeOnly("io.r2dbc:r2dbc-h2") + testRuntimeOnly("org.glassfish.jaxb:jaxb-runtime") + testRuntimeOnly("org.hsqldb:hsqldb") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jooq/JooqDependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/JooqDependsOnDatabaseInitializationDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jooq/JooqDependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/JooqDependsOnDatabaseInitializationDetector.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DefaultConfigurationCustomizer.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/DefaultConfigurationCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DefaultConfigurationCustomizer.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/DefaultConfigurationCustomizer.java index bae9936210ad..251c02abb109 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DefaultConfigurationCustomizer.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/DefaultConfigurationCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import org.jooq.impl.DefaultConfiguration; @@ -23,7 +23,7 @@ * {@link DefaultConfiguration} whilst retaining default auto-configuration. * * @author Stephane Nicoll - * @since 2.5.0 + * @since 4.0.0 */ @FunctionalInterface public interface DefaultConfigurationCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DefaultExceptionTranslatorExecuteListener.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/DefaultExceptionTranslatorExecuteListener.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DefaultExceptionTranslatorExecuteListener.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/DefaultExceptionTranslatorExecuteListener.java index a35140c4ceec..504307a34ede 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DefaultExceptionTranslatorExecuteListener.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/DefaultExceptionTranslatorExecuteListener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import java.sql.SQLException; import java.util.function.Function; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/ExceptionTranslatorExecuteListener.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/ExceptionTranslatorExecuteListener.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/ExceptionTranslatorExecuteListener.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/ExceptionTranslatorExecuteListener.java index bc85906087b3..055dcd2e4528 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/ExceptionTranslatorExecuteListener.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/ExceptionTranslatorExecuteListener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import java.sql.SQLException; import java.util.function.Function; @@ -34,7 +34,7 @@ * adapting an existing {@link SQLExceptionTranslator}. * * @author Dennis Melzer - * @since 3.3.0 + * @since 4.0.0 * @see #DEFAULT * @see #of(Function) */ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JaxbNotAvailableException.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JaxbNotAvailableException.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JaxbNotAvailableException.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JaxbNotAvailableException.java index dc056b83506f..d46265290029 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JaxbNotAvailableException.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JaxbNotAvailableException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; /** * Exception to be thrown if JAXB is not available. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JaxbNotAvailableExceptionFailureAnalyzer.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JaxbNotAvailableExceptionFailureAnalyzer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JaxbNotAvailableExceptionFailureAnalyzer.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JaxbNotAvailableExceptionFailureAnalyzer.java index 538c67b6efd5..cc675d5d2bd3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JaxbNotAvailableExceptionFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JaxbNotAvailableExceptionFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JooqAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JooqAutoConfiguration.java index d81ae898aa29..8f21ed6039be 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JooqAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import java.io.IOException; import java.io.InputStream; @@ -50,9 +50,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; import org.springframework.core.io.Resource; @@ -68,7 +68,7 @@ * @author Michael Simons * @author Dmytro Nosan * @author Moritz Halbritter - * @since 1.3.0 + * @since 4.0.0 */ @AutoConfiguration(after = { DataSourceAutoConfiguration.class, TransactionAutoConfiguration.class }) @ConditionalOnClass(DSLContext.class) @@ -127,7 +127,7 @@ DefaultConfiguration jooqConfiguration(JooqProperties properties, ConnectionProv @Bean @ConditionalOnProperty("spring.jooq.config") - @ConditionalOnMissingBean(Settings.class) + @ConditionalOnMissingBean Settings settings(JooqProperties properties) throws IOException { if (!ClassUtils.isPresent("jakarta.xml.bind.JAXBContext", null)) { throw new JaxbNotAvailableException(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JooqProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JooqProperties.java index 56ce670124a1..387736785e75 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/JooqProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import javax.sql.DataSource; @@ -29,7 +29,7 @@ * @author Andreas Ahlenstorf * @author Michael Simons * @author Moritz Halbritter - * @since 1.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.jooq") public class JooqProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/NoDslContextBeanFailureAnalyzer.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/NoDslContextBeanFailureAnalyzer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/NoDslContextBeanFailureAnalyzer.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/NoDslContextBeanFailureAnalyzer.java index bad557ddb7d8..10c88c3c92ef 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/NoDslContextBeanFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/NoDslContextBeanFailureAnalyzer.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import org.jooq.DSLContext; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.core.Ordered; class NoDslContextBeanFailureAnalyzer extends AbstractFailureAnalyzer diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SpringTransaction.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SpringTransaction.java index 86d2ce10f188..de775bf28d60 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SpringTransaction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import org.jooq.Transaction; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SpringTransactionProvider.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SpringTransactionProvider.java index 5b12f076ccfc..2792af850697 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SpringTransactionProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import org.jooq.TransactionContext; import org.jooq.TransactionProvider; @@ -30,7 +30,7 @@ * @author Lukas Eder * @author Andreas Ahlenstorf * @author Phillip Webb - * @since 1.5.10 + * @since 4.0.0 */ public class SpringTransactionProvider implements TransactionProvider { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookup.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SqlDialectLookup.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookup.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SqlDialectLookup.java index 9288689b7382..4d524acf7bb2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookup.java +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/SqlDialectLookup.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import java.sql.Connection; import java.sql.SQLException; diff --git a/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/package-info.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/package-info.java new file mode 100644 index 000000000000..caf069ee1c25 --- /dev/null +++ b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for jOOQ. + */ +package org.springframework.boot.jooq.autoconfigure; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jooq/package-info.java b/spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jooq/package-info.java rename to spring-boot-project/spring-boot-jooq/src/main/java/org/springframework/boot/jooq/package-info.java diff --git a/spring-boot-project/spring-boot-jooq/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-jooq/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..c36f52085fc6 --- /dev/null +++ b/spring-boot-project/spring-boot-jooq/src/main/resources/META-INF/spring.factories @@ -0,0 +1,9 @@ +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.boot.jooq.autoconfigure.JaxbNotAvailableExceptionFailureAnalyzer,\ +org.springframework.boot.jooq.autoconfigure.NoDslContextBeanFailureAnalyzer + +# Depends On Database Initialization Detectors +org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ +org.springframework.boot.jooq.JooqDependsOnDatabaseInitializationDetector + diff --git a/spring-boot-project/spring-boot-jooq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-jooq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..45b178286422 --- /dev/null +++ b/spring-boot-project/spring-boot-jooq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.jooq.autoconfigure.JooqAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/DefaultExceptionTranslatorExecuteListenerTests.java b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/DefaultExceptionTranslatorExecuteListenerTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/DefaultExceptionTranslatorExecuteListenerTests.java rename to spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/DefaultExceptionTranslatorExecuteListenerTests.java index cae56de5ec9c..ca56da04f629 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/DefaultExceptionTranslatorExecuteListenerTests.java +++ b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/DefaultExceptionTranslatorExecuteListenerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import java.sql.SQLException; import java.sql.SQLSyntaxErrorException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/JooqAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/JooqAutoConfigurationTests.java index 63d0e2ffa24b..e10e8a0e1804 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/JooqAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import javax.sql.DataSource; @@ -227,7 +227,7 @@ void autoConfiguredJooqConfigurationCanBeUsedToCreateCustomDslContext() { @Test void shouldLoadSettingsFromConfigPropertyThroughJaxb() { this.contextRunner.withUserConfiguration(JooqDataSourceConfiguration.class) - .withPropertyValues("spring.jooq.config=classpath:org/springframework/boot/autoconfigure/jooq/settings.xml") + .withPropertyValues("spring.jooq.config=classpath:org/springframework/boot/jooq/autoconfigure/settings.xml") .run((context) -> { assertThat(context).hasSingleBean(Settings.class); Settings settings = context.getBean(Settings.class); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqPropertiesTests.java b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/JooqPropertiesTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqPropertiesTests.java rename to spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/JooqPropertiesTests.java index 71cf4b70ecfe..2ef0d6a0251b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqPropertiesTests.java +++ b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/JooqPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import java.sql.Connection; import java.sql.DatabaseMetaData; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/NoDslContextBeanFailureAnalyzerTests.java b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/NoDslContextBeanFailureAnalyzerTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/NoDslContextBeanFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/NoDslContextBeanFailureAnalyzerTests.java index ba92129053af..b3d1c5cc766e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/NoDslContextBeanFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/NoDslContextBeanFailureAnalyzerTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import org.jooq.DSLContext; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookupTests.java b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/SqlDialectLookupTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookupTests.java rename to spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/SqlDialectLookupTests.java index db1b82af3eb1..35b93a3054d3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/SqlDialectLookupTests.java +++ b/spring-boot-project/spring-boot-jooq/src/test/java/org/springframework/boot/jooq/autoconfigure/SqlDialectLookupTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jooq; +package org.springframework.boot.jooq.autoconfigure; import java.sql.Connection; import java.sql.DatabaseMetaData; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jooq/settings.xml b/spring-boot-project/spring-boot-jooq/src/test/resources/org/springframework/boot/jooq/autoconfigure/settings.xml similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/jooq/settings.xml rename to spring-boot-project/spring-boot-jooq/src/test/resources/org/springframework/boot/jooq/autoconfigure/settings.xml diff --git a/spring-boot-project/spring-boot-jpa/build.gradle b/spring-boot-project/spring-boot-jpa/build.gradle new file mode 100644 index 000000000000..4081c656700c --- /dev/null +++ b/spring-boot-project/spring-boot-jpa/build.gradle @@ -0,0 +1,41 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot JPA" + +dependencies { + api(project(":spring-boot-project:spring-boot-jdbc")) + api(project(":spring-boot-project:spring-boot-tx")) + api("jakarta.persistence:jakarta.persistence-api") + api("org.springframework:spring-orm") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("jakarta.servlet:jakarta.servlet-api") + optional("org.springframework:spring-webmvc") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("org.springframework:spring-context-support") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityManagerFactoryBuilder.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java similarity index 85% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityManagerFactoryBuilder.java rename to spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java index 2975bbfabd34..1cffb77e427e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityManagerFactoryBuilder.java +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/EntityManagerFactoryBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.orm.jpa; +package org.springframework.boot.jpa; import java.net.URL; import java.util.HashMap; @@ -47,7 +47,7 @@ * @author Dave Syer * @author Phillip Webb * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ public class EntityManagerFactoryBuilder { @@ -99,41 +99,6 @@ public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, this.persistenceUnitRootLocation = persistenceUnitRootLocation; } - /** - * Create a new instance passing in the common pieces that will be shared if multiple - * EntityManagerFactory instances are created. - * @param jpaVendorAdapter a vendor adapter - * @param jpaProperties the JPA properties to be passed to the persistence provider - * @param persistenceUnitManager optional source of persistence unit information (can - * be null) - * @deprecated since 3.4.4 for removal in 4.0.0 in favor of - * {@link #EntityManagerFactoryBuilder(JpaVendorAdapter, Function, PersistenceUnitManager)} - */ - @Deprecated(since = "3.4.4", forRemoval = true) - public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, Map jpaProperties, - PersistenceUnitManager persistenceUnitManager) { - this(jpaVendorAdapter, (datasource) -> jpaProperties, persistenceUnitManager, null); - } - - /** - * Create a new instance passing in the common pieces that will be shared if multiple - * EntityManagerFactory instances are created. - * @param jpaVendorAdapter a vendor adapter - * @param jpaProperties the JPA properties to be passed to the persistence provider - * @param persistenceUnitManager optional source of persistence unit information (can - * be null) - * @param persistenceUnitRootLocation the persistence unit root location to use as a - * fallback or {@code null} - * @since 1.4.1 - * @deprecated since 3.4.4 for removal in 4.0.0 in favor of - * {@link #EntityManagerFactoryBuilder(JpaVendorAdapter, Function, PersistenceUnitManager, URL)} - */ - @Deprecated(since = "3.4.4", forRemoval = true) - public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, Map jpaProperties, - PersistenceUnitManager persistenceUnitManager, URL persistenceUnitRootLocation) { - this(jpaVendorAdapter, (datasource) -> jpaProperties, persistenceUnitManager, persistenceUnitRootLocation); - } - /** * Create a new {@link Builder} for a {@code EntityManagerFactory} using the settings * of the given instance, and the given {@link DataSource}. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/JpaDatabaseInitializerDetector.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/JpaDatabaseInitializerDetector.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/JpaDatabaseInitializerDetector.java rename to spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/JpaDatabaseInitializerDetector.java index baad8e4e3bab..99649aabdf75 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/JpaDatabaseInitializerDetector.java +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/JpaDatabaseInitializerDetector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.orm.jpa; +package org.springframework.boot.jpa; import java.util.Collections; import java.util.HashSet; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/JpaDependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/JpaDependsOnDatabaseInitializationDetector.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/JpaDependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/JpaDependsOnDatabaseInitializationDetector.java index 985b6a8ee533..6ff70b0593c2 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/JpaDependsOnDatabaseInitializationDetector.java +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/JpaDependsOnDatabaseInitializationDetector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.orm.jpa; +package org.springframework.boot.jpa; import java.util.Arrays; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/EntityManagerFactoryBuilderCustomizer.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/EntityManagerFactoryBuilderCustomizer.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/EntityManagerFactoryBuilderCustomizer.java rename to spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/EntityManagerFactoryBuilderCustomizer.java index 65aca20f1a3d..2508c2dfb08a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/EntityManagerFactoryBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/EntityManagerFactoryBuilderCustomizer.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.jpa.autoconfigure; -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jpa.EntityManagerFactoryBuilder; /** * Callback interface that can be used to customize the auto-configured * {@link EntityManagerFactoryBuilder}. * * @author Andy Wilkinson - * @since 2.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface EntityManagerFactoryBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/EntityManagerFactoryDependsOnPostProcessor.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/EntityManagerFactoryDependsOnPostProcessor.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/EntityManagerFactoryDependsOnPostProcessor.java rename to spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/EntityManagerFactoryDependsOnPostProcessor.java index 1a0fdc346d41..dde925b86234 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/EntityManagerFactoryDependsOnPostProcessor.java +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/EntityManagerFactoryDependsOnPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.jpa.autoconfigure; import jakarta.persistence.EntityManagerFactory; @@ -32,7 +32,7 @@ * @author Phillip Webb * @author Andy Wilkinson * @author Andrii Hrytsiuk - * @since 2.5.0 + * @since 4.0.0 * @see BeanDefinition#setDependsOn(String[]) */ public class EntityManagerFactoryDependsOnPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaBaseConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java rename to spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaBaseConfiguration.java index ebd597e39d2a..428c2f1f9583 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaBaseConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.jpa.autoconfigure; import java.util.HashMap; import java.util.List; @@ -33,13 +33,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.domain.EntityScanPackages; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; -import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizers; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -72,7 +72,7 @@ * @author Kazuki Shimizu * @author Eddú Meléndez * @author Yanming Zhou - * @since 1.0.0 + * @since 4.0.0 */ @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(JpaProperties.class) @@ -152,21 +152,9 @@ public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManager * Return the vendor-specific properties for the given {@link DataSource}. * @param dataSource the data source * @return the vendor properties - * @since 3.4.4 */ protected abstract Map getVendorProperties(DataSource dataSource); - /** - * Return the vendor-specific properties. - * @return the vendor properties - * @deprecated since 3.4.4 for removal in 4.0.0 in favor of - * {@link #getVendorProperties(DataSource)} - */ - @Deprecated(since = "3.4.4", forRemoval = true) - protected Map getVendorProperties() { - return getVendorProperties(getDataSource()); - } - /** * Customize vendor properties before they are used. Allows for post-processing (for * example to configure JTA specific settings). diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java rename to spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaProperties.java index 7b5045f802ce..77bb0d5737ec 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/JpaProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.orm.jpa; +package org.springframework.boot.jpa.autoconfigure; import java.util.ArrayList; import java.util.HashMap; @@ -32,7 +32,7 @@ * @author Stephane Nicoll * @author Eddú Meléndez * @author Madhura Bhave - * @since 1.1.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.jpa") public class JpaProperties { diff --git a/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/package-info.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/package-info.java new file mode 100644 index 000000000000..f336351258de --- /dev/null +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Base Auto-configuration for JPA and Spring ORM. + */ +package org.springframework.boot.jpa.autoconfigure; diff --git a/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/package-info.java b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/package-info.java new file mode 100644 index 000000000000..eb455d693a81 --- /dev/null +++ b/spring-boot-project/spring-boot-jpa/src/main/java/org/springframework/boot/jpa/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * JPA Support classes. + */ +package org.springframework.boot.jpa; diff --git a/spring-boot-project/spring-boot-jpa/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-jpa/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..1b02295bb7fa --- /dev/null +++ b/spring-boot-project/spring-boot-jpa/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,11 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.jpa.open-in-view", + "defaultValue": true + } + ], + "hints": [ + ] +} diff --git a/spring-boot-project/spring-boot-jpa/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-jpa/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..6437bb94c7a4 --- /dev/null +++ b/spring-boot-project/spring-boot-jpa/src/main/resources/META-INF/spring.factories @@ -0,0 +1,7 @@ +# Database Initializer Detectors +org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\ +org.springframework.boot.jpa.JpaDatabaseInitializerDetector + +# Depends On Database Initialization Detectors +org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ +org.springframework.boot.jpa.JpaDependsOnDatabaseInitializationDetector diff --git a/spring-boot-project/spring-boot-jsonb/build.gradle b/spring-boot-project/spring-boot-jsonb/build.gradle new file mode 100644 index 000000000000..3bb21f04f1f4 --- /dev/null +++ b/spring-boot-project/spring-boot-jsonb/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot JSON-B" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("jakarta.json.bind:jakarta.json.bind-api") + api("org.eclipse:yasson") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("org.eclipse:yasson") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfiguration.java b/spring-boot-project/spring-boot-jsonb/src/main/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfiguration.java rename to spring-boot-project/spring-boot-jsonb/src/main/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfiguration.java index 0122b7fde8d1..3230cfc52668 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfiguration.java +++ b/spring-boot-project/spring-boot-jsonb/src/main/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jsonb; +package org.springframework.boot.jsonb.autoconfigure; import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; @@ -30,7 +30,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for JSON-B. * * @author Eddú Meléndez - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(Jsonb.class) diff --git a/spring-boot-project/spring-boot-jsonb/src/main/java/org/springframework/boot/jsonb/autoconfigure/package-info.java b/spring-boot-project/spring-boot-jsonb/src/main/java/org/springframework/boot/jsonb/autoconfigure/package-info.java new file mode 100644 index 000000000000..0498069f261b --- /dev/null +++ b/spring-boot-project/spring-boot-jsonb/src/main/java/org/springframework/boot/jsonb/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JSON-B. + */ +package org.springframework.boot.jsonb.autoconfigure; diff --git a/spring-boot-project/spring-boot-jsonb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-jsonb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..31048a8e9e28 --- /dev/null +++ b/spring-boot-project/spring-boot-jsonb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.jsonb.autoconfigure.JsonbAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfigurationTests.java b/spring-boot-project/spring-boot-jsonb/src/test/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfigurationTests.java rename to spring-boot-project/spring-boot-jsonb/src/test/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfigurationTests.java index 7b3bb860d8fd..97119e8b5f81 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-jsonb/src/test/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jsonb; +package org.springframework.boot.jsonb.autoconfigure; import jakarta.json.bind.Jsonb; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfigurationWithNoProviderTests.java b/spring-boot-project/spring-boot-jsonb/src/test/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfigurationWithNoProviderTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfigurationWithNoProviderTests.java rename to spring-boot-project/spring-boot-jsonb/src/test/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfigurationWithNoProviderTests.java index 95deaba35c24..2543e6b90802 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jsonb/JsonbAutoConfigurationWithNoProviderTests.java +++ b/spring-boot-project/spring-boot-jsonb/src/test/java/org/springframework/boot/jsonb/autoconfigure/JsonbAutoConfigurationWithNoProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jsonb; +package org.springframework.boot.jsonb.autoconfigure; import jakarta.json.bind.Jsonb; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-kafka/build.gradle b/spring-boot-project/spring-boot-kafka/build.gradle new file mode 100644 index 000000000000..221d6421d559 --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/build.gradle @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Kafka" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.kafka:spring-kafka") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("org.apache.kafka:kafka-streams") + optional("org.testcontainers:kafka") + optional("org.testcontainers:redpanda") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("org.springframework.kafka:spring-kafka-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/ApacheKafkaContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/ApacheKafkaContainerConnectionDetailsFactoryIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/ApacheKafkaContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/ApacheKafkaContainerConnectionDetailsFactoryIntegrationTests.java index e0f9ef6d2535..687ca7222010 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/ApacheKafkaContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/ApacheKafkaContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.kafka; +package org.springframework.boot.kafka.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration; +import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/ConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/ConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/ConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/ConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java index 9ffc1fc699eb..65dfdf523b8d 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/ConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/ConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.kafka; +package org.springframework.boot.kafka.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration; +import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redpanda/RedpandaContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/RedpandaContainerConnectionDetailsFactoryIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redpanda/RedpandaContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/RedpandaContainerConnectionDetailsFactoryIntegrationTests.java index 0f61075158b7..7e6631badfa3 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/redpanda/RedpandaContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-kafka/src/dockerTest/java/org/springframework/boot/kafka/testcontainers/RedpandaContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.redpanda; +package org.springframework.boot.kafka.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration; +import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-kafka/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-kafka/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-kafka/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-kafka/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ConcurrentKafkaListenerContainerFactoryConfigurer.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/ConcurrentKafkaListenerContainerFactoryConfigurer.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ConcurrentKafkaListenerContainerFactoryConfigurer.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/ConcurrentKafkaListenerContainerFactoryConfigurer.java index ecdeab9c1545..6171a6ea7047 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ConcurrentKafkaListenerContainerFactoryConfigurer.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/ConcurrentKafkaListenerContainerFactoryConfigurer.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.time.Duration; import java.util.function.Function; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Listener; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.kafka.autoconfigure.KafkaProperties.Listener; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; import org.springframework.kafka.core.ConsumerFactory; @@ -49,7 +49,7 @@ * @author Eddú Meléndez * @author Thomas Kåsene * @author Moritz Halbritter - * @since 1.5.0 + * @since 4.0.0 */ public class ConcurrentKafkaListenerContainerFactoryConfigurer { @@ -130,7 +130,6 @@ void setTransactionManager(KafkaAwareTransactionManager transact /** * Set the {@link ConsumerAwareRebalanceListener} to use. * @param rebalanceListener the rebalance listener. - * @since 2.2 */ void setRebalanceListener(ConsumerAwareRebalanceListener rebalanceListener) { this.rebalanceListener = rebalanceListener; @@ -139,7 +138,6 @@ void setRebalanceListener(ConsumerAwareRebalanceListener rebalanceListener) { /** * Set the {@link CommonErrorHandler} to use. * @param commonErrorHandler the error handler. - * @since 2.6.0 */ public void setCommonErrorHandler(CommonErrorHandler commonErrorHandler) { this.commonErrorHandler = commonErrorHandler; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaConsumerFactoryCustomizer.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/DefaultKafkaConsumerFactoryCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaConsumerFactoryCustomizer.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/DefaultKafkaConsumerFactoryCustomizer.java index d5d6d55f223a..dbc1e7e54832 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaConsumerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/DefaultKafkaConsumerFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; @@ -22,7 +22,7 @@ * Callback interface for customizing {@code DefaultKafkaConsumerFactory} beans. * * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface DefaultKafkaConsumerFactoryCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaProducerFactoryCustomizer.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/DefaultKafkaProducerFactoryCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaProducerFactoryCustomizer.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/DefaultKafkaProducerFactoryCustomizer.java index c832eb777146..b9b3684afdcb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaProducerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/DefaultKafkaProducerFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import org.springframework.kafka.core.DefaultKafkaProducerFactory; @@ -22,7 +22,7 @@ * Callback interface for customizing {@code DefaultKafkaProducerFactory} beans. * * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface DefaultKafkaProducerFactoryCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaAnnotationDrivenConfiguration.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaAnnotationDrivenConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaAnnotationDrivenConfiguration.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaAnnotationDrivenConfiguration.java index f935b475304e..af5fb8ed8c0f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaAnnotationDrivenConfiguration.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaAnnotationDrivenConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.util.function.Function; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfiguration.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfiguration.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfiguration.java index 005a5a35b1ac..52164e68195a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.io.IOException; import java.time.Duration; @@ -36,11 +36,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails.Configuration; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Jaas; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Retry.Topic.Backoff; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails.Configuration; +import org.springframework.boot.kafka.autoconfigure.KafkaProperties.Jaas; +import org.springframework.boot.kafka.autoconfigure.KafkaProperties.Retry.Topic.Backoff; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; import org.springframework.context.annotation.Bean; @@ -76,7 +76,7 @@ * @author Phillip Webb * @author Andy Wilkinson * @author Scott Frederick - * @since 1.5.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(KafkaTemplate.class) diff --git a/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaConnectionDetails.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaConnectionDetails.java new file mode 100644 index 000000000000..8e5a3dfeb881 --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaConnectionDetails.java @@ -0,0 +1,163 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.kafka.autoconfigure; + +import java.util.List; + +import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; +import org.springframework.boot.ssl.SslBundle; + +/** + * Details required to establish a connection to a Kafka service. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @since 4.0.0 + */ +public interface KafkaConnectionDetails extends ConnectionDetails { + + /** + * Returns the list of bootstrap servers. + * @return the list of bootstrap servers + */ + List getBootstrapServers(); + + /** + * Returns the SSL bundle. + * @return the SSL bundle + */ + default SslBundle getSslBundle() { + return null; + } + + /** + * Returns the security protocol. + * @return the security protocol + */ + default String getSecurityProtocol() { + return null; + } + + /** + * Returns the consumer configuration. + * @return the consumer configuration + */ + default Configuration getConsumer() { + return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol()); + } + + /** + * Returns the producer configuration. + * @return the producer configuration + */ + default Configuration getProducer() { + return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol()); + } + + /** + * Returns the admin configuration. + * @return the admin configuration + */ + default Configuration getAdmin() { + return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol()); + } + + /** + * Returns the Kafka Streams configuration. + * @return the Kafka Streams configuration + */ + default Configuration getStreams() { + return Configuration.of(getBootstrapServers(), getSslBundle(), getSecurityProtocol()); + } + + /** + * Kafka connection details configuration. + */ + interface Configuration { + + /** + * Creates a new configuration with the given bootstrap servers. + * @param bootstrapServers the bootstrap servers + * @return the configuration + */ + static Configuration of(List bootstrapServers) { + return Configuration.of(bootstrapServers, null, null); + } + + /** + * Creates a new configuration with the given bootstrap servers and SSL bundle. + * @param bootstrapServers the bootstrap servers + * @param sslBundle the SSL bundle + * @return the configuration + */ + static Configuration of(List bootstrapServers, SslBundle sslBundle) { + return Configuration.of(bootstrapServers, sslBundle, null); + } + + /** + * Creates a new configuration with the given bootstrap servers, SSL bundle and + * security protocol. + * @param bootstrapServers the bootstrap servers + * @param sslBundle the SSL bundle + * @param securityProtocol the security protocol + * @return the configuration + */ + static Configuration of(List bootstrapServers, SslBundle sslBundle, String securityProtocol) { + return new Configuration() { + @Override + public List getBootstrapServers() { + return bootstrapServers; + } + + @Override + public SslBundle getSslBundle() { + return sslBundle; + } + + @Override + public String getSecurityProtocol() { + return securityProtocol; + } + }; + } + + /** + * Returns the list of bootstrap servers. + * @return the list of bootstrap servers + */ + List getBootstrapServers(); + + /** + * Returns the SSL bundle. + * @return the SSL bundle + */ + default SslBundle getSslBundle() { + return null; + } + + /** + * Returns the security protocol. + * @return the security protocol + */ + default String getSecurityProtocol() { + return null; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaProperties.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaProperties.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaProperties.java index c1aae142f5d0..3e4f340b41d9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaProperties.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.io.IOException; import java.time.Duration; @@ -34,7 +34,6 @@ import org.apache.kafka.common.serialization.StringSerializer; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; import org.springframework.boot.convert.DurationUnit; @@ -59,7 +58,7 @@ * @author Andy Wilkinson * @author Scott Frederick * @author Yanming Zhou - * @since 1.5.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.kafka") public class KafkaProperties { @@ -1585,51 +1584,6 @@ public void setAttempts(int attempts) { this.attempts = attempts; } - @DeprecatedConfigurationProperty(replacement = "spring.kafka.retry.topic.backoff.delay", since = "3.4.0") - @Deprecated(since = "3.4.0", forRemoval = true) - public Duration getDelay() { - return getBackoff().getDelay(); - } - - @Deprecated(since = "3.4.0", forRemoval = true) - public void setDelay(Duration delay) { - getBackoff().setDelay(delay); - } - - @DeprecatedConfigurationProperty(replacement = "spring.kafka.retry.topic.backoff.multiplier", - since = "3.4.0") - @Deprecated(since = "3.4.0", forRemoval = true) - public double getMultiplier() { - return getBackoff().getMultiplier(); - } - - @Deprecated(since = "3.4.0", forRemoval = true) - public void setMultiplier(double multiplier) { - getBackoff().setMultiplier(multiplier); - } - - @DeprecatedConfigurationProperty(replacement = "spring.kafka.retry.topic.backoff.maxDelay", since = "3.4.0") - @Deprecated(since = "3.4.0", forRemoval = true) - public Duration getMaxDelay() { - return getBackoff().getMaxDelay(); - } - - @Deprecated(since = "3.4.0", forRemoval = true) - public void setMaxDelay(Duration maxDelay) { - getBackoff().setMaxDelay(maxDelay); - } - - @DeprecatedConfigurationProperty(replacement = "spring.kafka.retry.topic.backoff.random", since = "3.4.0") - @Deprecated(since = "3.4.0", forRemoval = true) - public boolean isRandomBackOff() { - return getBackoff().isRandom(); - } - - @Deprecated(since = "3.4.0", forRemoval = true) - public void setRandomBackOff(boolean randomBackOff) { - getBackoff().setRandom(randomBackOff); - } - private final Backoff backoff = new Backoff(); public Backoff getBackoff() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaStreamsAnnotationDrivenConfiguration.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaStreamsAnnotationDrivenConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaStreamsAnnotationDrivenConfiguration.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaStreamsAnnotationDrivenConfiguration.java index 67ab8d8c6de2..6dfdb836685a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaStreamsAnnotationDrivenConfiguration.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/KafkaStreamsAnnotationDrivenConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/PropertiesKafkaConnectionDetails.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/PropertiesKafkaConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/PropertiesKafkaConnectionDetails.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/PropertiesKafkaConnectionDetails.java index 643b7930f9d5..da25d7bc2612 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/PropertiesKafkaConnectionDetails.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/PropertiesKafkaConnectionDetails.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.util.List; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Ssl; +import org.springframework.boot.kafka.autoconfigure.KafkaProperties.Ssl; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; import org.springframework.util.Assert; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/SslBundleSslEngineFactory.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/SslBundleSslEngineFactory.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/SslBundleSslEngineFactory.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/SslBundleSslEngineFactory.java index f3b633f040a7..8d227ee3d7f1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/SslBundleSslEngineFactory.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/SslBundleSslEngineFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.io.IOException; import java.security.KeyStore; @@ -34,7 +34,7 @@ * * @author Andy Wilkinson * @author Scott Frederick - * @since 3.2.0 + * @since 4.0.0 */ public class SslBundleSslEngineFactory implements SslEngineFactory { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/StreamsBuilderFactoryBeanCustomizer.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/StreamsBuilderFactoryBeanCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/StreamsBuilderFactoryBeanCustomizer.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/StreamsBuilderFactoryBeanCustomizer.java index 7174ab8af4a3..f65872934cc3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/StreamsBuilderFactoryBeanCustomizer.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/StreamsBuilderFactoryBeanCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import org.springframework.kafka.config.StreamsBuilderFactoryBean; @@ -22,7 +22,7 @@ * Callback interface for customizing {@code StreamsBuilderFactoryBean} beans. * * @author Eddú Meléndez - * @since 2.3.2 + * @since 4.0.0 */ @FunctionalInterface public interface StreamsBuilderFactoryBeanCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java index 62c7e2fe6f9a..f99ae223470c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.kafka.autoconfigure.metrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.kafka.KafkaClientMetrics; @@ -23,10 +23,10 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.kafka.DefaultKafkaConsumerFactoryCustomizer; -import org.springframework.boot.autoconfigure.kafka.DefaultKafkaProducerFactoryCustomizer; -import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration; -import org.springframework.boot.autoconfigure.kafka.StreamsBuilderFactoryBeanCustomizer; +import org.springframework.boot.kafka.autoconfigure.DefaultKafkaConsumerFactoryCustomizer; +import org.springframework.boot.kafka.autoconfigure.DefaultKafkaProducerFactoryCustomizer; +import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration; +import org.springframework.boot.kafka.autoconfigure.StreamsBuilderFactoryBeanCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.config.StreamsBuilderFactoryBean; @@ -43,11 +43,12 @@ * @author Andy Wilkinson * @author Stephane Nicoll * @author Eddú Meléndez - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(before = KafkaAutoConfiguration.class, - after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) -@ConditionalOnClass({ KafkaClientMetrics.class, ProducerFactory.class }) + afterName = { "org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration", + "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration" }) +@ConditionalOnClass({ KafkaClientMetrics.class, ProducerFactory.class, MeterRegistry.class }) @ConditionalOnBean(MeterRegistry.class) public class KafkaMetricsAutoConfiguration { diff --git a/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..f6a476f5188d --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Apache Kafka metrics. + */ +package org.springframework.boot.kafka.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/package-info.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/package-info.java new file mode 100644 index 000000000000..e3d109b4314a --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Apache Kafka. + */ +package org.springframework.boot.kafka.autoconfigure; diff --git a/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/metrics/autoconfigure/package-info.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/metrics/autoconfigure/package-info.java new file mode 100644 index 000000000000..d17e7a667b7c --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/metrics/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Apache Kafka metrics. + */ +package org.springframework.boot.kafka.metrics.autoconfigure; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/ApacheKafkaContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/ApacheKafkaContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/ApacheKafkaContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/ApacheKafkaContainerConnectionDetailsFactory.java index adae4c788c61..6dbe317b0f39 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/ApacheKafkaContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/ApacheKafkaContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.kafka; +package org.springframework.boot.kafka.testcontainers; import java.util.List; import org.testcontainers.kafka.KafkaContainer; -import org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails; +import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/ConfluentKafkaContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/ConfluentKafkaContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/ConfluentKafkaContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/ConfluentKafkaContainerConnectionDetailsFactory.java index 6b4668890000..6e9b767e960d 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/ConfluentKafkaContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/ConfluentKafkaContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.kafka; +package org.springframework.boot.kafka.testcontainers; import java.util.List; import org.testcontainers.kafka.ConfluentKafkaContainer; -import org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails; +import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redpanda/RedpandaContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/RedpandaContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redpanda/RedpandaContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/RedpandaContainerConnectionDetailsFactory.java index ec4978a8f491..289aa77d7806 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redpanda/RedpandaContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/RedpandaContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.redpanda; +package org.springframework.boot.kafka.testcontainers; import java.util.List; import org.testcontainers.redpanda.RedpandaContainer; -import org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails; +import org.springframework.boot.kafka.autoconfigure.KafkaConnectionDetails; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; diff --git a/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/package-info.java b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/package-info.java new file mode 100644 index 000000000000..7c01ce0890ae --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/main/java/org/springframework/boot/kafka/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Kafka service connections. + */ +package org.springframework.boot.kafka.testcontainers; diff --git a/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..1a1edd65daeb --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,279 @@ +{ + "properties": [ + { + "name": "spring.kafka.admin.ssl.keystore-location", + "type": "org.springframework.core.io.Resource", + "description": "Location of the key store file.", + "deprecation": { + "replacement": "spring.kafka.admin.ssl.key-store-location", + "level": "error" + } + }, + { + "name": "spring.kafka.admin.ssl.keystore-password", + "type": "java.lang.String", + "description": "Store password for the key store file.", + "deprecation": { + "replacement": "spring.kafka.admin.ssl.key-store-password", + "level": "error" + } + }, + { + "name": "spring.kafka.admin.ssl.truststore-location", + "type": "org.springframework.core.io.Resource", + "description": "Location of the trust store file.", + "deprecation": { + "replacement": "spring.kafka.admin.ssl.trust-store-location", + "level": "error" + } + }, + { + "name": "spring.kafka.admin.ssl.truststore-password", + "type": "java.lang.String", + "description": "Store password for the trust store file.", + "deprecation": { + "replacement": "spring.kafka.admin.ssl.trust-store-password", + "level": "error" + } + }, + { + "name": "spring.kafka.consumer.ssl.keystore-location", + "type": "org.springframework.core.io.Resource", + "description": "Location of the key store file.", + "deprecation": { + "replacement": "spring.kafka.consumer.ssl.key-store-location", + "level": "error" + } + }, + { + "name": "spring.kafka.consumer.ssl.keystore-password", + "type": "java.lang.String", + "description": "Store password for the key store file.", + "deprecation": { + "replacement": "spring.kafka.consumer.ssl.key-store-password", + "level": "error" + } + }, + { + "name": "spring.kafka.consumer.ssl.truststore-location", + "type": "org.springframework.core.io.Resource", + "description": "Location of the trust store file.", + "deprecation": { + "replacement": "spring.kafka.consumer.ssl.trust-store-location", + "level": "error" + } + }, + { + "name": "spring.kafka.consumer.ssl.truststore-password", + "type": "java.lang.String", + "description": "Store password for the trust store file.", + "deprecation": { + "replacement": "spring.kafka.consumer.ssl.trust-store-password", + "level": "error" + } + }, + { + "name": "spring.kafka.listener.only-log-record-metadata", + "type": "java.lang.Boolean", + "defaultValue": true, + "description": "Whether to suppress the entire record from being written to the log when retries are being attempted.", + "deprecation": { + "reason": "Use KafkaUtils#setConsumerRecordFormatter instead.", + "level": "error" + } + }, + { + "name": "spring.kafka.producer.ssl.keystore-location", + "type": "org.springframework.core.io.Resource", + "description": "Location of the key store file.", + "deprecation": { + "replacement": "spring.kafka.producer.ssl.key-store-location", + "level": "error" + } + }, + { + "name": "spring.kafka.producer.ssl.keystore-password", + "type": "java.lang.String", + "description": "Store password for the key store file.", + "deprecation": { + "replacement": "spring.kafka.producer.ssl.key-store-password", + "level": "error" + } + }, + { + "name": "spring.kafka.producer.ssl.truststore-location", + "type": "org.springframework.core.io.Resource", + "description": "Location of the trust store file.", + "deprecation": { + "replacement": "spring.kafka.producer.ssl.trust-store-location", + "level": "error" + } + }, + { + "name": "spring.kafka.producer.ssl.truststore-password", + "type": "java.lang.String", + "description": "Store password for the trust store file.", + "deprecation": { + "replacement": "spring.kafka.producer.ssl.trust-store-password", + "level": "error" + } + }, + { + "name": "spring.kafka.retry.topic.delay", + "type": "java.time.Duration", + "deprecation": { + "replacement": "spring.kafka.retry.topic.backoff.delay", + "since": "3.4.0" + } + }, + { + "name": "spring.kafka.retry.topic.max-delay", + "type": "java.time.Duration", + "deprecation": { + "replacement": "spring.kafka.retry.topic.backoff.maxDelay", + "since": "3.4.0" + } + }, + { + "name": "spring.kafka.retry.topic.multiplier", + "type": "java.lang.Double", + "deprecation": { + "replacement": "spring.kafka.retry.topic.backoff.multiplier", + "since": "3.4.0" + } + }, + { + "name": "spring.kafka.retry.topic.random-back-off", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "spring.kafka.retry.topic.backoff.random", + "since": "3.4.0" + } + }, + { + "name": "spring.kafka.ssl.keystore-location", + "type": "org.springframework.core.io.Resource", + "description": "Location of the key store file.", + "deprecation": { + "replacement": "spring.kafka.ssl.key-store-location", + "level": "error" + } + }, + { + "name": "spring.kafka.ssl.keystore-password", + "type": "java.lang.String", + "description": "Store password for the key store file.", + "deprecation": { + "replacement": "spring.kafka.ssl.key-store-password", + "level": "error" + } + }, + { + "name": "spring.kafka.ssl.truststore-location", + "type": "org.springframework.core.io.Resource", + "description": "Location of the trust store file.", + "deprecation": { + "replacement": "spring.kafka.ssl.trust-store-location", + "level": "error" + } + }, + { + "name": "spring.kafka.ssl.truststore-password", + "type": "java.lang.String", + "description": "Store password for the trust store file.", + "deprecation": { + "replacement": "spring.kafka.ssl.trust-store-password", + "level": "error" + } + }, + { + "name": "spring.kafka.streams.cache-max-bytes-buffering", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.kafka.streams.state-store-cache-max-size", + "level": "error" + } + }, + { + "name": "spring.kafka.streams.cache-max-size-buffering", + "type": "java.lang.Integer", + "deprecation": { + "replacement": "spring.kafka.streams.state-store-cache-max-size", + "level": "error", + "since": "3.1.0" + } + } + ], + "hints": [ + { + "name": "spring.kafka.consumer.auto-offset-reset", + "values": [ + { + "value": "earliest", + "description": "Automatically reset the offset to the earliest offset." + }, + { + "value": "latest", + "description": "Automatically reset the offset to the latest offset." + }, + { + "value": "none", + "description": "Throw exception to the consumer if no previous offset is found for the consumer's group." + }, + { + "value": "exception", + "description": "Throw exception to the consumer." + } + ], + "providers": [ + { + "name": "any" + } + ] + }, + { + "name": "spring.kafka.consumer.key-deserializer", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "org.apache.kafka.common.serialization.Deserializer" + } + } + ] + }, + { + "name": "spring.kafka.consumer.value-deserializer", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "org.apache.kafka.common.serialization.Deserializer" + } + } + ] + }, + { + "name": "spring.kafka.producer.key-serializer", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "org.apache.kafka.common.serialization.Serializer" + } + } + ] + }, + { + "name": "spring.kafka.producer.value-serializer", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "org.apache.kafka.common.serialization.Serializer" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..4a30c0c82ea7 --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/spring.factories @@ -0,0 +1,5 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.kafka.testcontainers.ApacheKafkaContainerConnectionDetailsFactory,\ +org.springframework.boot.kafka.testcontainers.ConfluentKafkaContainerConnectionDetailsFactory,\ +org.springframework.boot.kafka.testcontainers.RedpandaContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..a38ec2881071 --- /dev/null +++ b/spring-boot-project/spring-boot-kafka/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration +org.springframework.boot.kafka.autoconfigure.metrics.KafkaMetricsAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ConcurrentKafkaListenerContainerFactoryConfigurerTests.java b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/ConcurrentKafkaListenerContainerFactoryConfigurerTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ConcurrentKafkaListenerContainerFactoryConfigurerTests.java rename to spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/ConcurrentKafkaListenerContainerFactoryConfigurerTests.java index 38c760f17deb..33becc8bf22a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ConcurrentKafkaListenerContainerFactoryConfigurerTests.java +++ b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/ConcurrentKafkaListenerContainerFactoryConfigurerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.time.Duration; import java.util.function.Function; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfigurationIntegrationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfigurationIntegrationTests.java index 13a8f020142e..57b85d08a9d4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.util.ArrayList; import java.util.List; @@ -103,8 +103,8 @@ void testEndToEnd() throws Exception { void testEndToEndWithRetryTopics() throws Exception { load(KafkaConfig.class, "spring.kafka.bootstrap-servers:" + getEmbeddedKafkaBrokersAsString(), "spring.kafka.consumer.group-id=testGroup", "spring.kafka.retry.topic.enabled=true", - "spring.kafka.retry.topic.attempts=5", "spring.kafka.retry.topic.delay=100ms", - "spring.kafka.retry.topic.multiplier=2", "spring.kafka.retry.topic.max-delay=300ms", + "spring.kafka.retry.topic.attempts=5", "spring.kafka.retry.topic.backoff.delay=100ms", + "spring.kafka.retry.topic.backoff.multiplier=2", "spring.kafka.retry.topic.backoff.max-delay=300ms", "spring.kafka.consumer.auto-offset-reset=earliest"); RetryTopicConfiguration configuration = this.context.getBean(RetryTopicConfiguration.class); assertThat(configuration.getDestinationTopicProperties()).extracting(DestinationTopic.Properties::delay) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfigurationTests.java b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfigurationTests.java rename to spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfigurationTests.java index e1cae37d5328..0cd90450e12c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.io.File; import java.time.Duration; @@ -566,22 +566,6 @@ void retryTopicConfigurationWithExponentialBackOff() { }); } - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void retryTopicConfigurationWithExponentialBackOffUsingDeprecatedProperties() { - this.contextRunner.withPropertyValues("spring.application.name=my-test-app", - "spring.kafka.bootstrap-servers=localhost:9092,localhost:9093", "spring.kafka.retry.topic.enabled=true", - "spring.kafka.retry.topic.attempts=5", "spring.kafka.retry.topic.delay=100ms", - "spring.kafka.retry.topic.multiplier=2", "spring.kafka.retry.topic.max-delay=300ms") - .run((context) -> { - RetryTopicConfiguration configuration = context.getBean(RetryTopicConfiguration.class); - assertThat(configuration.getDestinationTopicProperties()).hasSize(5) - .extracting(DestinationTopic.Properties::delay, DestinationTopic.Properties::suffix) - .containsExactly(tuple(0L, ""), tuple(100L, "-retry-0"), tuple(200L, "-retry-1"), - tuple(300L, "-retry-2"), tuple(0L, "-dlt")); - }); - } - @Test void retryTopicConfigurationWithDefaultProperties() { this.contextRunner.withPropertyValues("spring.application.name=my-test-app", @@ -607,18 +591,6 @@ void retryTopicConfigurationWithFixedBackOff() { .containsExactly(0L, 2000L, 0L))); } - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void retryTopicConfigurationWithFixedBackOffUsingDeprecatedProperties() { - this.contextRunner.withPropertyValues("spring.application.name=my-test-app", - "spring.kafka.bootstrap-servers=localhost:9092,localhost:9093", "spring.kafka.retry.topic.enabled=true", - "spring.kafka.retry.topic.attempts=4", "spring.kafka.retry.topic.delay=2s") - .run(assertRetryTopicConfiguration( - (configuration) -> assertThat(configuration.getDestinationTopicProperties()).hasSize(3) - .extracting(DestinationTopic.Properties::delay) - .containsExactly(0L, 2000L, 0L))); - } - @Test void retryTopicConfigurationWithNoBackOff() { this.contextRunner.withPropertyValues("spring.application.name=my-test-app", @@ -630,18 +602,6 @@ void retryTopicConfigurationWithNoBackOff() { .containsExactly(0L, 0L, 0L))); } - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void retryTopicConfigurationWithNoBackOffUsingDeprecatedProperties() { - this.contextRunner.withPropertyValues("spring.application.name=my-test-app", - "spring.kafka.bootstrap-servers=localhost:9092,localhost:9093", "spring.kafka.retry.topic.enabled=true", - "spring.kafka.retry.topic.attempts=4", "spring.kafka.retry.topic.delay=0") - .run(assertRetryTopicConfiguration( - (configuration) -> assertThat(configuration.getDestinationTopicProperties()).hasSize(3) - .extracting(DestinationTopic.Properties::delay) - .containsExactly(0L, 0L, 0L))); - } - private ContextConsumer assertRetryTopicConfiguration( Consumer configuration) { return (context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaPropertiesTests.java b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaPropertiesTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaPropertiesTests.java rename to spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaPropertiesTests.java index 661b27049c6e..3d79ec287da3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/KafkaPropertiesTests.java +++ b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/KafkaPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.kafka; +package org.springframework.boot.kafka.autoconfigure; import java.util.Collections; import java.util.Map; @@ -22,11 +22,11 @@ import org.apache.kafka.common.config.SslConfigs; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Admin; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Cleanup; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties.IsolationLevel; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Listener; import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; +import org.springframework.boot.kafka.autoconfigure.KafkaProperties.Admin; +import org.springframework.boot.kafka.autoconfigure.KafkaProperties.Cleanup; +import org.springframework.boot.kafka.autoconfigure.KafkaProperties.IsolationLevel; +import org.springframework.boot.kafka.autoconfigure.KafkaProperties.Listener; import org.springframework.core.io.ClassPathResource; import org.springframework.kafka.core.CleanupConfig; import org.springframework.kafka.core.KafkaAdmin; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/metrics/KafkaMetricsAutoConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/metrics/KafkaMetricsAutoConfigurationTests.java index e59dee60af3f..91724607bdda 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-kafka/src/test/java/org/springframework/boot/kafka/autoconfigure/metrics/KafkaMetricsAutoConfigurationTests.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.kafka.autoconfigure.metrics; import java.util.regex.Pattern; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.apache.kafka.streams.StreamsBuilder; import org.apache.kafka.streams.kstream.KStream; import org.apache.kafka.streams.kstream.KTable; import org.apache.kafka.streams.kstream.Materialized; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration; +import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -54,7 +54,7 @@ class KafkaMetricsAutoConfigurationTests { @Test void whenThereIsAMeterRegistryThenMetricsListenersAreAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) .withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class)) .run((context) -> { assertThat(((DefaultKafkaProducerFactory) context.getBean(DefaultKafkaProducerFactory.class)) @@ -79,7 +79,7 @@ void whenKafkaStreamsIsEnabledAndThereIsAMeterRegistryThenMetricsListenersAreAdd this.contextRunner.withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class)) .withUserConfiguration(EnableKafkaStreamsConfiguration.class) .withPropertyValues("spring.application.name=my-test-app") - .with(MetricsRun.simple()) + .withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) .run((context) -> { StreamsBuilderFactoryBean streamsBuilderFactoryBean = context.getBean(StreamsBuilderFactoryBean.class); assertThat(streamsBuilderFactoryBean.getListeners()).hasSize(1) diff --git a/spring-boot-project/spring-boot-ldap/build.gradle b/spring-boot-project/spring-boot-ldap/build.gradle new file mode 100644 index 000000000000..03929388a601 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/build.gradle @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot LDAP" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.ldap:spring-ldap-core") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("com.unboundid:unboundid-ldapsdk") + optional("org.testcontainers:ldap") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("org.apache.commons:commons-pool2") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/ldap/LLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/docker/compose/LLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/ldap/LLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/docker/compose/LLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java index f8c04a4d8479..44102463544b 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/ldap/LLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/docker/compose/LLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.ldap; +package org.springframework.boot.ldap.docker.compose; -import org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/ldap/OpenLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/docker/compose/OpenLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/ldap/OpenLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/docker/compose/OpenLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java index c3c0aceecc15..0d1eebe990e2 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/ldap/OpenLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/docker/compose/OpenLdapDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.ldap; +package org.springframework.boot.ldap.docker.compose; -import org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/testcontainers/LLdapContainerConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/testcontainers/LLdapContainerConnectionDetailsFactoryIntegrationTests.java index cf2f15435cf2..8fd4d88f8d8a 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/testcontainers/LLdapContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.ldap; +package org.springframework.boot.ldap.testcontainers; import java.util.List; @@ -25,7 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/OpenLdapContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/testcontainers/OpenLdapContainerConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/OpenLdapContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/testcontainers/OpenLdapContainerConnectionDetailsFactoryIntegrationTests.java index e8841b56b6c7..ca522aa99100 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ldap/OpenLdapContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-ldap/src/dockerTest/java/org/springframework/boot/ldap/testcontainers/OpenLdapContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.ldap; +package org.springframework.boot.ldap.testcontainers; import java.util.List; @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.OpenLdapContainer; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-ldap/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-ldap/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/ldap/ldap-compose.yaml b/spring-boot-project/spring-boot-ldap/src/dockerTest/resources/org/springframework/boot/ldap/docker/compose/ldap-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/ldap/ldap-compose.yaml rename to spring-boot-project/spring-boot-ldap/src/dockerTest/resources/org/springframework/boot/ldap/docker/compose/ldap-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/ldap/lldap-compose.yaml b/spring-boot-project/spring-boot-ldap/src/dockerTest/resources/org/springframework/boot/ldap/docker/compose/lldap-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/ldap/lldap-compose.yaml rename to spring-boot-project/spring-boot-ldap/src/dockerTest/resources/org/springframework/boot/ldap/docker/compose/lldap-compose.yaml diff --git a/spring-boot-project/spring-boot-ldap/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-ldap/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfiguration.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfiguration.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapAutoConfiguration.java index e9f556da2430..b0b676d92fc5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfiguration.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap; +package org.springframework.boot.ldap.autoconfigure; import java.util.Collections; import java.util.Locale; @@ -24,10 +24,10 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.ldap.LdapProperties.Template; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.convert.ApplicationConversionService; +import org.springframework.boot.ldap.autoconfigure.LdapProperties.Template; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.ldap.convert.ConverterUtils; @@ -44,7 +44,7 @@ * * @author Eddú Meléndez * @author Vedran Pavic - * @since 1.5.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(ContextSource.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapConnectionDetails.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapConnectionDetails.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapConnectionDetails.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapConnectionDetails.java index 68d5050bb864..f43734cf08dd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapConnectionDetails.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap; +package org.springframework.boot.ldap.autoconfigure; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; @@ -22,7 +22,7 @@ * Details required to establish a connection to an LDAP service. * * @author Philipp Kessler - * @since 3.3.0 + * @since 4.0.0 */ public interface LdapConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapProperties.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapProperties.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java index 77ff3e428efb..9e2ac29929bc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapProperties.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap; +package org.springframework.boot.ldap.autoconfigure; import java.util.HashMap; import java.util.Map; @@ -30,7 +30,7 @@ * Configuration properties for LDAP. * * @author Eddú Meléndez - * @since 1.5.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.ldap") public class LdapProperties { @@ -199,8 +199,6 @@ public void setIgnoreSizeLimitExceededException(Boolean ignoreSizeLimitExceededE /** * Define the methods to handle referrals. - * - * @since 3.5.0 */ public enum Referral { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/PropertiesLdapConnectionDetails.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/PropertiesLdapConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/PropertiesLdapConnectionDetails.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/PropertiesLdapConnectionDetails.java index 18a817ef96f4..433994841d3f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/PropertiesLdapConnectionDetails.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/PropertiesLdapConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap; +package org.springframework.boot.ldap.autoconfigure; import org.springframework.core.env.Environment; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java index 7cb5082a5a29..0fa9a56cd6aa 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap.embedded; +package org.springframework.boot.ldap.autoconfigure.embedded; import java.io.InputStream; import java.util.Collections; @@ -40,12 +40,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; -import org.springframework.boot.autoconfigure.ldap.LdapProperties; -import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration.EmbeddedLdapAutoConfigurationRuntimeHints; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration; +import org.springframework.boot.ldap.autoconfigure.LdapProperties; +import org.springframework.boot.ldap.autoconfigure.embedded.EmbeddedLdapAutoConfiguration.EmbeddedLdapAutoConfigurationRuntimeHints; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; @@ -70,7 +70,7 @@ * @author Eddú Meléndez * @author Mathieu Ouellet * @author Raja Kolli - * @since 1.5.0 + * @since 4.0.0 */ @AutoConfiguration(before = LdapAutoConfiguration.class) @EnableConfigurationProperties({ LdapProperties.class, EmbeddedLdapProperties.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java index c4f5c9db1b46..e5b7fc97d773 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap.embedded; +package org.springframework.boot.ldap.autoconfigure.embedded; import java.util.ArrayList; import java.util.List; @@ -29,7 +29,7 @@ * * @author Eddú Meléndez * @author Mathieu Ouellet - * @since 1.5.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.ldap.embedded") public class EmbeddedLdapProperties { diff --git a/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/package-info.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/package-info.java new file mode 100644 index 000000000000..6f280abd4dbd --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for embedded LDAP. + */ +package org.springframework.boot.ldap.autoconfigure.embedded; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ldap/LdapHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/LdapHealthContributorAutoConfiguration.java similarity index 76% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ldap/LdapHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/LdapHealthContributorAutoConfiguration.java index d17322224e4a..17551d803abc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ldap/LdapHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/LdapHealthContributorAutoConfiguration.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.ldap; +package org.springframework.boot.ldap.autoconfigure.health; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.ldap.LdapHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration; +import org.springframework.boot.ldap.health.LdapHealthIndicator; import org.springframework.context.annotation.Bean; import org.springframework.ldap.core.LdapOperations; @@ -35,10 +35,10 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = LdapAutoConfiguration.class) -@ConditionalOnClass(LdapOperations.class) +@ConditionalOnClass({ LdapOperations.class, LdapHealthIndicator.class, ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(LdapOperations.class) @ConditionalOnEnabledHealthIndicator("ldap") public class LdapHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..73189bd89d30 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for LDAP health. + */ +package org.springframework.boot.ldap.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/package-info.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/package-info.java new file mode 100644 index 000000000000..ade61fdf0e10 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for LDAP. + */ +package org.springframework.boot.ldap.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/LLdapDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/LLdapDockerComposeConnectionDetailsFactory.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/LLdapDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/LLdapDockerComposeConnectionDetailsFactory.java index 7196132cc689..99ecbd94e9fc 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/LLdapDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/LLdapDockerComposeConnectionDetailsFactory.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.ldap; +package org.springframework.boot.ldap.docker.compose; import java.util.Map; -import org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link LdapConnectionDetails} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/OpenLdapDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/OpenLdapDockerComposeConnectionDetailsFactory.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/OpenLdapDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/OpenLdapDockerComposeConnectionDetailsFactory.java index d96ee8ce2326..a580a37641ba 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/ldap/OpenLdapDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/OpenLdapDockerComposeConnectionDetailsFactory.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.ldap; +package org.springframework.boot.ldap.docker.compose; import java.util.Arrays; import java.util.Map; import java.util.stream.Collectors; -import org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link LdapConnectionDetails} diff --git a/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/package-info.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/package-info.java new file mode 100644 index 000000000000..705f92e30d87 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose LDAP service connections. + */ +package org.springframework.boot.ldap.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ldap/LdapHealthIndicator.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/LdapHealthIndicator.java similarity index 88% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ldap/LdapHealthIndicator.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/LdapHealthIndicator.java index acb25d9cbc44..6865b5814a96 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ldap/LdapHealthIndicator.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/LdapHealthIndicator.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.ldap; +package org.springframework.boot.ldap.health; import javax.naming.NamingException; import javax.naming.directory.DirContext; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.ldap.core.ContextExecutor; import org.springframework.ldap.core.LdapOperations; import org.springframework.util.Assert; @@ -31,7 +31,7 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public class LdapHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/package-info.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/package-info.java new file mode 100644 index 000000000000..427c1cc08747 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for LDAP. + */ +package org.springframework.boot.ldap.health; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/LLdapContainerConnectionDetailsFactory.java similarity index 93% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/LLdapContainerConnectionDetailsFactory.java index 824824d2384b..c7d3f3d34e25 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/LLdapContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/LLdapContainerConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.ldap; +package org.springframework.boot.ldap.testcontainers; import org.testcontainers.ldap.LLdapContainer; -import org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails; +import org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/OpenLdapContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/OpenLdapContainerConnectionDetailsFactory.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/OpenLdapContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/OpenLdapContainerConnectionDetailsFactory.java index 443a48b2436c..a263712b0648 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/OpenLdapContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/OpenLdapContainerConnectionDetailsFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.ldap; +package org.springframework.boot.ldap.testcontainers; import java.util.Arrays; import java.util.Map; @@ -23,7 +23,7 @@ import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.autoconfigure.ldap.LdapConnectionDetails; +import org.springframework.boot.ldap.autoconfigure.LdapConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/package-info.java b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/package-info.java new file mode 100644 index 000000000000..d4242633be41 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Ldap service connections. + */ +package org.springframework.boot.ldap.testcontainers; diff --git a/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..b896e46bb8d9 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.ldap.docker.compose.LLdapDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.ldap.docker.compose.OpenLdapDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.ldap.testcontainers.LLdapContainerConnectionDetailsFactory,\ +org.springframework.boot.ldap.testcontainers.OpenLdapContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..eb1fc2a1db05 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring/additional-spring-configuration-metadata.json @@ -0,0 +1,10 @@ +{ + "properties": [ + { + "name": "management.health.ldap.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable LDAP health check.", + "defaultValue": true + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..997161deca67 --- /dev/null +++ b/spring-boot-project/spring-boot-ldap/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration +org.springframework.boot.ldap.autoconfigure.embedded.EmbeddedLdapAutoConfiguration +org.springframework.boot.ldap.autoconfigure.health.LdapHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfigurationTests.java b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/LdapAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfigurationTests.java rename to spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/LdapAutoConfigurationTests.java index f534c19495c0..01b51af2e2a4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/LdapAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap; +package org.springframework.boot.ldap.autoconfigure; import javax.naming.Name; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapPropertiesTests.java b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/LdapPropertiesTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapPropertiesTests.java rename to spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/LdapPropertiesTests.java index a521a42a3403..af5202ea4eee 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapPropertiesTests.java +++ b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/LdapPropertiesTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap; +package org.springframework.boot.ldap.autoconfigure; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.ldap.LdapProperties.Template; +import org.springframework.boot.ldap.autoconfigure.LdapProperties.Template; import org.springframework.ldap.core.LdapTemplate; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java rename to spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfigurationTests.java index f09d692d1c48..581ab966f8ca 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.ldap.embedded; +package org.springframework.boot.ldap.autoconfigure.embedded; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -31,7 +31,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.util.TestPropertyValues; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ldap/LdapHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/health/LdapHealthContributorAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ldap/LdapHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/health/LdapHealthContributorAutoConfigurationTests.java index b37e603105e7..1d0dbce7e7f9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ldap/LdapHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/health/LdapHealthContributorAutoConfigurationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.ldap; +package org.springframework.boot.ldap.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.ldap.LdapHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.ldap.health.LdapHealthIndicator; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.ldap.core.LdapOperations; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ldap/LdapHealthIndicatorTests.java b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/health/LdapHealthIndicatorTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ldap/LdapHealthIndicatorTests.java rename to spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/health/LdapHealthIndicatorTests.java index 0f58465888b7..eef8eb4fa2a3 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ldap/LdapHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/health/LdapHealthIndicatorTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.ldap; +package org.springframework.boot.ldap.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.ldap.CommunicationException; import org.springframework.ldap.core.ContextExecutor; import org.springframework.ldap.core.LdapTemplate; diff --git a/spring-boot-project/spring-boot-liquibase/build.gradle b/spring-boot-project/spring-boot-liquibase/build.gradle new file mode 100644 index 000000000000..3da80faccd05 --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/build.gradle @@ -0,0 +1,56 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Liquibase" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-jdbc")) + api("org.liquibase:liquibase-core") { + exclude(group: "javax.xml.bind", module: "jaxb-api") + } + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("org.testcontainers:jdbc") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:postgresql") + dockerTestRuntimeOnly("org.postgresql:postgresql") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("com.h2database:h2") + testImplementation("com.zaxxer:HikariCP") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("org.postgresql:postgresql") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/liquibase/JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-liquibase/src/dockerTest/java/org/springframework/boot/liquibase/docker/compose/JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/liquibase/JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-liquibase/src/dockerTest/java/org/springframework/boot/liquibase/docker/compose/JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests.java index 05295181d82d..95e47e01c416 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/liquibase/JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-liquibase/src/dockerTest/java/org/springframework/boot/liquibase/docker/compose/JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.liquibase; +package org.springframework.boot.liquibase.docker.compose; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/liquibase/LiquibaseContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-liquibase/src/dockerTest/java/org/springframework/boot/liquibase/testcontainers/LiquibaseContainerConnectionDetailsFactoryTests.java similarity index 92% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/liquibase/LiquibaseContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-liquibase/src/dockerTest/java/org/springframework/boot/liquibase/testcontainers/LiquibaseContainerConnectionDetailsFactoryTests.java index c244801ccedd..a2fd70ece8a6 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/liquibase/LiquibaseContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-liquibase/src/dockerTest/java/org/springframework/boot/liquibase/testcontainers/LiquibaseContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.liquibase; +package org.springframework.boot.liquibase.testcontainers; import liquibase.integration.spring.SpringLiquibase; import org.junit.jupiter.api.Test; @@ -24,8 +24,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/resources/db/changelog/db.changelog-master.yaml b/spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/db/changelog/db.changelog-master.yaml similarity index 100% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/resources/db/changelog/db.changelog-master.yaml rename to spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/db/changelog/db.changelog-master.yaml diff --git a/spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/liquibase/liquibase-compose.yaml b/spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/org/springframework/boot/liquibase/docker/compose/liquibase-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/liquibase/liquibase-compose.yaml rename to spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/org/springframework/boot/liquibase/docker/compose/liquibase-compose.yaml diff --git a/spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzer.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzer.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/liquibase/LiquibaseDatabaseInitializerDetector.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/LiquibaseDatabaseInitializerDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/liquibase/LiquibaseDatabaseInitializerDetector.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/LiquibaseDatabaseInitializerDetector.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/DataSourceClosingSpringLiquibase.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/DataSourceClosingSpringLiquibase.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/DataSourceClosingSpringLiquibase.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/DataSourceClosingSpringLiquibase.java index f2135aea54c2..8e92cfdf01b0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/DataSourceClosingSpringLiquibase.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/DataSourceClosingSpringLiquibase.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import java.lang.reflect.Method; @@ -31,7 +31,7 @@ * {@link DataSource} once the database has been migrated. * * @author Andy Wilkinson - * @since 2.0.6 + * @since 4.0.0 */ public class DataSourceClosingSpringLiquibase extends SpringLiquibase implements DisposableBean { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseAutoConfiguration.java index 856bd6d68158..f6f7b53ae6ee 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import javax.sql.DataSource; @@ -37,13 +37,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseAutoConfigurationRuntimeHints; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseDataSourceCondition; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration.LiquibaseAutoConfigurationRuntimeHints; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration.LiquibaseDataSourceCondition; import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -71,9 +70,9 @@ * @author Evgeniy Cheban * @author Moritz Halbritter * @author Ahmed Ashour - * @since 1.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) +@AutoConfiguration(after = DataSourceAutoConfiguration.class) @ConditionalOnClass({ SpringLiquibase.class, DatabaseChange.class }) @ConditionalOnBooleanProperty(name = "spring.liquibase.enabled", matchIfMissing = true) @Conditional(LiquibaseDataSourceCondition.class) @@ -82,8 +81,7 @@ public class LiquibaseAutoConfiguration { @Bean - public LiquibaseSchemaManagementProvider liquibaseDefaultDdlModeProvider( - ObjectProvider liquibases) { + LiquibaseSchemaManagementProvider liquibaseDefaultDdlModeProvider(ObjectProvider liquibases) { return new LiquibaseSchemaManagementProvider(liquibases); } @@ -91,7 +89,7 @@ public LiquibaseSchemaManagementProvider liquibaseDefaultDdlModeProvider( @ConditionalOnClass(ConnectionCallback.class) @ConditionalOnMissingBean(SpringLiquibase.class) @EnableConfigurationProperties(LiquibaseProperties.class) - public static class LiquibaseConfiguration { + static class LiquibaseConfiguration { @Bean @ConditionalOnMissingBean(LiquibaseConnectionDetails.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseConnectionDetails.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseConnectionDetails.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseConnectionDetails.java index aa7e2a7a4c52..5fdd97d43644 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseConnectionDetails.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; import org.springframework.boot.jdbc.DatabaseDriver; @@ -23,7 +23,7 @@ * Details required for Liquibase to establish a connection to an SQL service using JDBC. * * @author Andy Wilkinson - * @since 3.1.0 + * @since 4.0.0 */ public interface LiquibaseConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseDataSource.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseDataSource.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseDataSource.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseDataSource.java index 75089670c3ba..8947d1c57437 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseDataSource.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseDataSource.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -29,7 +29,7 @@ * second data source, the other (main) one would normally be marked as {@code @Primary}. * * @author Eddú Meléndez - * @since 1.4.1 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseProperties.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseProperties.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseProperties.java index 55bc8347585b..d3e2536e0725 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseProperties.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import java.io.File; import java.util.List; @@ -35,7 +35,7 @@ * @author Eddú Meléndez * @author Ferenc Gratzer * @author Evgeniy Cheban - * @since 1.1.0 + * @since 4.0.0 */ @ConfigurationProperties(prefix = "spring.liquibase", ignoreUnknownFields = false) public class LiquibaseProperties { @@ -361,8 +361,6 @@ public void setLicenseKey(String licenseKey) { * Enumeration of types of summary to show. Values are the same as those on * {@link UpdateSummaryEnum}. To maximize backwards compatibility, the Liquibase enum * is not used directly. - * - * @since 3.2.1 */ public enum ShowSummary { @@ -387,8 +385,6 @@ public enum ShowSummary { * Enumeration of destinations to which the summary should be output. Values are the * same as those on {@link UpdateSummaryOutputEnum}. To maximize backwards * compatibility, the Liquibase enum is not used directly. - * - * @since 3.2.1 */ public enum ShowSummaryOutput { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseSchemaManagementProvider.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseSchemaManagementProvider.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseSchemaManagementProvider.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseSchemaManagementProvider.java index 70bf9aa02dfa..c763ce8232fc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseSchemaManagementProvider.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseSchemaManagementProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import java.util.stream.StreamSupport; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/endpoint/LiquibaseEndpointAutoConfiguration.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointAutoConfiguration.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/endpoint/LiquibaseEndpointAutoConfiguration.java index 80708fa88d8a..5e591165cf56 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/endpoint/LiquibaseEndpointAutoConfiguration.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure.endpoint; import liquibase.integration.spring.SpringLiquibase; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.liquibase.LiquibaseEndpoint; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.liquibase.DataSourceClosingSpringLiquibase; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.DataSourceClosingSpringLiquibase; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; +import org.springframework.boot.liquibase.endpoint.LiquibaseEndpoint; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -36,10 +36,10 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link LiquibaseEndpoint}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = LiquibaseAutoConfiguration.class) -@ConditionalOnClass(SpringLiquibase.class) +@ConditionalOnClass({ SpringLiquibase.class, LiquibaseEndpoint.class, ConditionalOnAvailableEndpoint.class }) @ConditionalOnAvailableEndpoint(LiquibaseEndpoint.class) public class LiquibaseEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/endpoint/package-info.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/endpoint/package-info.java new file mode 100644 index 000000000000..02c03c333efa --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Liquibase endpoint. + */ +package org.springframework.boot.liquibase.autoconfigure.endpoint; diff --git a/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/package-info.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/package-info.java new file mode 100644 index 000000000000..11e1da2a4a7e --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Liquibase. + */ +package org.springframework.boot.liquibase.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/liquibase/JdbcAdaptingLiquibaseConnectionDetailsFactory.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/docker/compose/JdbcAdaptingLiquibaseConnectionDetailsFactory.java similarity index 88% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/liquibase/JdbcAdaptingLiquibaseConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/docker/compose/JdbcAdaptingLiquibaseConnectionDetailsFactory.java index d1fc4ff5d22f..3bd6b99f040a 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/liquibase/JdbcAdaptingLiquibaseConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/docker/compose/JdbcAdaptingLiquibaseConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.liquibase; +package org.springframework.boot.liquibase.docker.compose; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseConnectionDetails; /** * {@link ConnectionDetailsFactory} that produces {@link LiquibaseConnectionDetails} by diff --git a/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/docker/compose/package-info.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/docker/compose/package-info.java new file mode 100644 index 000000000000..85c2ab397dfb --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Liquibase service connections. + */ +package org.springframework.boot.liquibase.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/liquibase/LiquibaseEndpoint.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/endpoint/LiquibaseEndpoint.java similarity index 99% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/liquibase/LiquibaseEndpoint.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/endpoint/LiquibaseEndpoint.java index 38666551be34..6469f5922107 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/liquibase/LiquibaseEndpoint.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/endpoint/LiquibaseEndpoint.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.liquibase; +package org.springframework.boot.liquibase.endpoint; import java.time.Instant; import java.util.HashMap; @@ -43,7 +43,7 @@ * {@link Endpoint @Endpoint} to expose liquibase info. * * @author Eddú Meléndez - * @since 2.0.0 + * @since 4.0.0 */ @Endpoint(id = "liquibase") public class LiquibaseEndpoint { diff --git a/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/endpoint/package-info.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/endpoint/package-info.java new file mode 100644 index 000000000000..539140b4eba9 --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator endpoint for Liquibase. + */ +package org.springframework.boot.liquibase.endpoint; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/liquibase/package-info.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/liquibase/package-info.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/package-info.java diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/liquibase/LiquibaseContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/testcontainers/LiquibaseContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/liquibase/LiquibaseContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/testcontainers/LiquibaseContainerConnectionDetailsFactory.java index 24327f622b8b..701611ce3b0b 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/liquibase/LiquibaseContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/testcontainers/LiquibaseContainerConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.liquibase; +package org.springframework.boot.liquibase.testcontainers; import org.testcontainers.containers.JdbcDatabaseContainer; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/testcontainers/package-info.java b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/testcontainers/package-info.java new file mode 100644 index 000000000000..ca59b899a86e --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/main/java/org/springframework/boot/liquibase/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Liquibase service connections. + */ +package org.springframework.boot.liquibase.testcontainers; diff --git a/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..7ae151708954 --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,46 @@ +{ + "properties": [ + { + "name": "spring.liquibase.check-change-log-location", + "type": "java.lang.Boolean", + "description": "Check the change log location exists.", + "defaultValue": true, + "deprecation": { + "reason": "Liquibase has its own check that checks if the change log location exists making this property redundant.", + "level": "error" + } + }, + { + "name": "spring.liquibase.labels", + "deprecation": { + "replacement": "spring.liquibase.label-filter", + "level": "error" + } + }, + { + "name": "spring.liquibase.show-summary", + "defaultValue": "summary" + }, + { + "name": "spring.liquibase.show-summary-output", + "defaultValue": "log" + }, + { + "name": "spring.liquibase.ui-service", + "defaultValue": "logger" + } + ], + "hints": [ + { + "name": "spring.liquibase.change-log", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "org.springframework.core.io.Resource" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..29f0956de64d --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/spring.factories @@ -0,0 +1,12 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.liquibase.docker.compose.JdbcAdaptingLiquibaseConnectionDetailsFactory,\ +org.springframework.boot.liquibase.testcontainers.LiquibaseContainerConnectionDetailsFactory + +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.boot.liquibase.LiquibaseChangelogMissingFailureAnalyzer + +# Database Initializer Detectors +org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\ +org.springframework.boot.liquibase.LiquibaseDatabaseInitializerDetector diff --git a/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..bb4b46df1400 --- /dev/null +++ b/spring-boot-project/spring-boot-liquibase/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration +org.springframework.boot.liquibase.autoconfigure.endpoint.LiquibaseEndpointAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzerTests.java b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzerTests.java similarity index 91% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzerTests.java index 69986ea41f52..1315c8b607bc 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/LiquibaseChangelogMissingFailureAnalyzerTests.java @@ -18,13 +18,12 @@ import javax.sql.DataSource; +import com.zaxxer.hikari.HikariDataSource; import liquibase.integration.spring.SpringLiquibase; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.diagnostics.FailureAnalysis; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,7 +35,6 @@ * * @author Sebastiaan Fernandez */ -@ClassPathExclusions("derby-*") class LiquibaseChangelogMissingFailureAnalyzerTests { @Test @@ -70,7 +68,10 @@ static class LiquibaseConfiguration { @Bean DataSource dataSource() { - return DataSourceBuilder.create().url("jdbc:hsqldb:mem:test").username("sa").build(); + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setJdbcUrl("jdbc:h2:mem:test"); + dataSource.setUsername("sa"); + return dataSource; } @Bean diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/liquibase/LiquibaseEndpointTests.java b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/actuate/endpoint/LiquibaseEndpointTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/liquibase/LiquibaseEndpointTests.java rename to spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/actuate/endpoint/LiquibaseEndpointTests.java index 8c04745f124d..822649ed1971 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/liquibase/LiquibaseEndpointTests.java +++ b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/actuate/endpoint/LiquibaseEndpointTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.liquibase; +package org.springframework.boot.liquibase.actuate.endpoint; import java.sql.Connection; import java.sql.SQLException; @@ -27,12 +27,13 @@ import liquibase.integration.spring.SpringLiquibase; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.liquibase.LiquibaseEndpoint.LiquibaseBeanDescriptor; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; +import org.springframework.boot.liquibase.endpoint.LiquibaseEndpoint; +import org.springframework.boot.liquibase.endpoint.LiquibaseEndpoint.LiquibaseBeanDescriptor; import org.springframework.boot.sql.init.DatabaseInitializationSettings; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; @@ -213,7 +214,7 @@ SpringLiquibase liquibaseBackup(DataSource dataSourceBackup) { private DataSource createEmbeddedDatabase() { return new EmbeddedDatabaseBuilder().generateUniqueName(true) - .setType(EmbeddedDatabaseConnection.HSQLDB.getType()) + .setType(EmbeddedDatabaseConnection.H2.getType()) .build(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/Liquibase423AutoConfigurationTests.java b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/Liquibase423AutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/Liquibase423AutoConfigurationTests.java rename to spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/Liquibase423AutoConfigurationTests.java index 7f17bece091d..7711150ab85a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/Liquibase423AutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/Liquibase423AutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import java.util.function.Consumer; @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseAutoConfigurationTests.java similarity index 77% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java rename to spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseAutoConfigurationTests.java index e63eb35dc300..c2c7e2c952fd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/LiquibaseAutoConfigurationTests.java @@ -14,11 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import java.io.File; import java.io.IOException; -import java.io.Serializable; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -27,7 +26,6 @@ import java.nio.file.Path; import java.sql.Connection; import java.sql.SQLException; -import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.function.Consumer; @@ -35,10 +33,6 @@ import javax.sql.DataSource; import com.zaxxer.hikari.HikariDataSource; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; import liquibase.Liquibase; import liquibase.UpdateSummaryEnum; import liquibase.UpdateSummaryOutputEnum; @@ -46,7 +40,6 @@ import liquibase.integration.spring.Customizer; import liquibase.integration.spring.SpringLiquibase; import liquibase.ui.UIServiceEnum; -import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.io.TempDir; @@ -56,16 +49,11 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseAutoConfigurationRuntimeHints; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; -import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; +import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration.LiquibaseAutoConfigurationRuntimeHints; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -81,7 +69,6 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -118,7 +105,7 @@ void backsOffWithNoDataSourceBeanAndNoLiquibaseUrl() { @Test @WithDbChangelogMasterYamlResource void createsDataSourceWithNoDataSourceBeanAndLiquibaseUrl() { - String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID(); + String jdbcUrl = "jdbc:h2:mem:liquibase" + UUID.randomUUID(); this.contextRunner.withPropertyValues("spring.liquibase.url:" + jdbcUrl).run(assertLiquibase((liquibase) -> { SimpleDriverDataSource dataSource = (SimpleDriverDataSource) liquibase.getDataSource(); assertThat(dataSource.getUrl()).isEqualTo(jdbcUrl); @@ -127,7 +114,7 @@ void createsDataSourceWithNoDataSourceBeanAndLiquibaseUrl() { @Test void backsOffWithLiquibaseUrlAndNoSpringJdbc() { - this.contextRunner.withPropertyValues("spring.liquibase.url:jdbc:hsqldb:mem:" + UUID.randomUUID()) + this.contextRunner.withPropertyValues("spring.liquibase.url:jdbc:h2:mem:" + UUID.randomUUID()) .withClassLoader(new FilteredClassLoader("org.springframework.jdbc")) .run((context) -> assertThat(context).doesNotHaveBean(SpringLiquibase.class)); } @@ -162,7 +149,7 @@ void liquibaseDataSourceIsUsedOverJdbcConnectionDetails() { .withUserConfiguration(LiquibaseDataSourceConfiguration.class, JdbcConnectionDetailsConfiguration.class) .run(assertLiquibase((liquibase) -> { HikariDataSource dataSource = (HikariDataSource) liquibase.getDataSource(); - assertThat(dataSource.getJdbcUrl()).startsWith("jdbc:hsqldb:mem:liquibasetest"); + assertThat(dataSource.getJdbcUrl()).startsWith("jdbc:h2:mem:liquibasetest"); assertThat(dataSource.getUsername()).isEqualTo("sa"); assertThat(dataSource.getPassword()).isNull(); })); @@ -176,7 +163,7 @@ void liquibaseDataSourceIsUsedOverLiquibaseConnectionDetails() { LiquibaseConnectionDetailsConfiguration.class) .run(assertLiquibase((liquibase) -> { HikariDataSource dataSource = (HikariDataSource) liquibase.getDataSource(); - assertThat(dataSource.getJdbcUrl()).startsWith("jdbc:hsqldb:mem:liquibasetest"); + assertThat(dataSource.getJdbcUrl()).startsWith("jdbc:h2:mem:liquibasetest"); assertThat(dataSource.getUsername()).isEqualTo("sa"); assertThat(dataSource.getPassword()).isNull(); })); @@ -186,13 +173,12 @@ void liquibaseDataSourceIsUsedOverLiquibaseConnectionDetails() { @WithDbChangelogMasterYamlResource void liquibasePropertiesAreUsedOverJdbcConnectionDetails() { this.contextRunner - .withPropertyValues("spring.liquibase.url=jdbc:hsqldb:mem:liquibasetest", "spring.liquibase.user=some-user", - "spring.liquibase.password=some-password", - "spring.liquibase.driver-class-name=org.hsqldb.jdbc.JDBCDriver") + .withPropertyValues("spring.liquibase.url=jdbc:h2:mem:liquibasetest", "spring.liquibase.user=some-user", + "spring.liquibase.password=some-password", "spring.liquibase.driver-class-name=org.h2.Driver") .withUserConfiguration(JdbcConnectionDetailsConfiguration.class) .run(assertLiquibase((liquibase) -> { SimpleDriverDataSource dataSource = (SimpleDriverDataSource) liquibase.getDataSource(); - assertThat(dataSource.getUrl()).startsWith("jdbc:hsqldb:mem:liquibasetest"); + assertThat(dataSource.getUrl()).startsWith("jdbc:h2:mem:liquibasetest"); assertThat(dataSource.getUsername()).isEqualTo("some-user"); assertThat(dataSource.getPassword()).isEqualTo("some-password"); })); @@ -201,9 +187,8 @@ void liquibasePropertiesAreUsedOverJdbcConnectionDetails() { @Test void liquibaseConnectionDetailsAreUsedOverLiquibaseProperties() { this.contextRunner.withSystemProperties("shouldRun=false") - .withPropertyValues("spring.liquibase.url=jdbc:hsqldb:mem:liquibasetest", "spring.liquibase.user=some-user", - "spring.liquibase.password=some-password", - "spring.liquibase.driver-class-name=org.hsqldb.jdbc.JDBCDriver") + .withPropertyValues("spring.liquibase.url=jdbc:h2:mem:liquibasetest", "spring.liquibase.user=some-user", + "spring.liquibase.password=some-password", "spring.liquibase.driver-class-name=org.h2.Driver") .withUserConfiguration(LiquibaseConnectionDetailsConfiguration.class) .run(assertLiquibase((liquibase) -> { SimpleDriverDataSource dataSource = (SimpleDriverDataSource) liquibase.getDataSource(); @@ -331,7 +316,7 @@ void overrideDropFirst() { @Test @WithDbChangelogMasterYamlResource void overrideClearChecksums() { - String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID(); + String jdbcUrl = "jdbc:h2:mem:liquibase" + UUID.randomUUID(); this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.liquibase.url:" + jdbcUrl) .run((context) -> assertThat(context).hasNotFailed()); @@ -343,21 +328,21 @@ void overrideClearChecksums() { @Test @WithDbChangelogMasterYamlResource void overrideDataSource() { - String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID(); + String jdbcUrl = "jdbc:h2:mem:liquibase" + UUID.randomUUID(); this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.liquibase.url:" + jdbcUrl) .run(assertLiquibase((liquibase) -> { SimpleDriverDataSource dataSource = (SimpleDriverDataSource) liquibase.getDataSource(); assertThat(dataSource.getUrl()).isEqualTo(jdbcUrl); - assertThat(dataSource.getDriver().getClass().getName()).isEqualTo("org.hsqldb.jdbc.JDBCDriver"); + assertThat(dataSource.getDriver().getClass().getName()).isEqualTo("org.h2.Driver"); })); } @Test @WithDbChangelogMasterYamlResource void overrideDataSourceAndDriverClassName() { - String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID(); - String driverClassName = "org.hsqldb.jdbcDriver"; + String jdbcUrl = "jdbc:h2:mem:liquibase" + UUID.randomUUID(); + String driverClassName = "org.h2.Driver"; this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.liquibase.url:" + jdbcUrl, "spring.liquibase.driver-class-name:" + driverClassName) @@ -400,7 +385,7 @@ void overrideUserWhenCustom() { @Test @WithDbChangelogMasterYamlResource void createDataSourceDoesNotFallbackToEmbeddedProperties() { - String jdbcUrl = "jdbc:hsqldb:mem:liquibase" + UUID.randomUUID(); + String jdbcUrl = "jdbc:h2:mem:liquibase" + UUID.randomUUID(); this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) .withPropertyValues("spring.liquibase.url:" + jdbcUrl) .run(assertLiquibase((liquibase) -> { @@ -549,49 +534,6 @@ void userConfigurationBeans() { }); } - @Test - @WithDbChangelogMasterYamlResource - void userConfigurationEntityManagerFactoryDependency() { - this.contextRunner.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class)) - .withUserConfiguration(LiquibaseUserConfiguration.class, EmbeddedDataSourceConfiguration.class) - .run((context) -> { - BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("entityManagerFactory"); - assertThat(beanDefinition.getDependsOn()).containsExactly("springLiquibase"); - }); - } - - @Test - @WithDbChangelogMasterYamlResource - @WithMetaInfPersistenceXmlResource - void jpaApplyDdl() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class)) - .run((context) -> { - Map jpaProperties = context.getBean(LocalContainerEntityManagerFactoryBean.class) - .getJpaPropertyMap(); - assertThat(jpaProperties).doesNotContainKey("hibernate.hbm2ddl.auto"); - }); - } - - @Test - @WithDbChangelogMasterYamlResource - @WithMetaInfPersistenceXmlResource - void jpaAndMultipleDataSourcesApplyDdl() { - this.contextRunner.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class)) - .withUserConfiguration(JpaWithMultipleDataSourcesConfiguration.class) - .run((context) -> { - LocalContainerEntityManagerFactoryBean normalEntityManagerFactoryBean = context - .getBean("&normalEntityManagerFactory", LocalContainerEntityManagerFactoryBean.class); - assertThat(normalEntityManagerFactoryBean.getJpaPropertyMap()).containsEntry("configured", "normal") - .containsEntry("hibernate.hbm2ddl.auto", "create-drop"); - LocalContainerEntityManagerFactoryBean liquibaseEntityManagerFactory = context - .getBean("&liquibaseEntityManagerFactory", LocalContainerEntityManagerFactoryBean.class); - assertThat(liquibaseEntityManagerFactory.getJpaPropertyMap()).containsEntry("configured", "liquibase") - .doesNotContainKey("hibernate.hbm2ddl.auto"); - }); - } - @Test @WithDbChangelogMasterYamlResource void userConfigurationJdbcTemplateDependency() { @@ -611,28 +553,6 @@ void overrideTag() { .run(assertLiquibase((liquibase) -> assertThat(liquibase.getTag()).isEqualTo("1.0.0"))); } - @Test - @WithDbChangelogMasterYamlResource - void whenLiquibaseIsAutoConfiguredThenJooqDslContextDependsOnSpringLiquibaseBeans() { - this.contextRunner.withConfiguration(AutoConfigurations.of(JooqAutoConfiguration.class)) - .withUserConfiguration(EmbeddedDataSourceConfiguration.class) - .run((context) -> { - BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("dslContext"); - assertThat(beanDefinition.getDependsOn()).containsExactly("liquibase"); - }); - } - - @Test - @WithDbChangelogMasterYamlResource - void whenCustomSpringLiquibaseIsDefinedThenJooqDslContextDependsOnSpringLiquibaseBeans() { - this.contextRunner.withConfiguration(AutoConfigurations.of(JooqAutoConfiguration.class)) - .withUserConfiguration(LiquibaseUserConfiguration.class, EmbeddedDataSourceConfiguration.class) - .run((context) -> { - BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("dslContext"); - assertThat(beanDefinition.getDependsOn()).containsExactly("springLiquibase"); - }); - } - @Test void shouldRegisterHints() { RuntimeHints hints = new RuntimeHints(); @@ -684,14 +604,14 @@ static class LiquibaseDataSourceConfiguration { @Bean @Primary DataSource normalDataSource() { - return DataSourceBuilder.create().url("jdbc:hsqldb:mem:normal" + UUID.randomUUID()).username("sa").build(); + return DataSourceBuilder.create().url("jdbc:h2:mem:normal" + UUID.randomUUID()).username("sa").build(); } @LiquibaseDataSource @Bean DataSource liquibaseDataSource() { return DataSourceBuilder.create() - .url("jdbc:hsqldb:mem:liquibasetest" + UUID.randomUUID()) + .url("jdbc:h2:mem:liquibasetest" + UUID.randomUUID()) .username("sa") .build(); } @@ -712,46 +632,6 @@ SpringLiquibase springLiquibase(DataSource dataSource) { } - @Configuration(proxyBeanMethods = false) - static class JpaWithMultipleDataSourcesConfiguration { - - @Bean - @Primary - DataSource normalDataSource() { - return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.HSQLDB.getType()) - .generateUniqueName(true) - .build(); - } - - @Bean - @Primary - LocalContainerEntityManagerFactoryBean normalEntityManagerFactory(EntityManagerFactoryBuilder builder, - DataSource normalDataSource) { - Map properties = new HashMap<>(); - properties.put("configured", "normal"); - properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); - return builder.dataSource(normalDataSource).properties(properties).build(); - } - - @Bean - @LiquibaseDataSource - DataSource liquibaseDataSource() { - return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.HSQLDB.getType()) - .generateUniqueName(true) - .build(); - } - - @Bean - LocalContainerEntityManagerFactoryBean liquibaseEntityManagerFactory(EntityManagerFactoryBuilder builder, - @LiquibaseDataSource DataSource liquibaseDataSource) { - Map properties = new HashMap<>(); - properties.put("configured", "liquibase"); - properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); - return builder.dataSource(liquibaseDataSource).properties(properties).build(); - } - - } - @Configuration(proxyBeanMethods = false) static class CustomDataSourceConfiguration { @@ -888,74 +768,4 @@ static class CustomH2Driver extends org.h2.Driver { } - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - @WithResource(name = "META-INF/persistence.xml", - content = """ - - - - org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfigurationTests$City - true - - - """) - @interface WithMetaInfPersistenceXmlResource { - - } - - @Entity - public static class City implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue - private Long id; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private String state; - - @Column(nullable = false) - private String country; - - @Column(nullable = false) - private String map; - - protected City() { - } - - City(String name, String state, String country, String map) { - this.name = name; - this.state = state; - this.country = country; - this.map = map; - } - - public String getName() { - return this.name; - } - - public String getState() { - return this.state; - } - - public String getCountry() { - return this.country; - } - - public String getMap() { - return this.map; - } - - @Override - public String toString() { - return getName() + "," + getState() + "," + getCountry(); - } - - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibasePropertiesTests.java b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/LiquibasePropertiesTests.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibasePropertiesTests.java rename to spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/LiquibasePropertiesTests.java index 29f552795cf8..5d7f7ed75bf9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibasePropertiesTests.java +++ b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/LiquibasePropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure; import java.util.List; import java.util.stream.Stream; @@ -24,9 +24,9 @@ import liquibase.ui.UIServiceEnum; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties.ShowSummary; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties.ShowSummaryOutput; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties.UiService; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseProperties.ShowSummary; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseProperties.ShowSummaryOutput; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseProperties.UiService; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/endpoint/LiquibaseEndpointAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointAutoConfigurationTests.java rename to spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/endpoint/LiquibaseEndpointAutoConfigurationTests.java index 6b54b34467d5..4205d627d777 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/liquibase/LiquibaseEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-liquibase/src/test/java/org/springframework/boot/liquibase/autoconfigure/endpoint/LiquibaseEndpointAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.liquibase; +package org.springframework.boot.liquibase.autoconfigure.endpoint; import liquibase.integration.spring.SpringLiquibase; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.liquibase.LiquibaseEndpoint; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.liquibase.DataSourceClosingSpringLiquibase; +import org.springframework.boot.liquibase.autoconfigure.DataSourceClosingSpringLiquibase; +import org.springframework.boot.liquibase.endpoint.LiquibaseEndpoint; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-mail/build.gradle b/spring-boot-project/spring-boot-mail/build.gradle new file mode 100644 index 000000000000..cfd8d94df3be --- /dev/null +++ b/spring-boot-project/spring-boot-mail/build.gradle @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Mail" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-context-support") + api("org.eclipse.angus:jakarta.mail") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-health")) + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation("org.testcontainers:testcontainers") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-mail/src/dockerTest/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfigurationIntegrationTests.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-mail/src/dockerTest/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfigurationIntegrationTests.java index 92288768f6dc..3424ce816a99 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-mail/src/dockerTest/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import java.net.SocketTimeoutException; import java.security.cert.CertPathBuilderException; @@ -95,9 +95,9 @@ class ImplicitTlsTests { private static final MailpitContainer mailpit = TestImage.container(MailpitContainer.class) .withSmtpRequireTls(true) .withSmtpTlsCert(MountableFile - .forClasspathResource("/org/springframework/boot/autoconfigure/mail/ssl/test-server.crt")) + .forClasspathResource("/org/springframework/boot/mail/autoconfigure/ssl/test-server.crt")) .withSmtpTlsKey(MountableFile - .forClasspathResource("/org/springframework/boot/autoconfigure/mail/ssl/test-server.key")) + .forClasspathResource("/org/springframework/boot/mail/autoconfigure/ssl/test-server.key")) .withPop3Auth("user:pass"); private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() @@ -108,9 +108,9 @@ void sendEmailWithSslEnabledAndCert() { this.contextRunner.withPropertyValues("spring.mail.host:" + mailpit.getHost(), "spring.mail.port:" + mailpit.getSmtpPort(), "spring.mail.ssl.enabled:true", "spring.mail.ssl.bundle:test-bundle", - "spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-ca.crt", - "spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.crt", - "spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.key", + "spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-ca.crt", + "spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-client.crt", + "spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-client.key", "spring.mail.properties.mail.pop3.host:" + mailpit.getHost(), "spring.mail.properties.mail.pop3.port:" + mailpit.getPop3Port()) .run((context) -> { @@ -137,9 +137,9 @@ void sendEmailWithoutSslWithCert() { this.contextRunner.withPropertyValues("spring.mail.host:" + mailpit.getHost(), "spring.mail.port:" + mailpit.getSmtpPort(), "spring.mail.properties.mail.smtp.timeout:1000", "spring.mail.ssl.bundle:test-bundle", - "spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-ca.crt", - "spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.crt", - "spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.key") + "spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-ca.crt", + "spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-client.crt", + "spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-client.key") .run((context) -> { JavaMailSenderImpl mailSender = context.getBean(JavaMailSenderImpl.class); assertThatException().isThrownBy(() -> mailSender.send(createMessage("Should fail"))) @@ -156,9 +156,9 @@ class StarttlsTests { private static final MailpitContainer mailpit = TestImage.container(MailpitContainer.class) .withSmtpRequireStarttls(true) .withSmtpTlsCert(MountableFile - .forClasspathResource("/org/springframework/boot/autoconfigure/mail/ssl/test-server.crt")) + .forClasspathResource("/org/springframework/boot/mail/autoconfigure/ssl/test-server.crt")) .withSmtpTlsKey(MountableFile - .forClasspathResource("/org/springframework/boot/autoconfigure/mail/ssl/test-server.key")) + .forClasspathResource("/org/springframework/boot/mail/autoconfigure/ssl/test-server.key")) .withPop3Auth("user:pass"); final ApplicationContextRunner contextRunner = new ApplicationContextRunner() @@ -170,9 +170,9 @@ void sendEmailWithStarttlsAndCertAndSslDisabled() { "spring.mail.port:" + mailpit.getSmtpPort(), "spring.mail.properties.mail.smtp.starttls.enable:true", "spring.mail.properties.mail.smtp.starttls.required:true", "spring.mail.ssl.bundle:test-bundle", - "spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-ca.crt", - "spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.crt", - "spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.key", + "spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-ca.crt", + "spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-client.crt", + "spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-client.key", "spring.mail.properties.mail.pop3.host:" + mailpit.getHost(), "spring.mail.properties.mail.pop3.port:" + mailpit.getPop3Port()) .run((context) -> { @@ -188,9 +188,9 @@ void sendEmailWithStarttlsAndCertAndSslEnabled() { "spring.mail.port:" + mailpit.getSmtpPort(), "spring.mail.ssl.enabled:true", "spring.mail.properties.mail.smtp.starttls.enable:true", "spring.mail.properties.mail.smtp.starttls.required:true", "spring.mail.ssl.bundle:test-bundle", - "spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-ca.crt", - "spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.crt", - "spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.key", + "spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-ca.crt", + "spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-client.crt", + "spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/mail/autoconfigure/ssl/test-client.key", "spring.mail.properties.mail.pop3.host:" + mailpit.getHost(), "spring.mail.properties.mail.pop3.port:" + mailpit.getPop3Port()) .run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-ca.crt b/spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-ca.crt similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-ca.crt rename to spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-ca.crt diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-ca.key b/spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-ca.key similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-ca.key rename to spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-ca.key diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-client.crt b/spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-client.crt similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-client.crt rename to spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-client.crt diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-client.key b/spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-client.key similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-client.key rename to spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-client.key diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-server.crt b/spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-server.crt similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-server.crt rename to spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-server.crt diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-server.key b/spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-server.key similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/resources/org/springframework/boot/autoconfigure/mail/ssl/test-server.key rename to spring-boot-project/spring-boot-mail/src/dockerTest/resources/org/springframework/boot/mail/autoconfigure/ssl/test-server.key diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mail/MailHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailHealthContributorAutoConfiguration.java similarity index 78% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mail/MailHealthContributorAutoConfiguration.java rename to spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailHealthContributorAutoConfiguration.java index d7f7d6c277c0..a9d98c9d4302 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mail/MailHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailHealthContributorAutoConfiguration.java @@ -14,19 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.mail.MailHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.mail.health.MailHealthIndicator; import org.springframework.context.annotation.Bean; import org.springframework.mail.javamail.JavaMailSenderImpl; @@ -34,10 +33,10 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link MailHealthIndicator}. * * @author Johannes Edmeier - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = MailSenderAutoConfiguration.class) -@ConditionalOnClass(JavaMailSenderImpl.class) +@ConditionalOnClass({ JavaMailSenderImpl.class, MailHealthIndicator.class, ConditionalOnEnabledHealthIndicator.class }) @ConditionalOnBean(JavaMailSenderImpl.class) @ConditionalOnEnabledHealthIndicator("mail") public class MailHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java rename to spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailProperties.java index caf9fd877d01..3d58af36ce75 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -29,7 +29,7 @@ * @author Oliver Gierke * @author Stephane Nicoll * @author Eddú Meléndez - * @since 1.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.mail") public class MailProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java rename to spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfiguration.java index b47734ce1b9f..1b468c1064ce 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfiguration.java +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import jakarta.activation.MimeType; import jakarta.mail.internet.MimeMessage; @@ -25,8 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration.MailSenderCondition; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.mail.autoconfigure.MailSenderAutoConfiguration.MailSenderCondition; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Import; import org.springframework.mail.MailSender; @@ -37,7 +37,7 @@ * @author Oliver Gierke * @author Stephane Nicoll * @author Eddú Meléndez - * @since 1.2.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ MimeMessage.class, MimeType.class, MailSender.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderJndiConfiguration.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderJndiConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderJndiConfiguration.java rename to spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderJndiConfiguration.java index 6ddda8276ba3..37e2871194b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderJndiConfiguration.java +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderJndiConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import javax.naming.NamingException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderPropertiesConfiguration.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderPropertiesConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderPropertiesConfiguration.java rename to spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderPropertiesConfiguration.java index e872fe8332e6..360d0e1b83c2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderPropertiesConfiguration.java +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderPropertiesConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import java.util.Map; import java.util.Properties; @@ -22,7 +22,7 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.mail.MailProperties.Ssl; +import org.springframework.boot.mail.autoconfigure.MailProperties.Ssl; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderValidatorAutoConfiguration.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderValidatorAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderValidatorAutoConfiguration.java rename to spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderValidatorAutoConfiguration.java index 1cca661f1cff..ed2e9e1e16b5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderValidatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/MailSenderValidatorAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import jakarta.mail.MessagingException; @@ -30,7 +30,7 @@ * * @author Eddú Meléndez * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ @AutoConfiguration(after = MailSenderAutoConfiguration.class) @ConditionalOnBooleanProperty("spring.mail.test-connection") diff --git a/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/package-info.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/package-info.java new file mode 100644 index 000000000000..7942cfc8232f --- /dev/null +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for email support. + */ +package org.springframework.boot.mail.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/health/MailHealthIndicator.java similarity index 81% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java rename to spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/health/MailHealthIndicator.java index 213f570a7215..113fdb09628d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/health/MailHealthIndicator.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.mail; +package org.springframework.boot.mail.health; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.util.StringUtils; @@ -27,7 +27,7 @@ * * @author Johannes Edmeier * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ public class MailHealthIndicator extends AbstractHealthIndicator { @@ -39,7 +39,7 @@ public MailHealthIndicator(JavaMailSenderImpl mailSender) { } @Override - protected void doHealthCheck(Builder builder) throws Exception { + protected void doHealthCheck(Health.Builder builder) throws Exception { String host = this.mailSender.getHost(); int port = this.mailSender.getPort(); StringBuilder location = new StringBuilder((host != null) ? host : ""); diff --git a/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/health/package-info.java b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/health/package-info.java new file mode 100644 index 000000000000..0a6a389998f7 --- /dev/null +++ b/spring-boot-project/spring-boot-mail/src/main/java/org/springframework/boot/mail/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for JavaMail. + */ +package org.springframework.boot.mail.health; diff --git a/spring-boot-project/spring-boot-mail/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-mail/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..1a0de547c5e9 --- /dev/null +++ b/spring-boot-project/spring-boot-mail/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,18 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.health.mail.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Mail health check.", + "defaultValue": true + }, + { + "name": "spring.mail.test-connection", + "description": "Whether to test that the mail server is available on startup.", + "sourceType": "org.springframework.boot.autoconfigure.mail.MailProperties", + "type": "java.lang.Boolean", + "defaultValue": false + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-mail/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-mail/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..e13a5286aaaa --- /dev/null +++ b/spring-boot-project/spring-boot-mail/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.mail.autoconfigure.MailHealthContributorAutoConfiguration +org.springframework.boot.mail.autoconfigure.MailSenderAutoConfiguration +org.springframework.boot.mail.autoconfigure.MailSenderValidatorAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mail/MailHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/autoconfigure/MailHealthContributorAutoConfigurationTests.java similarity index 84% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mail/MailHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/autoconfigure/MailHealthContributorAutoConfigurationTests.java index 9b611ff4f706..8be346751661 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mail/MailHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/autoconfigure/MailHealthContributorAutoConfigurationTests.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.mail.MailHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.mail.health.MailHealthIndicator; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java b/spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java rename to spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfigurationTests.java index b2ae3f3647b6..7b44e26a7e80 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mail/MailSenderAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/autoconfigure/MailSenderAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mail; +package org.springframework.boot.mail.autoconfigure; import java.util.Properties; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mail/MailHealthIndicatorTests.java b/spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/health/MailHealthIndicatorTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mail/MailHealthIndicatorTests.java rename to spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/health/MailHealthIndicatorTests.java index 5190c85c9cfb..3f6320efaf07 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mail/MailHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-mail/src/test/java/org/springframework/boot/mail/health/MailHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.mail; +package org.springframework.boot.mail.health; import java.util.Properties; @@ -29,8 +29,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import org.springframework.mail.javamail.JavaMailSenderImpl; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mail/test.jks b/spring-boot-project/spring-boot-mail/src/test/resources/org/springframework/boot/mail/autoconfigure/test.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mail/test.jks rename to spring-boot-project/spring-boot-mail/src/test/resources/org/springframework/boot/mail/autoconfigure/test.jks diff --git a/spring-boot-project/spring-boot-metrics/build.gradle b/spring-boot-project/spring-boot-metrics/build.gradle new file mode 100644 index 000000000000..1a704459d120 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/build.gradle @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "java-test-fixtures" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Metrics" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-observation")) + api("io.micrometer:micrometer-core") + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-opentelemetry")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("ch.qos.logback:logback-classic") + optional("io.micrometer:micrometer-java21") + optional("io.micrometer:micrometer-registry-appoptics") + optional("io.micrometer:micrometer-registry-atlas") { + exclude group: "javax.inject", module: "javax.inject" + } + optional("io.micrometer:micrometer-registry-datadog") + optional("io.micrometer:micrometer-registry-dynatrace") + optional("io.micrometer:micrometer-registry-elastic") + optional("io.micrometer:micrometer-registry-ganglia") + optional("io.micrometer:micrometer-registry-graphite") + optional("io.micrometer:micrometer-registry-humio") + optional("io.micrometer:micrometer-registry-influx") + optional("io.micrometer:micrometer-registry-jmx") + optional("io.micrometer:micrometer-registry-kairos") + optional("io.micrometer:micrometer-registry-new-relic") + optional("io.micrometer:micrometer-registry-otlp") + optional("io.micrometer:micrometer-registry-prometheus") + optional("io.micrometer:micrometer-registry-stackdriver") { + exclude group: "javax.annotation", module: "javax.annotation-api" + } + optional("io.micrometer:micrometer-registry-statsd") + optional("io.prometheus:prometheus-metrics-exporter-pushgateway") + optional("org.apache.kafka:kafka-streams") + optional("org.apache.logging.log4j:log4j-core") + optional("org.aspectj:aspectjweaver") + optional("org.testcontainers:grafana") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("io.rest-assured:rest-assured") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testFixturesImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("io.micrometer:micrometer-registry-atlas") + testImplementation("io.micrometer:micrometer-registry-new-relic") + testImplementation("io.micrometer:micrometer-registry-prometheus") + testImplementation("org.apache.logging.log4j:log4j-to-slf4j") + testImplementation("org.springframework:spring-webflux") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/docker/compose/otlp/GrafanaOpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 88% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/docker/compose/otlp/GrafanaOpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java index c219aae73e3c..d1bc5d89434b 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/docker/compose/otlp/GrafanaOpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.metrics.docker.compose.otlp; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/docker/compose/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 88% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/docker/compose/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java index d0a006ce540d..341033b68cf7 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/docker/compose/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.metrics.docker.compose.otlp; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/testcontainers/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java similarity index 96% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/testcontainers/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java index 62d8672303e1..9a604adab46d 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/testcontainers/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.metrics.testcontainers.otlp; import java.time.Duration; @@ -33,8 +33,8 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/testcontainers/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java similarity index 96% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/testcontainers/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java index dd4d66748ebf..2bd316201dbc 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/dockerTest/java/org/springframework/boot/metrics/testcontainers/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.metrics.testcontainers.otlp; import java.time.Duration; @@ -34,8 +34,8 @@ import org.testcontainers.utility.MountableFile; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/resources/collector-config.yml b/spring-boot-project/spring-boot-metrics/src/dockerTest/resources/collector-config.yml similarity index 100% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/resources/collector-config.yml rename to spring-boot-project/spring-boot-metrics/src/dockerTest/resources/collector-config.yml diff --git a/spring-boot-project/spring-boot-metrics/src/dockerTest/resources/org/springframework/boot/metrics/docker/compose/otlp/otlp-compose.yaml b/spring-boot-project/spring-boot-metrics/src/dockerTest/resources/org/springframework/boot/metrics/docker/compose/otlp/otlp-compose.yaml new file mode 100644 index 000000000000..86e05475417d --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/dockerTest/resources/org/springframework/boot/metrics/docker/compose/otlp/otlp-compose.yaml @@ -0,0 +1,6 @@ +services: + otlp: + image: '{imageName}' + ports: + - '4317' + - '4318' diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/OnlyOnceLoggingDenyMeterFilter.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/OnlyOnceLoggingDenyMeterFilter.java index d7d2b3881f45..d406fe993147 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/OnlyOnceLoggingDenyMeterFilter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/OnlyOnceLoggingDenyMeterFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -32,7 +32,7 @@ * * @author Jon Schneider * @author Dmytro Nosan - * @since 2.0.5 + * @since 4.0.0 */ public final class OnlyOnceLoggingDenyMeterFilter implements MeterFilter { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/ValidationFailureAnalyzer.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/ValidationFailureAnalyzer.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/ValidationFailureAnalyzer.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/ValidationFailureAnalyzer.java index 3ac4e1d2617a..3ac867fd8516 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/ValidationFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/ValidationFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics; import io.micrometer.core.instrument.config.validate.Validated.Invalid; import io.micrometer.core.instrument.config.validate.ValidationException; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/MetricsEndpoint.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/actuate/endpoint/MetricsEndpoint.java similarity index 99% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/MetricsEndpoint.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/actuate/endpoint/MetricsEndpoint.java index dd3391dcacf2..4f5c4cbf5e89 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/MetricsEndpoint.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/actuate/endpoint/MetricsEndpoint.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics; +package org.springframework.boot.metrics.actuate.endpoint; import java.util.Collection; import java.util.Collections; @@ -45,7 +45,7 @@ * * @author Jon Schneider * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ @Endpoint(id = "metrics") public class MetricsEndpoint { diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/actuate/endpoint/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/actuate/endpoint/package-info.java new file mode 100644 index 000000000000..6c6fc2548959 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/actuate/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator endpoint for metrics. + */ +package org.springframework.boot.metrics.actuate.endpoint; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/AutoConfiguredCompositeMeterRegistry.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/AutoConfiguredCompositeMeterRegistry.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/AutoConfiguredCompositeMeterRegistry.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/AutoConfiguredCompositeMeterRegistry.java index c5d9d01fb3ab..e24693724ba6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/AutoConfiguredCompositeMeterRegistry.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/AutoConfiguredCompositeMeterRegistry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryAutoConfiguration.java index 25add070eab4..c6f76b30fe41 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; @@ -28,7 +28,7 @@ * {@link CompositeMeterRegistry}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration @Import({ NoOpMeterRegistryConfiguration.class, CompositeMeterRegistryConfiguration.class }) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryConfiguration.java index 2efbecf21d7b..425fea4d833a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.util.List; @@ -22,10 +22,10 @@ import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryConfiguration.MultipleNonPrimaryMeterRegistriesCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryConfiguration.MultipleNonPrimaryMeterRegistriesCondition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryCustomizer.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryCustomizer.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryCustomizer.java index f2ac877b8d3c..b8e563e25fe8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryCustomizer.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; @@ -28,7 +28,7 @@ * * @param the registry type to customize * @author Jon Schneider - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface MeterRegistryCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryPostProcessor.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryPostProcessor.java index 450a2850166c..7f8adcbf09d9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.util.LinkedHashSet; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterValue.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterValue.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterValue.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterValue.java index 4f31eeec70ab..b3b1b3a8b22a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterValue.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MeterValue.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -30,7 +30,7 @@ * * @author Phillip Webb * @author Stephane Nicoll - * @since 2.2.0 + * @since 4.0.0 */ public final class MeterValue { @@ -97,7 +97,6 @@ public static MeterValue valueOf(String value) { * Return a new {@link MeterValue} instance for the given double value. * @param value the source value * @return a {@link MeterValue} instance - * @since 2.3.0 */ public static MeterValue valueOf(double value) { return new MeterValue(value); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsAspectsAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsAspectsAutoConfiguration.java index ff94831b5505..245f4e4fb184 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsAspectsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import io.micrometer.core.aop.CountedAspect; import io.micrometer.core.aop.MeterTagAnnotationHandler; @@ -36,7 +36,7 @@ * aspects. * * @author Jonatan Ivanov - * @since 3.2.0 + * @since 4.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) @ConditionalOnClass({ MeterRegistry.class, Advice.class }) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfiguration.java similarity index 76% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfiguration.java index f87fa02e16a5..0c0fb5a5ff07 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.util.List; @@ -22,7 +22,11 @@ import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.composite.CompositeMeterRegistry; import io.micrometer.core.instrument.config.MeterFilter; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler.IgnoredMeters; +import io.micrometer.core.instrument.observation.MeterObservationHandler; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -30,6 +34,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.observation.autoconfigure.ObservationHandlerGroup; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; @@ -42,7 +47,8 @@ * @author Jon Schneider * @author Stephane Nicoll * @author Moritz Halbritter - * @since 2.0.0 + * @author Phillip Webb + * @since 4.0.0 */ @AutoConfiguration(before = CompositeMeterRegistryAutoConfiguration.class) @ConditionalOnClass(Timed.class) @@ -75,6 +81,19 @@ MeterRegistryCloser meterRegistryCloser(ObjectProvider meterRegis return new MeterRegistryCloser(meterRegistries.orderedStream().toList()); } + @Bean + ObservationHandlerGroup metricsObservationHandlerGroup() { + return ObservationHandlerGroup.of(MeterObservationHandler.class); + } + + @Bean + DefaultMeterObservationHandler defaultMeterObservationHandler(ObjectProvider meterRegistryProvider, + Clock clock, MetricsProperties properties) { + MeterRegistry meterRegistry = meterRegistryProvider.getIfAvailable(() -> new CompositeMeterRegistry(clock)); + return new DefaultMeterObservationHandler(meterRegistry, + properties.getObservations().getIgnoredMeters().toArray(IgnoredMeters[]::new)); + } + /** * Ensures that {@link MeterRegistry meter registries} are closed early in the * shutdown process. diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsEndpointAutoConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsEndpointAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsEndpointAutoConfiguration.java index 84c5734eed1d..be15a4c74017 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsEndpointAutoConfiguration.java @@ -14,28 +14,28 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import io.micrometer.core.annotation.Timed; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.metrics.MetricsEndpoint; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.metrics.actuate.endpoint.MetricsEndpoint; import org.springframework.context.annotation.Bean; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link MetricsEndpoint}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) -@ConditionalOnClass(Timed.class) +@ConditionalOnClass({ ConditionalOnAvailableEndpoint.class, Timed.class }) @ConditionalOnAvailableEndpoint(MetricsEndpoint.class) public class MetricsEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsProperties.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsProperties.java index 1b7b494552c4..a1bf8dd816c4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/MetricsProperties.java @@ -14,18 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.io.File; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; + +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler.IgnoredMeters; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.NestedConfigurationProperty; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring @@ -35,7 +38,7 @@ * @author Alexander Abramov * @author Tadaya Tsuyukubo * @author Chris Bono - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.metrics") public class MetricsProperties { @@ -60,12 +63,12 @@ public class MetricsProperties { private final Web web = new Web(); - private final Data data = new Data(); - private final System system = new System(); private final Distribution distribution = new Distribution(); + private final Observations observations = new Observations(); + public boolean isUseGlobalRegistry() { return this.useGlobalRegistry; } @@ -86,10 +89,6 @@ public Web getWeb() { return this.web; } - public Data getData() { - return this.data; - } - public System getSystem() { return this.system; } @@ -98,6 +97,10 @@ public Distribution getDistribution() { return this.distribution; } + public Observations getObservations() { + return this.observations; + } + public static class Web { private final Client client = new Client(); @@ -152,43 +155,6 @@ public void setMaxUriTags(int maxUriTags) { } - public static class Data { - - private final Repository repository = new Repository(); - - public Repository getRepository() { - return this.repository; - } - - public static class Repository { - - /** - * Name of the metric for sent requests. - */ - private String metricName = "spring.data.repository.invocations"; - - /** - * Auto-timed request settings. - */ - @NestedConfigurationProperty - private final AutoTimeProperties autotime = new AutoTimeProperties(); - - public String getMetricName() { - return this.metricName; - } - - public void setMetricName(String metricName) { - this.metricName = metricName; - } - - public AutoTimeProperties getAutotime() { - return this.autotime; - } - - } - - } - public static class System { private final Diskspace diskspace = new Diskspace(); @@ -301,4 +267,21 @@ public Map getBufferLength() { } + public static class Observations { + + /** + * Meters that should be ignored when recoding observations. + */ + private Set ignoredMeters = new LinkedHashSet<>(); + + public Set getIgnoredMeters() { + return this.ignoredMeters; + } + + public void setIgnoredMeters(Set ignoredMeters) { + this.ignoredMeters = ignoredMeters; + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/NoOpMeterRegistryConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/NoOpMeterRegistryConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/NoOpMeterRegistryConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/NoOpMeterRegistryConfiguration.java index 71dc09b89a10..139db2129498 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/NoOpMeterRegistryConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/NoOpMeterRegistryConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.MeterRegistry; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/PropertiesMeterFilter.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/PropertiesMeterFilter.java index 085d3af48e1d..f73274c849eb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/PropertiesMeterFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.util.Arrays; import java.util.Map; @@ -30,7 +30,7 @@ import io.micrometer.core.instrument.config.MeterFilterReply; import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Distribution; +import org.springframework.boot.metrics.autoconfigure.MetricsProperties.Distribution; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -42,7 +42,7 @@ * @author Stephane Nicoll * @author Artsiom Yudovin * @author Alexander Abramov - * @since 2.0.0 + * @since 4.0.0 */ public class PropertiesMeterFilter implements MeterFilter { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/ServiceLevelObjectiveBoundary.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ServiceLevelObjectiveBoundary.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/ServiceLevelObjectiveBoundary.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ServiceLevelObjectiveBoundary.java index 66063a758d43..c20cc13b3937 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/ServiceLevelObjectiveBoundary.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ServiceLevelObjectiveBoundary.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.time.Duration; @@ -31,7 +31,7 @@ * * @author Phillip Webb * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ public final class ServiceLevelObjectiveBoundary { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ConditionalOnEnabledMetricsExport.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ConditionalOnEnabledMetricsExport.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ConditionalOnEnabledMetricsExport.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ConditionalOnEnabledMetricsExport.java index d74088da3e10..38f3235ebfdd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ConditionalOnEnabledMetricsExport.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ConditionalOnEnabledMetricsExport.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export; +package org.springframework.boot.metrics.autoconfigure.export; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,7 +32,7 @@ * not configured. * * @author Chris Bono - * @since 2.4.0 + * @since 4.0.0 */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/OnMetricsExportEnabledCondition.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/OnMetricsExportEnabledCondition.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/OnMetricsExportEnabledCondition.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/OnMetricsExportEnabledCondition.java index 6d62650ce447..ed0b7d163c00 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/OnMetricsExportEnabledCondition.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/OnMetricsExportEnabledCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export; +package org.springframework.boot.metrics.autoconfigure.export; import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsMetricsExportAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsMetricsExportAutoConfiguration.java index 7441f84362b7..d8b082f909f2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsMetricsExportAutoConfiguration.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics; +package org.springframework.boot.metrics.autoconfigure.export.appoptics; import io.micrometer.appoptics.AppOpticsConfig; import io.micrometer.appoptics.AppOpticsMeterRegistry; import io.micrometer.core.instrument.Clock; import io.micrometer.core.ipc.http.HttpUrlConnectionSender; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -38,7 +38,7 @@ * * @author Stephane Nicoll * @author Artsiom Yudovin - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsProperties.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsProperties.java index ce1efb461a67..fc26dc86c905 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsProperties.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics; +package org.springframework.boot.metrics.autoconfigure.export.appoptics; import java.time.Duration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring AppOptics * metrics export. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @ConfigurationProperties("management.appoptics.metrics.export") public class AppOpticsProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesConfigAdapter.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesConfigAdapter.java index 0965e7e46e1d..7747862382b0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesConfigAdapter.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics; +package org.springframework.boot.metrics.autoconfigure.export.appoptics; import io.micrometer.appoptics.AppOpticsConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link AppOpticsProperties} to an {@link AppOpticsConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/package-info.java new file mode 100644 index 000000000000..a39f5f96792e --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to AppOptics. + */ +package org.springframework.boot.metrics.autoconfigure.export.appoptics; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasMetricsExportAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasMetricsExportAutoConfiguration.java index ad9e488285a1..a68eeb6483d4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasMetricsExportAutoConfiguration.java @@ -14,22 +14,22 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas; +package org.springframework.boot.metrics.autoconfigure.export.atlas; import com.netflix.spectator.atlas.AtlasConfig; import io.micrometer.atlas.AtlasMeterRegistry; import io.micrometer.core.instrument.Clock; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -37,7 +37,7 @@ * * @author Jon Schneider * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasProperties.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasProperties.java index 397b39e2d363..2860aa135451 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas; +package org.springframework.boot.metrics.autoconfigure.export.atlas; import java.time.Duration; @@ -26,7 +26,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.atlas.metrics.export") public class AtlasProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesConfigAdapter.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesConfigAdapter.java index ccdbc49ee56b..c4abbbf8f2b2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesConfigAdapter.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas; +package org.springframework.boot.metrics.autoconfigure.export.atlas; import java.time.Duration; import com.netflix.spectator.atlas.AtlasConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; /** * Adapter to convert {@link AtlasProperties} to an {@link AtlasConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/package-info.java new file mode 100644 index 000000000000..aaaf0538cc35 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/atlas/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Atlas. + */ +package org.springframework.boot.metrics.autoconfigure.export.atlas; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogMetricsExportAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogMetricsExportAutoConfiguration.java index f5ee296ec863..a8a4ffc5c470 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogMetricsExportAutoConfiguration.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog; +package org.springframework.boot.metrics.autoconfigure.export.datadog; import io.micrometer.core.instrument.Clock; import io.micrometer.core.ipc.http.HttpUrlConnectionSender; import io.micrometer.datadog.DatadogConfig; import io.micrometer.datadog.DatadogMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -38,7 +38,7 @@ * * @author Jon Schneider * @author Artsiom Yudovin - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogProperties.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogProperties.java index 863523e612c3..e5dfa7a3cfef 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogProperties.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog; +package org.springframework.boot.metrics.autoconfigure.export.datadog; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring Datadog @@ -25,7 +25,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.datadog.metrics.export") public class DatadogProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesConfigAdapter.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesConfigAdapter.java index 1de3dba9fd3f..10c9bc2f5721 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesConfigAdapter.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog; +package org.springframework.boot.metrics.autoconfigure.export.datadog; import io.micrometer.datadog.DatadogConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link DatadogProperties} to a {@link DatadogConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/package-info.java new file mode 100644 index 000000000000..e63eef3d4bd4 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/datadog/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Datadog. + */ +package org.springframework.boot.metrics.autoconfigure.export.datadog; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceMetricsExportAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceMetricsExportAutoConfiguration.java index bc462b280bf9..75ff2fbc072e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceMetricsExportAutoConfiguration.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace; +package org.springframework.boot.metrics.autoconfigure.export.dynatrace; import io.micrometer.core.instrument.Clock; import io.micrometer.core.ipc.http.HttpUrlConnectionSender; import io.micrometer.dynatrace.DynatraceConfig; import io.micrometer.dynatrace.DynatraceMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -38,7 +38,7 @@ * * @author Andy Wilkinson * @author Artsiom Yudovin - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceProperties.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceProperties.java index f70f19d293b5..4af58d6b18b4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceProperties.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace; +package org.springframework.boot.metrics.autoconfigure.export.dynatrace; import java.util.Map; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring Dynatrace @@ -27,7 +27,7 @@ * * @author Andy Wilkinson * @author Georg Pirklbauer - * @since 2.1.0 + * @since 4.0.0 */ @ConfigurationProperties("management.dynatrace.metrics.export") public class DynatraceProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesConfigAdapter.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesConfigAdapter.java index 0eaf1dc782ee..d2f2e158d455 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace; +package org.springframework.boot.metrics.autoconfigure.export.dynatrace; import java.util.Map; import java.util.function.Function; @@ -22,9 +22,9 @@ import io.micrometer.dynatrace.DynatraceApiVersion; import io.micrometer.dynatrace.DynatraceConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace.DynatraceProperties.V1; -import org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace.DynatraceProperties.V2; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.dynatrace.DynatraceProperties.V1; +import org.springframework.boot.metrics.autoconfigure.export.dynatrace.DynatraceProperties.V2; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link DynatraceProperties} to a {@link DynatraceConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/package-info.java new file mode 100644 index 000000000000..07271af2c013 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Dynatrace. + */ +package org.springframework.boot.metrics.autoconfigure.export.dynatrace; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticMetricsExportAutoConfiguration.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticMetricsExportAutoConfiguration.java index bc7114dd6a25..6069089869bb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticMetricsExportAutoConfiguration.java @@ -14,17 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.elastic; +package org.springframework.boot.metrics.autoconfigure.export.elastic; import io.micrometer.core.instrument.Clock; import io.micrometer.core.ipc.http.HttpUrlConnectionSender; import io.micrometer.elastic.ElasticConfig; import io.micrometer.elastic.ElasticMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -32,6 +28,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -39,7 +39,7 @@ * * @author Andy Wilkinson * @author Artsiom Yudovin - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticProperties.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticProperties.java index 17175f80dfa1..4b69f3f1a166 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticProperties.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.elastic; +package org.springframework.boot.metrics.autoconfigure.export.elastic; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring Elastic * metrics export. * * @author Andy Wilkinson - * @since 2.1.0 + * @since 4.0.0 */ @ConfigurationProperties("management.elastic.metrics.export") public class ElasticProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesConfigAdapter.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesConfigAdapter.java index 401481a8b9d8..b9ddb7325b6e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesConfigAdapter.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.elastic; +package org.springframework.boot.metrics.autoconfigure.export.elastic; import io.micrometer.elastic.ElasticConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link ElasticProperties} to an {@link ElasticConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/package-info.java new file mode 100644 index 000000000000..2be15cab52fe --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/elastic/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Elastic. + */ +package org.springframework.boot.metrics.autoconfigure.export.elastic; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaMetricsExportAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaMetricsExportAutoConfiguration.java index 790305d5eb44..5609dee12ec6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaMetricsExportAutoConfiguration.java @@ -14,29 +14,29 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia; +package org.springframework.boot.metrics.autoconfigure.export.ganglia; import io.micrometer.core.instrument.Clock; import io.micrometer.ganglia.GangliaConfig; import io.micrometer.ganglia.GangliaMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Ganglia. * * @author Jon Schneider - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaProperties.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaProperties.java index a44e83ceabfc..cc82f352b6c1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia; +package org.springframework.boot.metrics.autoconfigure.export.ganglia; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -29,7 +29,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.ganglia.metrics.export") public class GangliaProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesConfigAdapter.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesConfigAdapter.java index 78e5d08867df..eacb7efc2a44 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia; +package org.springframework.boot.metrics.autoconfigure.export.ganglia; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -22,7 +22,7 @@ import info.ganglia.gmetric4j.gmetric.GMetric; import io.micrometer.ganglia.GangliaConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; /** * Adapter to convert {@link GangliaProperties} to a {@link GangliaConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/package-info.java new file mode 100644 index 000000000000..bd9aa9cde8ca --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Ganglia. + */ +package org.springframework.boot.metrics.autoconfigure.export.ganglia; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteMetricsExportAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteMetricsExportAutoConfiguration.java index 736716b28f5b..371a3af3891d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteMetricsExportAutoConfiguration.java @@ -14,29 +14,29 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.graphite; +package org.springframework.boot.metrics.autoconfigure.export.graphite; import io.micrometer.core.instrument.Clock; import io.micrometer.graphite.GraphiteConfig; import io.micrometer.graphite.GraphiteMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Graphite. * * @author Jon Schneider - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteProperties.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteProperties.java index 77dbfff2a01d..27601e2b1c90 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.graphite; +package org.springframework.boot.metrics.autoconfigure.export.graphite; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -30,7 +30,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.graphite.metrics.export") public class GraphiteProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesConfigAdapter.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesConfigAdapter.java index 78f4aca4cb43..307f21a353b9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.graphite; +package org.springframework.boot.metrics.autoconfigure.export.graphite; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -22,7 +22,7 @@ import io.micrometer.graphite.GraphiteConfig; import io.micrometer.graphite.GraphiteProtocol; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; /** * Adapter to convert {@link GraphiteProperties} to a {@link GraphiteConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/package-info.java new file mode 100644 index 000000000000..b03d20f09d21 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/graphite/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Graphite. + */ +package org.springframework.boot.metrics.autoconfigure.export.graphite; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioMetricsExportAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioMetricsExportAutoConfiguration.java index c316192df3f4..a5832130a5eb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioMetricsExportAutoConfiguration.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; +package org.springframework.boot.metrics.autoconfigure.export.humio; import io.micrometer.core.instrument.Clock; import io.micrometer.core.ipc.http.HttpUrlConnectionSender; import io.micrometer.humio.HumioConfig; import io.micrometer.humio.HumioMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -38,7 +38,7 @@ * * @author Andy Wilkinson * @author Artsiom Yudovin - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioProperties.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioProperties.java index 66ea08126d3f..383f9c71d767 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioProperties.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; +package org.springframework.boot.metrics.autoconfigure.export.humio; import java.time.Duration; import java.util.HashMap; import java.util.Map; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring Humio metrics * export. * * @author Andy Wilkinson - * @since 2.1.0 + * @since 4.0.0 */ @ConfigurationProperties("management.humio.metrics.export") public class HumioProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesConfigAdapter.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesConfigAdapter.java index db24c1cbd7b0..45fc13cfc69e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesConfigAdapter.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; +package org.springframework.boot.metrics.autoconfigure.export.humio; import java.util.Map; import io.micrometer.humio.HumioConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link HumioProperties} to a {@link HumioConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/package-info.java new file mode 100644 index 000000000000..5f99ca898351 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/humio/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Humio. + */ +package org.springframework.boot.metrics.autoconfigure.export.humio; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxMetricsExportAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxMetricsExportAutoConfiguration.java index 7b5e63d971bf..71a82c7b15e6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxMetricsExportAutoConfiguration.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.influx; +package org.springframework.boot.metrics.autoconfigure.export.influx; import io.micrometer.core.instrument.Clock; import io.micrometer.core.ipc.http.HttpUrlConnectionSender; import io.micrometer.influx.InfluxConfig; import io.micrometer.influx.InfluxMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -38,7 +38,7 @@ * * @author Jon Schneider * @author Artsiom Yudovin - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxProperties.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxProperties.java index e0f745acc60c..2e4674fdeb0e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxProperties.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.influx; +package org.springframework.boot.metrics.autoconfigure.export.influx; import io.micrometer.influx.InfluxApiVersion; import io.micrometer.influx.InfluxConsistency; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring Influx metrics @@ -28,7 +28,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.influx.metrics.export") public class InfluxProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesConfigAdapter.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesConfigAdapter.java index 41f0c89c9174..f454d6c6cbfa 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesConfigAdapter.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.influx; +package org.springframework.boot.metrics.autoconfigure.export.influx; import io.micrometer.influx.InfluxApiVersion; import io.micrometer.influx.InfluxConfig; import io.micrometer.influx.InfluxConsistency; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link InfluxProperties} to an {@link InfluxConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/package-info.java new file mode 100644 index 000000000000..93d39e12c499 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/influx/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to InfluxDB. + */ +package org.springframework.boot.metrics.autoconfigure.export.influx; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxMetricsExportAutoConfiguration.java similarity index 80% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxMetricsExportAutoConfiguration.java index 895cb5cde9b8..a60c731bb406 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxMetricsExportAutoConfiguration.java @@ -14,29 +14,29 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.jmx; +package org.springframework.boot.metrics.autoconfigure.export.jmx; import io.micrometer.core.instrument.Clock; import io.micrometer.jmx.JmxConfig; import io.micrometer.jmx.JmxMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to JMX. * * @author Jon Schneider - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxProperties.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxProperties.java index e05c775c7083..b5c1573c0f27 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.jmx; +package org.springframework.boot.metrics.autoconfigure.export.jmx; import java.time.Duration; @@ -26,7 +26,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.jmx.metrics.export") public class JmxProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesConfigAdapter.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesConfigAdapter.java index 76dea2dd29ab..3f1512f149c6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesConfigAdapter.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.jmx; +package org.springframework.boot.metrics.autoconfigure.export.jmx; import java.time.Duration; import io.micrometer.jmx.JmxConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; /** * Adapter to convert {@link JmxProperties} to a {@link JmxConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/package-info.java new file mode 100644 index 000000000000..893d76f1713b --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/jmx/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to JMX. + */ +package org.springframework.boot.metrics.autoconfigure.export.jmx; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosMetricsExportAutoConfiguration.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosMetricsExportAutoConfiguration.java index cb6c6a8b1500..3891af334fa7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosMetricsExportAutoConfiguration.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.kairos; +package org.springframework.boot.metrics.autoconfigure.export.kairos; import io.micrometer.core.instrument.Clock; import io.micrometer.core.ipc.http.HttpUrlConnectionSender; import io.micrometer.kairos.KairosConfig; import io.micrometer.kairos.KairosMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -38,7 +38,7 @@ * * @author Stephane Nicoll * @author Artsiom Yudovin - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosProperties.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosProperties.java index eec38689b69c..32bfd278f7af 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosProperties.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.kairos; +package org.springframework.boot.metrics.autoconfigure.export.kairos; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring KairosDB * metrics export. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @ConfigurationProperties("management.kairos.metrics.export") public class KairosProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesConfigAdapter.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesConfigAdapter.java index e875e019982f..877086a60242 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesConfigAdapter.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.kairos; +package org.springframework.boot.metrics.autoconfigure.export.kairos; import io.micrometer.kairos.KairosConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link KairosProperties} to a {@link KairosConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/package-info.java new file mode 100644 index 000000000000..18c97d8fc087 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/kairos/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to KairosDB. + */ +package org.springframework.boot.metrics.autoconfigure.export.kairos; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicMetricsExportAutoConfiguration.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicMetricsExportAutoConfiguration.java index a05a8b0b0f44..ef706f0f58d1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicMetricsExportAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic; +package org.springframework.boot.metrics.autoconfigure.export.newrelic; import io.micrometer.core.instrument.Clock; import io.micrometer.core.ipc.http.HttpUrlConnectionSender; @@ -25,16 +25,16 @@ import io.micrometer.newrelic.NewRelicInsightsApiClientProvider; import io.micrometer.newrelic.NewRelicMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -43,7 +43,7 @@ * @author Jon Schneider * @author Andy Wilkinson * @author Artsiom Yudovin - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicProperties.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicProperties.java index d239131db2ab..7da7a35fd406 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicProperties.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic; +package org.springframework.boot.metrics.autoconfigure.export.newrelic; import io.micrometer.newrelic.ClientProviderType; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring New Relic @@ -29,7 +29,7 @@ * @author Andy Wilkinson * @author Stephane Nicoll * @author Neil Powell - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.newrelic.metrics.export") public class NewRelicProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesConfigAdapter.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesConfigAdapter.java index 7bc6c55af0d0..53076aef3129 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesConfigAdapter.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic; +package org.springframework.boot.metrics.autoconfigure.export.newrelic; import io.micrometer.newrelic.ClientProviderType; import io.micrometer.newrelic.NewRelicConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link NewRelicProperties} to a {@link NewRelicConfig}. * * @author Jon Schneider * @author Neil Powell - * @since 2.0.0 + * @since 4.0.0 */ public class NewRelicPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter implements NewRelicConfig { diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/package-info.java new file mode 100644 index 000000000000..1d2e9d194634 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to New Relic. + */ +package org.springframework.boot.metrics.autoconfigure.export.newrelic; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsConnectionDetails.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsConnectionDetails.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsConnectionDetails.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsConnectionDetails.java index ebe8b2076bee..430680f247a0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsConnectionDetails.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp; +package org.springframework.boot.metrics.autoconfigure.export.otlp; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; @@ -22,7 +22,7 @@ * Details required to establish a connection to an OpenTelemetry Collector service. * * @author Eddú Meléndez - * @since 3.2.0 + * @since 4.0.0 */ public interface OtlpMetricsConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsExportAutoConfiguration.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsExportAutoConfiguration.java index 7961c834cd8e..cf071ecb97ea 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsExportAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp; +package org.springframework.boot.metrics.autoconfigure.export.otlp; import io.micrometer.core.instrument.Clock; import io.micrometer.registry.otlp.OtlpConfig; @@ -22,11 +22,6 @@ import io.micrometer.registry.otlp.OtlpMetricsSender; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -35,6 +30,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; import org.springframework.boot.autoconfigure.thread.Threading; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetryProperties; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.core.task.VirtualThreadTaskExecutor; @@ -44,7 +44,7 @@ * * @author Eddú Meléndez * @author Moritz Halbritter - * @since 3.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsProperties.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsProperties.java index c4f8187c449f..934fa1c3f1cd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp; +package org.springframework.boot.metrics.autoconfigure.export.otlp; import java.util.LinkedHashMap; import java.util.Map; @@ -23,8 +23,8 @@ import io.micrometer.registry.otlp.AggregationTemporality; import io.micrometer.registry.otlp.HistogramFlavor; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring OTLP metrics @@ -32,7 +32,7 @@ * * @author Eddú Meléndez * @author Jonatan Ivanov - * @since 3.4.0 + * @since 4.0.0 */ @ConfigurationProperties("management.otlp.metrics.export") public class OtlpMetricsProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesConfigAdapter.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesConfigAdapter.java index ee3db136ddd5..714cb5438dd5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp; +package org.springframework.boot.metrics.autoconfigure.export.otlp; import java.util.Collections; import java.util.LinkedHashMap; @@ -26,10 +26,10 @@ import io.micrometer.registry.otlp.HistogramFlavor; import io.micrometer.registry.otlp.OtlpConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsProperties.Meter; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; -import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryProperties; -import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryResourceAttributes; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsProperties.Meter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetryProperties; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetryResourceAttributes; import org.springframework.core.env.Environment; import org.springframework.util.CollectionUtils; diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/package-info.java new file mode 100644 index 000000000000..3276ce9b8d34 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/otlp/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to OTLP. + */ +package org.springframework.boot.metrics.autoconfigure.export.otlp; diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/package-info.java new file mode 100644 index 000000000000..1e80775cb000 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for metrics exporter. + */ +package org.springframework.boot.metrics.autoconfigure.export; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusMetricsExportAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusMetricsExportAutoConfiguration.java index d3d981bd94d4..02e2c4d8b844 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusMetricsExportAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; +package org.springframework.boot.metrics.autoconfigure.export.prometheus; import io.micrometer.core.instrument.Clock; import io.micrometer.prometheusmetrics.PrometheusConfig; @@ -28,10 +28,6 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager; import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -42,6 +38,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -53,7 +53,7 @@ * @author Jon Schneider * @author David J. M. Karlsen * @author Jonatan Ivanov - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusProperties.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusProperties.java index 422fc26f5870..5bb698bc3d2e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; +package org.springframework.boot.metrics.autoconfigure.export.prometheus; import java.time.Duration; import java.util.HashMap; @@ -29,7 +29,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.prometheus.metrics.export") public class PrometheusProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesConfigAdapter.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesConfigAdapter.java index 8f4108662615..4d7d5a436ae9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; +package org.springframework.boot.metrics.autoconfigure.export.prometheus; import java.time.Duration; import java.util.Map; @@ -22,7 +22,7 @@ import io.micrometer.prometheusmetrics.PrometheusConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; /** * Adapter to convert {@link PrometheusProperties} to a {@link PrometheusConfig}. diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/package-info.java new file mode 100644 index 000000000000..c3a99b0e9596 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Prometheus. + */ +package org.springframework.boot.metrics.autoconfigure.export.prometheus; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PropertiesConfigAdapter.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PropertiesConfigAdapter.java index 1acfb44bebd1..e410fe880f06 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; +package org.springframework.boot.metrics.autoconfigure.export.properties; import java.util.function.Function; import java.util.function.Supplier; @@ -27,7 +27,7 @@ * @param the properties type * @author Phillip Webb * @author Nikolay Rybak - * @since 2.0.0 + * @since 4.0.0 */ public class PropertiesConfigAdapter { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryProperties.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryProperties.java index afcc2500c258..a78821d3442c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryProperties.java @@ -14,10 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; +package org.springframework.boot.metrics.autoconfigure.export.properties; import java.time.Duration; +import org.springframework.boot.context.properties.ConfigurationPropertiesSource; + /** * Base class for properties that configure a metrics registry that pushes aggregated * metrics on a regular interval. @@ -25,8 +27,9 @@ * @author Jon Schneider * @author Andy Wilkinson * @author Stephane Nicoll - * @since 2.2.0 + * @since 4.0.0 */ +@ConfigurationPropertiesSource public abstract class PushRegistryProperties { /** diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryPropertiesConfigAdapter.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryPropertiesConfigAdapter.java index 2049b93c56ef..d236110f0861 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryPropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; +package org.springframework.boot.metrics.autoconfigure.export.properties; import java.time.Duration; @@ -27,7 +27,7 @@ * @author Jon Schneider * @author Phillip Webb * @author Artsiom Yudovin - * @since 2.2.0 + * @since 4.0.0 */ public abstract class PushRegistryPropertiesConfigAdapter extends PropertiesConfigAdapter implements PushRegistryConfig { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryProperties.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryProperties.java index 2b0b41fe54c0..f03f2a5302f1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; +package org.springframework.boot.metrics.autoconfigure.export.properties; /** * {@link PushRegistryProperties} extensions for registries that are step-normalized. @@ -22,7 +22,7 @@ * @author Jon Schneider * @author Andy Wilkinson * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public abstract class StepRegistryProperties extends PushRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesConfigAdapter.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesConfigAdapter.java index e874a0327673..e32d4c8dd013 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; +package org.springframework.boot.metrics.autoconfigure.export.properties; import io.micrometer.core.instrument.step.StepRegistryConfig; @@ -25,7 +25,7 @@ * @author Jon Schneider * @author Phillip Webb * @author Artsiom Yudovin - * @since 2.0.0 + * @since 4.0.0 */ public abstract class StepRegistryPropertiesConfigAdapter extends PushRegistryPropertiesConfigAdapter { diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/package-info.java new file mode 100644 index 000000000000..f23464783687 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/properties/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Base properties and adapters used when exporting actuator metrics. + */ +package org.springframework.boot.metrics.autoconfigure.export.properties; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleMetricsExportAutoConfiguration.java similarity index 84% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleMetricsExportAutoConfiguration.java index 181aff980382..ff5dff2d0218 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleMetricsExportAutoConfiguration.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.simple; +package org.springframework.boot.metrics.autoconfigure.export.simple; import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.simple.SimpleConfig; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; import org.springframework.context.annotation.Bean; /** @@ -37,7 +37,7 @@ * beans and only used as a fallback. * * @author Jon Schneider - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(before = CompositeMeterRegistryAutoConfiguration.class, after = MetricsAutoConfiguration.class) @ConditionalOnBean(Clock.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleProperties.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleProperties.java index 96bf789c0c46..a4000b3d932c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.simple; +package org.springframework.boot.metrics.autoconfigure.export.simple; import java.time.Duration; @@ -29,7 +29,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.simple.metrics.export") public class SimpleProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesConfigAdapter.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesConfigAdapter.java index 099ab2ffac5e..7c09dd713091 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesConfigAdapter.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.simple; +package org.springframework.boot.metrics.autoconfigure.export.simple; import java.time.Duration; import io.micrometer.core.instrument.simple.CountingMode; import io.micrometer.core.instrument.simple.SimpleConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; /** * Adapter to convert {@link SimpleProperties} to a {@link SimpleConfig}. * * @author Jon Schneider - * @since 2.0.0 + * @since 4.0.0 */ public class SimplePropertiesConfigAdapter extends PropertiesConfigAdapter implements SimpleConfig { diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/package-info.java new file mode 100644 index 000000000000..2d80d42b2dad --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/simple/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to a simple in-memory store. + */ +package org.springframework.boot.metrics.autoconfigure.export.simple; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverMetricsExportAutoConfiguration.java similarity index 82% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverMetricsExportAutoConfiguration.java index 2ed3f59f83a4..ab530f492b1b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverMetricsExportAutoConfiguration.java @@ -14,22 +14,22 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver; +package org.springframework.boot.metrics.autoconfigure.export.stackdriver; import io.micrometer.core.instrument.Clock; import io.micrometer.stackdriver.StackdriverConfig; import io.micrometer.stackdriver.StackdriverMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -38,7 +38,7 @@ * * @author Johannes Graf * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverProperties.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverProperties.java index 1fd07285a5f7..8e14b27087d0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverProperties.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver; +package org.springframework.boot.metrics.autoconfigure.export.stackdriver; import java.util.Map; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryProperties; /** * {@link ConfigurationProperties @ConfigurationProperties} for configuring Stackdriver @@ -27,7 +27,7 @@ * * @author Johannes Graf * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ @ConfigurationProperties("management.stackdriver.metrics.export") public class StackdriverProperties extends StepRegistryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesConfigAdapter.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesConfigAdapter.java index 3345bc0cc3df..a214623b489e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesConfigAdapter.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver; +package org.springframework.boot.metrics.autoconfigure.export.stackdriver; import java.util.Map; import io.micrometer.stackdriver.StackdriverConfig; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapter; /** * Adapter to convert {@link StackdriverProperties} to a {@link StackdriverConfig}. * * @author Johannes Graf - * @since 2.3.0 + * @since 4.0.0 */ public class StackdriverPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter implements StackdriverConfig { diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/package-info.java new file mode 100644 index 000000000000..3bef63703ac2 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to Stackdriver. + */ +package org.springframework.boot.metrics.autoconfigure.export.stackdriver; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdMetricsExportAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdMetricsExportAutoConfiguration.java index ac88b466451e..0054a85ad579 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdMetricsExportAutoConfiguration.java @@ -14,29 +14,29 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; +package org.springframework.boot.metrics.autoconfigure.export.statsd; import io.micrometer.core.instrument.Clock; import io.micrometer.statsd.StatsdConfig; import io.micrometer.statsd.StatsdMeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.ConditionalOnEnabledMetricsExport; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; /** * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to StatsD. * * @author Jon Schneider - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdProperties.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdProperties.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdProperties.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdProperties.java index 87fd8c3a29e4..9179c40de0f8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdProperties.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; +package org.springframework.boot.metrics.autoconfigure.export.statsd; import java.time.Duration; @@ -29,7 +29,7 @@ * * @author Jon Schneider * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.statsd.metrics.export") public class StatsdProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesConfigAdapter.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapter.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesConfigAdapter.java index 5566b91cd5e2..6b4340c6403c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesConfigAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; +package org.springframework.boot.metrics.autoconfigure.export.statsd; import java.time.Duration; @@ -22,13 +22,13 @@ import io.micrometer.statsd.StatsdFlavor; import io.micrometer.statsd.StatsdProtocol; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; /** * Adapter to convert {@link StatsdProperties} to a {@link StatsdConfig}. * * @author Jon Schneider - * @since 2.0.0 + * @since 4.0.0 */ public class StatsdPropertiesConfigAdapter extends PropertiesConfigAdapter implements StatsdConfig { diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/package-info.java new file mode 100644 index 000000000000..f1fe0b29a6c7 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/export/statsd/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for exporting actuator metrics to StatsD. + */ +package org.springframework.boot.metrics.autoconfigure.export.statsd; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/jvm/JvmMetricsAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/jvm/JvmMetricsAutoConfiguration.java index 935b4a6072c2..3aa23450bdfe 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/jvm/JvmMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.jvm; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.MeterBinder; @@ -35,6 +35,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.util.ClassUtils; @@ -44,7 +46,7 @@ * * @author Stephane Nicoll * @author Eddú Meléndez - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) @ConditionalOnClass(MeterRegistry.class) diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/jvm/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/jvm/package-info.java new file mode 100644 index 000000000000..ca886784a34c --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/jvm/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JVM metrics. + */ +package org.springframework.boot.metrics.autoconfigure.jvm; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsAutoConfiguration.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsAutoConfiguration.java index 1afa4dde2123..6a9a5075b91f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsAutoConfiguration.java @@ -14,20 +14,22 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.logging.log4j2; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.spi.LoggerContext; -import org.springframework.boot.actuate.autoconfigure.metrics.Log4J2MetricsAutoConfiguration.Log4JCoreLoggerContextCondition; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.logging.log4j2.Log4J2MetricsAutoConfiguration.Log4JCoreLoggerContextCondition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; @@ -37,7 +39,7 @@ * Auto-configuration for Log4J2 metrics. * * @author Andy Wilkinson - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) @ConditionalOnClass(value = { Log4j2Metrics.class, LogManager.class }, diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/package-info.java new file mode 100644 index 000000000000..dc9950647503 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Log4J2 metrics. + */ +package org.springframework.boot.metrics.autoconfigure.logging.log4j2; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfiguration.java index dc9868d01774..7907647c7b74 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.logging.logback; import ch.qos.logback.classic.LoggerContext; import io.micrometer.core.instrument.MeterRegistry; @@ -22,7 +22,6 @@ import org.slf4j.ILoggerFactory; import org.slf4j.LoggerFactory; -import org.springframework.boot.actuate.autoconfigure.metrics.LogbackMetricsAutoConfiguration.LogbackLoggingCondition; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionMessage; @@ -31,6 +30,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.logging.logback.LogbackMetricsAutoConfiguration.LogbackLoggingCondition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; @@ -40,7 +42,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for Logback metrics. * * @author Stephane Nicoll - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) @ConditionalOnClass({ MeterRegistry.class, LoggerContext.class, LoggerFactory.class }) diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/logback/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/logback/package-info.java new file mode 100644 index 000000000000..3748c64a62c0 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/logging/logback/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Logback metrics. + */ +package org.springframework.boot.metrics.autoconfigure.logging.logback; diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/package-info.java new file mode 100644 index 000000000000..4688a0e1680d --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for metrics with Micrometer. + */ +package org.springframework.boot.metrics.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslMeterBinder.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMeterBinder.java similarity index 99% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslMeterBinder.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMeterBinder.java index 699857f491fc..f208b7cc4b8e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/ssl/SslMeterBinder.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMeterBinder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.ssl; +package org.springframework.boot.metrics.autoconfigure.ssl; import java.time.Clock; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMetricsAutoConfiguration.java new file mode 100644 index 000000000000..58fa7414f32b --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMetricsAutoConfiguration.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.metrics.autoconfigure.ssl; + +import io.micrometer.core.instrument.MeterRegistry; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.info.SslInfo; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for SSL metrics. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +@AutoConfiguration(after = { CompositeMeterRegistryAutoConfiguration.class, MetricsAutoConfiguration.class, + SslAutoConfiguration.class }) +@ConditionalOnClass(MeterRegistry.class) +@ConditionalOnBean({ MeterRegistry.class, SslBundles.class }) +public class SslMetricsAutoConfiguration { + + @Bean + SslMeterBinder sslMeterBinder(SslBundles sslBundles, ObjectProvider sslInfo) { + return new SslMeterBinder(sslInfo.getIfAvailable(() -> new SslInfo(sslBundles)), sslBundles); + } + +} diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/package-info.java new file mode 100644 index 000000000000..b0406956eedd --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/ssl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for SSL metrics. + */ +package org.springframework.boot.metrics.autoconfigure.ssl; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/StartupTimeMetricsListenerAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/startup/StartupTimeMetricsListenerAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/StartupTimeMetricsListenerAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/startup/StartupTimeMetricsListenerAutoConfiguration.java index 0b0454dc875d..8485cd82febe 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/StartupTimeMetricsListenerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/startup/StartupTimeMetricsListenerAutoConfiguration.java @@ -14,25 +14,25 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.startup; +package org.springframework.boot.metrics.autoconfigure.startup; import io.micrometer.core.instrument.MeterRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.metrics.startup.StartupTimeMetricsListener; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.startup.StartupTimeMetricsListener; import org.springframework.context.annotation.Bean; /** * {@link EnableAutoConfiguration Auto-configuration} for startup time metrics. * * @author Chris Bono - * @since 2.6.0 + * @since 4.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) @ConditionalOnClass(MeterRegistry.class) diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/startup/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/startup/package-info.java new file mode 100644 index 000000000000..c207f638ec59 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/startup/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for actuator startup time metrics. + */ +package org.springframework.boot.metrics.autoconfigure.startup; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/system/SystemMetricsAutoConfiguration.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/system/SystemMetricsAutoConfiguration.java index 922008150569..2fd4995d4e24 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/system/SystemMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.system; import java.io.File; import java.util.List; @@ -25,13 +25,16 @@ import io.micrometer.core.instrument.binder.system.ProcessorMetrics; import io.micrometer.core.instrument.binder.system.UptimeMetrics; -import org.springframework.boot.actuate.metrics.system.DiskSpaceMetricsBinder; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsProperties; +import org.springframework.boot.metrics.system.DiskSpaceMetricsBinder; import org.springframework.context.annotation.Bean; /** @@ -39,7 +42,7 @@ * * @author Stephane Nicoll * @author Chris Bono - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) @ConditionalOnClass(MeterRegistry.class) diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/system/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/system/package-info.java new file mode 100644 index 000000000000..56c2a9391bfe --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/system/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for system metrics. + */ +package org.springframework.boot.metrics.autoconfigure.system; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/task/TaskExecutorMetricsAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/task/TaskExecutorMetricsAutoConfiguration.java index d1d0a0ebde62..4cf6d39cb323 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/task/TaskExecutorMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.task; +package org.springframework.boot.metrics.autoconfigure.task; import java.util.Collections; import java.util.concurrent.Executor; @@ -27,14 +27,14 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver; import org.springframework.boot.LazyInitializationExcludeFilter; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -47,7 +47,7 @@ * * @author Stephane Nicoll * @author Scott Frederick - * @since 2.6.0 + * @since 4.0.0 */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class, TaskExecutionAutoConfiguration.class, TaskSchedulingAutoConfiguration.class }) diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/task/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/task/package-info.java new file mode 100644 index 000000000000..2a76968c699e --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/autoconfigure/task/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for task execution and scheduling metrics. + */ +package org.springframework.boot.metrics.autoconfigure.task; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/docker/compose/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactory.java similarity index 88% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/docker/compose/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactory.java index 2b456e912c77..3b7160e35950 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/docker/compose/otlp/OpenTelemetryMetricsDockerComposeConnectionDetailsFactory.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.metrics.docker.compose.otlp; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create @@ -37,7 +37,7 @@ class OpenTelemetryMetricsDockerComposeConnectionDetailsFactory OpenTelemetryMetricsDockerComposeConnectionDetailsFactory() { super(OPENTELEMETRY_IMAGE_NAMES, - "org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration"); + "org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration"); } @Override diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/docker/compose/otlp/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/docker/compose/otlp/package-info.java new file mode 100644 index 000000000000..8d01bba6aac9 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/docker/compose/otlp/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose OpenTelemetry metrics service connections. + */ +package org.springframework.boot.metrics.docker.compose.otlp; diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/package-info.java new file mode 100644 index 000000000000..78c5cb1dd583 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * General metrics-related classes. + */ +package org.springframework.boot.metrics; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/startup/StartupTimeMetricsListener.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/startup/StartupTimeMetricsListener.java index fba9fa5336de..de64654a8b9d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/startup/StartupTimeMetricsListener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.startup; +package org.springframework.boot.metrics.startup; import java.time.Duration; import java.util.Collections; @@ -37,7 +37,7 @@ * * @author Chris Bono * @author Phillip Webb - * @since 2.6.0 + * @since 4.0.0 */ public class StartupTimeMetricsListener implements SmartApplicationListener { diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/startup/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/startup/package-info.java new file mode 100644 index 000000000000..d7872d0f9633 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/startup/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for startup metrics. + */ +package org.springframework.boot.metrics.startup; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/system/DiskSpaceMetricsBinder.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/system/DiskSpaceMetricsBinder.java index d331ac43cf80..bbf95c509c7c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/system/DiskSpaceMetricsBinder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.system; +package org.springframework.boot.metrics.system; import java.io.File; import java.util.List; @@ -30,7 +30,7 @@ * A {@link MeterBinder} that binds one or more {@link DiskSpaceMetrics}. * * @author Chris Bono - * @since 2.6.0 + * @since 4.0.0 */ public class DiskSpaceMetricsBinder implements MeterBinder { diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/system/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/system/package-info.java new file mode 100644 index 000000000000..db8314d9c1f3 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/system/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * System metrics. + */ +package org.springframework.boot.metrics.system; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory.java similarity index 88% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory.java index 4395515ada6c..2d7a2f80da7e 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.metrics.testcontainers.otlp; import org.testcontainers.grafana.LgtmStackContainer; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; @@ -36,7 +36,7 @@ class GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory() { super(ANY_CONNECTION_NAME, - "org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration"); + "org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration"); } @Override diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactory.java similarity index 88% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactory.java index 9605fd57ed8a..c731f33661d0 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/OpenTelemetryMetricsContainerConnectionDetailsFactory.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.metrics.testcontainers.otlp; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; @@ -37,7 +37,7 @@ class OpenTelemetryMetricsContainerConnectionDetailsFactory OpenTelemetryMetricsContainerConnectionDetailsFactory() { super("otel/opentelemetry-collector-contrib", - "org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration"); + "org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration"); } @Override diff --git a/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/package-info.java b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/package-info.java new file mode 100644 index 000000000000..509cfc6aac54 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/java/org/springframework/boot/metrics/testcontainers/otlp/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Testcontainers OpenTelemetry metrics service connections. + */ +package org.springframework.boot.metrics.testcontainers.otlp; diff --git a/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..92b38e4e7887 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,1634 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.defaults.metrics.export.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable default metrics exporters.", + "defaultValue": true + }, + { + "name": "management.metrics.binders.files.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable files metrics.", + "defaultValue": true, + "deprecation": { + "level": "error", + "replacement": "management.metrics.enable.process.files", + "reason": "Instead, filter 'process.files' metrics." + } + }, + { + "name": "management.metrics.binders.jvm.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable JVM metrics.", + "defaultValue": true, + "deprecation": { + "level": "error", + "replacement": "management.metrics.enable.jvm", + "reason": "Instead, disable JvmMetricsAutoConfiguration or filter 'jvm' metrics." + } + }, + { + "name": "management.metrics.binders.logback.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Logback metrics.", + "defaultValue": true, + "deprecation": { + "level": "error", + "replacement": "management.metrics.enable.logback", + "reason": "Instead, disable LogbackMetricsAutoConfiguration or filter 'logback' metrics." + } + }, + { + "name": "management.metrics.binders.processor.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable processor metrics.", + "defaultValue": true, + "deprecation": { + "level": "error", + "reason": "Instead, filter 'system.cpu' and 'process.cpu' metrics." + } + }, + { + "name": "management.metrics.binders.uptime.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable uptime metrics.", + "defaultValue": true, + "deprecation": { + "level": "error", + "reason": "Instead, filter 'process.uptime' and 'process.start.time' metrics." + } + }, + { + "name": "management.metrics.export.appoptics.api-token", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.api-token" + } + }, + { + "name": "management.metrics.export.appoptics.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.appoptics.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.appoptics.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.appoptics.floor-times", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.floor-times" + } + }, + { + "name": "management.metrics.export.appoptics.host-tag", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.host-tag" + } + }, + { + "name": "management.metrics.export.appoptics.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.appoptics.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.appoptics.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.step" + } + }, + { + "name": "management.metrics.export.appoptics.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.appoptics.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.atlas.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.atlas.config-refresh-frequency", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.config-refresh-frequency" + } + }, + { + "name": "management.metrics.export.atlas.config-time-to-live", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.config-time-to-live" + } + }, + { + "name": "management.metrics.export.atlas.config-uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.config-uri" + } + }, + { + "name": "management.metrics.export.atlas.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.atlas.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.atlas.eval-uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.eval-uri" + } + }, + { + "name": "management.metrics.export.atlas.lwc-enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.lwc-enabled" + } + }, + { + "name": "management.metrics.export.atlas.meter-time-to-live", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.meter-time-to-live" + } + }, + { + "name": "management.metrics.export.atlas.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.atlas.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.atlas.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.step" + } + }, + { + "name": "management.metrics.export.atlas.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.atlas.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.datadog.api-key", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.api-key" + } + }, + { + "name": "management.metrics.export.datadog.application-key", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.application-key" + } + }, + { + "name": "management.metrics.export.datadog.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.datadog.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.datadog.descriptions", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.descriptions" + } + }, + { + "name": "management.metrics.export.datadog.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.datadog.host-tag", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.host-tag" + } + }, + { + "name": "management.metrics.export.datadog.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.datadog.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.datadog.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.step" + } + }, + { + "name": "management.metrics.export.datadog.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.datadog.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.defaults.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.defaults.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.dynatrace.api-token", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.api-token" + } + }, + { + "name": "management.metrics.export.dynatrace.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.dynatrace.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.dynatrace.device-id", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.device-id" + } + }, + { + "name": "management.metrics.export.dynatrace.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.dynatrace.group", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.group" + } + }, + { + "name": "management.metrics.export.dynatrace.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.dynatrace.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.dynatrace.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.step" + } + }, + { + "name": "management.metrics.export.dynatrace.technology-type", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.technology-type" + } + }, + { + "name": "management.metrics.export.dynatrace.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.dynatrace.v1.device-id", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.v1.device-id" + } + }, + { + "name": "management.metrics.export.dynatrace.v1.group", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.v1.group" + } + }, + { + "name": "management.metrics.export.dynatrace.v1.technology-type", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.v1.technology-type" + } + }, + { + "name": "management.metrics.export.dynatrace.v2.default-dimensions", + "type": "java.util.Map", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.v2.default-dimensions" + } + }, + { + "name": "management.metrics.export.dynatrace.v2.enrich-with-dynatrace-metadata", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.v2.enrich-with-dynatrace-metadata" + } + }, + { + "name": "management.metrics.export.dynatrace.v2.metric-key-prefix", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.dynatrace.metrics.export.v2.metric-key-prefix" + } + }, + { + "name": "management.metrics.export.elastic.api-key-credentials", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.api-key-credentials" + } + }, + { + "name": "management.metrics.export.elastic.auto-create-index", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.auto-create-index" + } + }, + { + "name": "management.metrics.export.elastic.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.elastic.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.elastic.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.elastic.host", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.host" + } + }, + { + "name": "management.metrics.export.elastic.index", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.index" + } + }, + { + "name": "management.metrics.export.elastic.index-date-format", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.index-date-format" + } + }, + { + "name": "management.metrics.export.elastic.index-date-separator", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.index-date-separator" + } + }, + { + "name": "management.metrics.export.elastic.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.elastic.password", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.password" + } + }, + { + "name": "management.metrics.export.elastic.pipeline", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.pipeline" + } + }, + { + "name": "management.metrics.export.elastic.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.elastic.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.step" + } + }, + { + "name": "management.metrics.export.elastic.timestamp-field-name", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.timestamp-field-name" + } + }, + { + "name": "management.metrics.export.elastic.user-name", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.elastic.metrics.export.user-name" + } + }, + { + "name": "management.metrics.export.ganglia.addressing-mode", + "type": "info.ganglia.gmetric4j.gmetric.GMetric$UDPAddressingMode", + "deprecation": { + "level": "error", + "replacement": "management.ganglia.metrics.export.addressing-mode" + } + }, + { + "name": "management.metrics.export.ganglia.duration-units", + "type": "java.util.concurrent.TimeUnit", + "deprecation": { + "level": "error", + "replacement": "management.ganglia.metrics.export.duration-units" + } + }, + { + "name": "management.metrics.export.ganglia.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.ganglia.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.ganglia.host", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.ganglia.metrics.export.host" + } + }, + { + "name": "management.metrics.export.ganglia.port", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.ganglia.metrics.export.port" + } + }, + { + "name": "management.metrics.export.ganglia.rate-units", + "type": "java.util.concurrent.TimeUnit", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.ganglia.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.ganglia.metrics.export.step" + } + }, + { + "name": "management.metrics.export.ganglia.time-to-live", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.ganglia.metrics.export.time-to-live" + } + }, + { + "name": "management.metrics.export.graphite.duration-units", + "type": "java.util.concurrent.TimeUnit", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.duration-units" + } + }, + { + "name": "management.metrics.export.graphite.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.graphite.graphite-tags-enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.graphite-tags-enabled" + } + }, + { + "name": "management.metrics.export.graphite.host", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.host" + } + }, + { + "name": "management.metrics.export.graphite.port", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.port" + } + }, + { + "name": "management.metrics.export.graphite.protocol", + "type": "io.micrometer.graphite.GraphiteProtocol", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.protocol" + } + }, + { + "name": "management.metrics.export.graphite.rate-units", + "type": "java.util.concurrent.TimeUnit", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.rate-units" + } + }, + { + "name": "management.metrics.export.graphite.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.step" + } + }, + { + "name": "management.metrics.export.graphite.tags-as-prefix", + "type": "java.lang.String[]", + "deprecation": { + "level": "error", + "replacement": "management.graphite.metrics.export.tags-as-prefix" + } + }, + { + "name": "management.metrics.export.humio.api-token", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.humio.metrics.export.api-token" + } + }, + { + "name": "management.metrics.export.humio.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.humio.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.humio.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.humio.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.humio.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.humio.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.humio.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.humio.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.humio.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.humio.repository", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.humio.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.humio.metrics.export.step" + } + }, + { + "name": "management.metrics.export.humio.tags", + "type": "java.util.Map", + "deprecation": { + "level": "error", + "replacement": "management.humio.metrics.export.tags" + } + }, + { + "name": "management.metrics.export.humio.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.humio.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.influx.api-version", + "type": "io.micrometer.influx.InfluxApiVersion", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.api-version" + } + }, + { + "name": "management.metrics.export.influx.auto-create-db", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.auto-create-db" + } + }, + { + "name": "management.metrics.export.influx.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.influx.bucket", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.bucket" + } + }, + { + "name": "management.metrics.export.influx.compressed", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.compressed" + } + }, + { + "name": "management.metrics.export.influx.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.influx.consistency", + "type": "io.micrometer.influx.InfluxConsistency", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.consistency" + } + }, + { + "name": "management.metrics.export.influx.db", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.db" + } + }, + { + "name": "management.metrics.export.influx.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.influx.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.influx.org", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.org" + } + }, + { + "name": "management.metrics.export.influx.password", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.password" + } + }, + { + "name": "management.metrics.export.influx.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.influx.retention-duration", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.retention-duration" + } + }, + { + "name": "management.metrics.export.influx.retention-policy", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.retention-policy" + } + }, + { + "name": "management.metrics.export.influx.retention-replication-factor", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.retention-replication-factor" + } + }, + { + "name": "management.metrics.export.influx.retention-shard-duration", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.retention-shard-duration" + } + }, + { + "name": "management.metrics.export.influx.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.step" + } + }, + { + "name": "management.metrics.export.influx.token", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.token" + } + }, + { + "name": "management.metrics.export.influx.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.influx.user-name", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.influx.metrics.export.user-name" + } + }, + { + "name": "management.metrics.export.jmx.domain", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.jmx.metrics.export.domain" + } + }, + { + "name": "management.metrics.export.jmx.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.jmx.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.jmx.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.jmx.metrics.export.step" + } + }, + { + "name": "management.metrics.export.kairos.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.kairos.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.kairos.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.kairos.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.kairos.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.kairos.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.kairos.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.kairos.password", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.kairos.metrics.export.password" + } + }, + { + "name": "management.metrics.export.kairos.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.kairos.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.kairos.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.kairos.metrics.export.step" + } + }, + { + "name": "management.metrics.export.kairos.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.kairos.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.kairos.user-name", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.kairos.metrics.export.user-name" + } + }, + { + "name": "management.metrics.export.newrelic.account-id", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.account-id" + } + }, + { + "name": "management.metrics.export.newrelic.api-key", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.api-key" + } + }, + { + "name": "management.metrics.export.newrelic.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.newrelic.client-provider-type", + "type": "io.micrometer.newrelic.ClientProviderType", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.client-provider-type" + } + }, + { + "name": "management.metrics.export.newrelic.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.newrelic.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.newrelic.event-type", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.event-type" + } + }, + { + "name": "management.metrics.export.newrelic.meter-name-event-type-enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.meter-name-event-type-enabled" + } + }, + { + "name": "management.metrics.export.newrelic.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.newrelic.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.newrelic.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.step" + } + }, + { + "name": "management.metrics.export.newrelic.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.newrelic.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.prometheus.descriptions", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.descriptions" + } + }, + { + "name": "management.metrics.export.prometheus.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.prometheus.histogram-flavor", + "type": "io.micrometer.prometheus.HistogramFlavor", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.histogram-flavor" + } + }, + { + "name": "management.metrics.export.prometheus.pushgateway.base-url", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.base-url" + } + }, + { + "name": "management.metrics.export.prometheus.pushgateway.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.enabled" + } + }, + { + "name": "management.metrics.export.prometheus.pushgateway.grouping-key", + "type": "java.util.Map", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.grouping-key" + } + }, + { + "name": "management.metrics.export.prometheus.pushgateway.job", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.job" + } + }, + { + "name": "management.metrics.export.prometheus.pushgateway.password", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.password" + } + }, + { + "name": "management.metrics.export.prometheus.pushgateway.push-rate", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.push-rate" + } + }, + { + "name": "management.metrics.export.prometheus.pushgateway.shutdown-operation", + "type": "org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager$ShutdownOperation", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.shutdown-operation" + } + }, + { + "name": "management.metrics.export.prometheus.pushgateway.username", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.username" + } + }, + { + "name": "management.metrics.export.prometheus.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.step" + } + }, + { + "name": "management.metrics.export.signalfx.access-token", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.access-token" + } + }, + { + "name": "management.metrics.export.signalfx.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.signalfx.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.signalfx.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.signalfx.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.signalfx.published-histogram-type", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.published-histogram-type" + } + }, + { + "name": "management.metrics.export.signalfx.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.signalfx.source", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.source" + } + }, + { + "name": "management.metrics.export.signalfx.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.step" + } + }, + { + "name": "management.metrics.export.signalfx.uri", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.signalfx.metrics.export.uri" + } + }, + { + "name": "management.metrics.export.simple.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.simple.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.simple.mode", + "type": "io.micrometer.core.instrument.simple.CountingMode", + "deprecation": { + "level": "error", + "replacement": "management.simple.metrics.export.mode" + } + }, + { + "name": "management.metrics.export.simple.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.simple.metrics.export.step" + } + }, + { + "name": "management.metrics.export.stackdriver.batch-size", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.batch-size" + } + }, + { + "name": "management.metrics.export.stackdriver.connect-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.connect-timeout" + } + }, + { + "name": "management.metrics.export.stackdriver.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.stackdriver.num-threads", + "type": "java.lang.Integer", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.export.stackdriver.project-id", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.project-id" + } + }, + { + "name": "management.metrics.export.stackdriver.read-timeout", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.read-timeout" + } + }, + { + "name": "management.metrics.export.stackdriver.resource-labels", + "type": "java.util.Map", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.resource-labels" + } + }, + { + "name": "management.metrics.export.stackdriver.resource-type", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.resource-type" + } + }, + { + "name": "management.metrics.export.stackdriver.step", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.step" + } + }, + { + "name": "management.metrics.export.stackdriver.use-semantic-metric-types", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.stackdriver.metrics.export.use-semantic-metric-types" + } + }, + { + "name": "management.metrics.export.statsd.enabled", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.statsd.metrics.export.enabled" + } + }, + { + "name": "management.metrics.export.statsd.flavor", + "type": "io.micrometer.statsd.StatsdFlavor", + "deprecation": { + "level": "error", + "replacement": "management.statsd.metrics.export.flavor" + } + }, + { + "name": "management.metrics.export.statsd.host", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.statsd.metrics.export.host" + } + }, + { + "name": "management.metrics.export.statsd.max-packet-length", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.statsd.metrics.export.max-packet-length" + } + }, + { + "name": "management.metrics.export.statsd.polling-frequency", + "type": "java.time.Duration", + "deprecation": { + "level": "error", + "replacement": "management.statsd.metrics.export.polling-frequency" + } + }, + { + "name": "management.metrics.export.statsd.port", + "type": "java.lang.Integer", + "deprecation": { + "level": "error", + "replacement": "management.statsd.metrics.export.port" + } + }, + { + "name": "management.metrics.export.statsd.protocol", + "type": "io.micrometer.statsd.StatsdProtocol", + "deprecation": { + "level": "error", + "replacement": "management.statsd.metrics.export.protocol" + } + }, + { + "name": "management.metrics.export.statsd.publish-unchanged-meters", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "replacement": "management.statsd.metrics.export.publish-unchanged-meters" + } + }, + { + "name": "management.metrics.export.statsd.queue-size", + "deprecation": { + "level": "error" + } + }, + { + "name": "management.metrics.system.diskspace.paths", + "type": "java.util.List", + "defaultValue": [ + "." + ] + }, + { + "name": "management.metrics.web.client.request.autotime.enabled", + "description": "Whether to automatically time web client requests.", + "defaultValue": true, + "deprecation": { + "level": "error", + "reason": "Requests are timed automatically." + } + }, + { + "name": "management.metrics.web.client.request.autotime.percentiles", + "description": "Computed non-aggregable percentiles to publish.", + "deprecation": { + "level": "error", + "reason": "Should be configured globally via management.metrics.distribution.percentiles." + } + }, + { + "name": "management.metrics.web.client.request.autotime.percentiles-histogram", + "description": "Whether percentile histograms should be published.", + "defaultValue": false, + "deprecation": { + "level": "error", + "reason": "Should be configured globally via management.metrics.distribution.percentiles-histogram." + } + }, + { + "name": "management.metrics.web.client.request.metric-name", + "type": "java.lang.String", + "deprecation": { + "replacement": "management.observations.http.client.requests.name", + "level": "error" + } + }, + { + "name": "management.metrics.web.client.requests-metric-name", + "type": "java.lang.String", + "deprecation": { + "replacement": "management.observations.http.client.requests.name", + "level": "error" + } + }, + { + "name": "management.metrics.web.server.auto-time-requests", + "type": "java.lang.Boolean", + "deprecation": { + "replacement": "management.metrics.web.server.request.autotime.enabled", + "level": "error" + } + }, + { + "name": "management.metrics.web.server.request.autotime.enabled", + "description": "Whether to automatically time web server requests.", + "defaultValue": true, + "deprecation": { + "level": "error", + "reason": "Requests are timed automatically." + } + }, + { + "name": "management.metrics.web.server.request.autotime.percentiles", + "description": "Computed non-aggregable percentiles to publish.", + "deprecation": { + "level": "error", + "reason": "Should be configured globally via management.metrics.distribution.percentiles." + } + }, + { + "name": "management.metrics.web.server.request.autotime.percentiles-histogram", + "description": "Whether percentile histograms should be published.", + "defaultValue": false, + "deprecation": { + "level": "error", + "reason": "Should be configured globally via management.metrics.distribution.percentiles-histogram." + } + }, + { + "name": "management.metrics.web.server.request.ignore-trailing-slash", + "type": "java.lang.Boolean", + "deprecation": { + "level": "error", + "reason": "Not needed anymore, direct instrumentation in Spring MVC." + } + }, + { + "name": "management.metrics.web.server.request.metric-name", + "type": "java.lang.String", + "deprecation": { + "replacement": "management.observations.http.server.requests.name", + "level": "error" + } + }, + { + "name": "management.metrics.web.server.requests-metric-name", + "type": "java.lang.String", + "deprecation": { + "replacement": "management.observations.http.server.requests.name", + "level": "error" + } + }, + { + "name": "management.promethus.metrics.export.pushgateway.base-url", + "type": "java.lang.String", + "deprecation": { + "level": "error", + "replacement": "management.prometheus.metrics.export.pushgateway.address" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..fc13ca12bd19 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring.factories @@ -0,0 +1,9 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.metrics.docker.compose.otlp.OpenTelemetryMetricsDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.metrics.testcontainers.otlp.GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory,\ +org.springframework.boot.metrics.testcontainers.otlp.OpenTelemetryMetricsContainerConnectionDetailsFactory + +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.boot.metrics.ValidationFailureAnalyzer diff --git a/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..4a0e79229d61 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.metrics.autoconfigure.ServiceLevelObjectiveBoundary$ServiceLevelObjectiveBoundaryHints diff --git a/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..17efdbd49ea3 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,27 @@ +org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration +org.springframework.boot.metrics.autoconfigure.MetricsAspectsAutoConfiguration +org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration +org.springframework.boot.metrics.autoconfigure.MetricsEndpointAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.appoptics.AppOpticsMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.atlas.AtlasMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.datadog.DatadogMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.dynatrace.DynatraceMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.elastic.ElasticMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.ganglia.GangliaMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.graphite.GraphiteMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.humio.HumioMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.influx.InfluxMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.jmx.JmxMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.kairos.KairosMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.newrelic.NewRelicMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.prometheus.PrometheusMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.stackdriver.StackdriverMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.export.statsd.StatsdMetricsExportAutoConfiguration +org.springframework.boot.metrics.autoconfigure.jvm.JvmMetricsAutoConfiguration +org.springframework.boot.metrics.autoconfigure.logging.log4j2.Log4J2MetricsAutoConfiguration +org.springframework.boot.metrics.autoconfigure.logging.logback.LogbackMetricsAutoConfiguration +org.springframework.boot.metrics.autoconfigure.startup.StartupTimeMetricsListenerAutoConfiguration +org.springframework.boot.metrics.autoconfigure.system.SystemMetricsAutoConfiguration +org.springframework.boot.metrics.autoconfigure.task.TaskExecutorMetricsAutoConfiguration diff --git a/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/ValidationFailureAnalyzerTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/ValidationFailureAnalyzerTests.java new file mode 100644 index 000000000000..7bee38482225 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/ValidationFailureAnalyzerTests.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.metrics; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.newrelic.NewRelicConfig; +import io.micrometer.newrelic.NewRelicMeterRegistry; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.diagnostics.FailureAnalysis; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +/** + * Tests for {@link ValidationFailureAnalyzer}. + * + * @author Andy Wilkinson + */ +class ValidationFailureAnalyzerTests { + + @Test + void analyzesMissingRequiredConfiguration() { + FailureAnalysis analysis = new ValidationFailureAnalyzer() + .analyze(createFailure(MissingAccountIdAndApiKeyConfiguration.class)); + assertThat(analysis).isNotNull(); + assertThat(analysis.getCause().getMessage()).contains("newrelic.metrics.export.apiKey was 'null'"); + assertThat(analysis.getDescription()).isEqualTo(String.format("Invalid Micrometer configuration detected:%n%n" + + " - newrelic.metrics.export.apiKey was 'null' but it is required when publishing to Insights API%n" + + " - newrelic.metrics.export.accountId was 'null' but it is required when publishing to Insights API")); + } + + private Exception createFailure(Class configuration) { + try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(configuration)) { + fail("Expected failure did not occur"); + return null; + } + catch (Exception ex) { + return ex; + } + } + + @Configuration(proxyBeanMethods = false) + static class MissingAccountIdAndApiKeyConfiguration { + + @Bean + NewRelicMeterRegistry meterRegistry() { + return new NewRelicMeterRegistry(new NewRelicConfig() { + + @Override + public String get(String key) { + return null; + } + + @Override + public String prefix() { + return "newrelic.metrics.export"; + } + + }, Clock.SYSTEM); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/actuate/endpoint/MetricsEndpointTests.java similarity index 99% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/actuate/endpoint/MetricsEndpointTests.java index bfc0f452e9bc..b43ffb73b82c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/actuate/endpoint/MetricsEndpointTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics; +package org.springframework.boot.metrics.actuate.endpoint; import java.util.Collections; import java.util.Optional; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryAutoConfigurationTests.java index 058c027119d7..34aad20ebd93 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/CompositeMeterRegistryAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/CompositeMeterRegistryAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.MeterRegistry; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryCustomizerTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryCustomizerTests.java similarity index 78% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryCustomizerTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryCustomizerTests.java index 98752f7c21cd..95e37930d627 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryCustomizerTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryCustomizerTests.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; +import com.netflix.spectator.atlas.AtlasConfig; import io.micrometer.atlas.AtlasMeterRegistry; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.prometheusmetrics.PrometheusConfig; import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.metrics.autoconfigure.jvm.JvmMetricsAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -40,9 +40,25 @@ class MeterRegistryCustomizerTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .with(MetricsRun.limitedTo(AtlasMetricsExportAutoConfiguration.class, - PrometheusMetricsExportAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(JvmMetricsAutoConfiguration.class)); + .withBean(AtlasMeterRegistry.class, () -> new AtlasMeterRegistry(new AtlasConfig() { + + @Override + public String get(String k) { + return null; + } + + })) + .withBean(PrometheusMeterRegistry.class, () -> new PrometheusMeterRegistry(new PrometheusConfig() { + + @Override + public String get(String key) { + return null; + } + + })) + .withPropertyValues("management.metrics.use-global-registry=false") + .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, + CompositeMeterRegistryAutoConfiguration.class, JvmMetricsAutoConfiguration.class)); @Test void commonTagsAreAppliedToAutoConfiguredBinders() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessorTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryPostProcessorTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessorTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryPostProcessorTests.java index e904ec2a280d..a9c886f6eb6c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessorTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterRegistryPostProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.util.ArrayList; import java.util.Collections; @@ -34,7 +34,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryPostProcessor.CompositeMeterRegistries; +import org.springframework.boot.metrics.autoconfigure.MeterRegistryPostProcessor.CompositeMeterRegistries; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterValueTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterValueTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterValueTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterValueTests.java index 0d940540ec12..c60efeae817f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterValueTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MeterValueTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import io.micrometer.core.instrument.Meter.Type; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAspectsAutoConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAspectsAutoConfigurationTests.java index a13fecd3d659..3bae5c1f9705 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAspectsAutoConfigurationTests.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import io.micrometer.core.aop.CountedAspect; import io.micrometer.core.aop.MeterTagAnnotationHandler; import io.micrometer.core.aop.TimedAspect; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.aspectj.weaver.Advice; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -40,14 +40,14 @@ */ class MetricsAspectsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) .withPropertyValues("management.observations.annotations.enabled=true") .withConfiguration(AutoConfigurations.of(MetricsAspectsAutoConfiguration.class)); @Test void shouldNotConfigureAspectsByDefault() { - new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(MetricsAspectsAutoConfiguration.class)) + new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(MetricsAspectsAutoConfiguration.class)) .run((context) -> { assertThat(context).doesNotHaveBean(CountedAspect.class); assertThat(context).doesNotHaveBean(TimedAspect.class); diff --git a/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationIntegrationTests.java new file mode 100644 index 000000000000..d8029c96d61f --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationIntegrationTests.java @@ -0,0 +1,146 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.metrics.autoconfigure; + +import java.util.Arrays; +import java.util.Set; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.MockClock; +import io.micrometer.core.instrument.composite.CompositeMeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for metrics auto-configuration. + * + * @author Stephane Nicoll + */ +class MetricsAutoConfigurationIntegrationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=false"); + + @Test + void propertyBasedMeterFilteringIsAutoConfigured() { + this.contextRunner.withPropertyValues("management.metrics.enable.my.org=false").run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.timer("my.org.timer"); + assertThat(registry.find("my.org.timer").timer()).isNull(); + }); + } + + @Test + void propertyBasedCommonTagsIsAutoConfigured() { + this.contextRunner + .withPropertyValues("management.metrics.tags.region=test", "management.metrics.tags.origin=local") + .run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.counter("my.counter", "env", "qa"); + assertThat(registry.find("my.counter") + .tags("env", "qa") + .tags("region", "test") + .tags("origin", "local") + .counter()).isNotNull(); + }); + } + + @Test + void emptyCompositeIsCreatedWhenNoMeterRegistriesAreAutoConfigured() { + this.contextRunner.run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); + assertThat(((CompositeMeterRegistry) registry).getRegistries()).isEmpty(); + }); + } + + @Test + void noCompositeIsCreatedWhenASingleMeterRegistryIsAutoConfigured() { + this.contextRunner.withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) + .run((context) -> assertThat(context.getBean(MeterRegistry.class)).isInstanceOf(SimpleMeterRegistry.class)); + } + + @Test + void noCompositeIsCreatedWithMultipleRegistriesAndOneThatIsPrimary() { + this.contextRunner + .withBean("meterRegistry1", SimpleMeterRegistry.class, SimpleMeterRegistry::new, + (definition) -> definition.setPrimary(true)) + .withBean("meterRegistry2", SimpleMeterRegistry.class, SimpleMeterRegistry::new) + .run((context) -> assertThat(context.getBean(MeterRegistry.class)).isInstanceOf(SimpleMeterRegistry.class)); + } + + @Test + void compositeCreatedWithMultipleRegistries() { + this.contextRunner.withBean("meterRegistry1", SimpleMeterRegistry.class, SimpleMeterRegistry::new) + .withBean("meterRegistry2", SimpleMeterRegistry.class, SimpleMeterRegistry::new) + .run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); + assertThat(((CompositeMeterRegistry) registry).getRegistries()).hasSize(2); + }); + } + + @Test + void autoConfiguredCompositeDoesNotHaveMeterFiltersApplied() { + this.contextRunner.withBean("meterRegistry1", SimpleMeterRegistry.class, SimpleMeterRegistry::new) + .withBean("meterRegistry2", SimpleMeterRegistry.class, SimpleMeterRegistry::new) + .run((context) -> { + MeterRegistry composite = context.getBean(MeterRegistry.class); + assertThat(composite).extracting("filters", InstanceOfAssertFactories.ARRAY).isEmpty(); + assertThat(composite).isInstanceOf(CompositeMeterRegistry.class); + Set registries = ((CompositeMeterRegistry) composite).getRegistries(); + assertThat(registries).hasSize(2); + assertThat(registries).allSatisfy( + (registry) -> assertThat(registry).extracting("filters", InstanceOfAssertFactories.ARRAY) + .hasSize(1)); + }); + } + + @Test + void userConfiguredCompositeHasMeterFiltersApplied() { + this.contextRunner.withUserConfiguration(CompositeMeterRegistryConfiguration.class).run((context) -> { + MeterRegistry composite = context.getBean(MeterRegistry.class); + assertThat(composite).extracting("filters", InstanceOfAssertFactories.ARRAY).hasSize(1); + assertThat(composite).isInstanceOf(CompositeMeterRegistry.class); + Set registries = ((CompositeMeterRegistry) composite).getRegistries(); + assertThat(registries).hasSize(2); + assertThat(registries).hasOnlyElementsOfTypes(SimpleMeterRegistry.class); + }); + } + + @Configuration(proxyBeanMethods = false) + static class CompositeMeterRegistryConfiguration { + + @Bean + CompositeMeterRegistry compositeMeterRegistry() { + return new CompositeMeterRegistry(new MockClock(), + Arrays.asList(new SimpleMeterRegistry(), new SimpleMeterRegistry())); + } + + } + +} diff --git a/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java new file mode 100644 index 000000000000..b1bd52c707a9 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java @@ -0,0 +1,156 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.metrics.autoconfigure; + +import java.util.Map; + +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.composite.CompositeMeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.metrics.autoconfigure.jvm.JvmMetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.logging.logback.LogbackMetricsAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link MeterRegistryPostProcessor} configured by + * {@link MetricsAutoConfiguration}. + * + * @author Jon Schneider + */ +class MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=false"); + + @Test + void binderMetricsAreSearchableFromTheComposite() { + this.contextRunner.withConfiguration(AutoConfigurations.of(JvmMetricsAutoConfiguration.class)) + .run((context) -> { + CompositeMeterRegistry composite = context.getBean(CompositeMeterRegistry.class); + composite.get("jvm.memory.used").gauge(); + context.getBeansOfType(MeterRegistry.class) + .forEach((name, registry) -> registry.get("jvm.memory.used").gauge()); + }); + } + + @Test + void customizersAreAppliedBeforeBindersAreCreated() { + this.contextRunner.withUserConfiguration(TestConfiguration.class).run((context) -> { + }); + } + + @Test + void counterIsIncrementedOncePerEventWithoutCompositeMeterRegistry() { + this.contextRunner.withBean(SimpleMeterRegistry.class) + .withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)) + .run((context) -> { + Logger logger = ((LoggerContext) LoggerFactory.getILoggerFactory()).getLogger("test-logger"); + logger.error("Error."); + Map registriesByName = context.getBeansOfType(MeterRegistry.class); + assertThat(registriesByName).hasSize(1); + MeterRegistry registry = registriesByName.values().iterator().next(); + assertThat(registry.get("logback.events").tag("level", "error").counter().count()).isOne(); + }); + } + + @Test + void counterIsIncrementedOncePerEventWithCompositeMeterRegistry() { + this.contextRunner.withBean("meterRegistry1", SimpleMeterRegistry.class) + .withBean("meterRegistry2", SimpleMeterRegistry.class) + .withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)) + .run((context) -> { + Logger logger = ((LoggerContext) LoggerFactory.getILoggerFactory()).getLogger("test-logger"); + logger.error("Error."); + Map registriesByName = context.getBeansOfType(MeterRegistry.class); + assertThat(registriesByName).hasSize(3); + registriesByName.forEach((name, + registry) -> assertThat(registry.get("logback.events").tag("level", "error").counter().count()) + .isOne()); + }); + } + + @Configuration(proxyBeanMethods = false) + static class TestConfiguration { + + @Bean + MeterBinder testBinder(Alpha thing) { + return (registry) -> { + }; + } + + @Bean + MeterRegistryCustomizer testCustomizer() { + return (registry) -> registry.config().commonTags("testTag", "testValue"); + } + + @Bean + Alpha alpha() { + return new Alpha(); + } + + @Bean + Bravo bravo(Alpha alpha) { + return new Bravo(alpha); + } + + @Bean + static BeanPostProcessor testPostProcessor(ApplicationContext context) { + return new BeanPostProcessor() { + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) { + if (bean instanceof Bravo) { + MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); + meterRegistry.gauge("test", 1); + System.out.println(meterRegistry.find("test").gauge().getId().getTags()); + } + return bean; + } + + }; + } + + } + + static class Alpha { + + } + + static class Bravo { + + Bravo(Alpha alpha) { + + } + + } + +} diff --git a/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationTests.java new file mode 100644 index 000000000000..22371b5476e7 --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/MetricsAutoConfigurationTests.java @@ -0,0 +1,168 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.metrics.autoconfigure; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.config.MeterFilter; +import io.micrometer.core.instrument.config.MeterFilterReply; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import io.micrometer.observation.ObservationHandler; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration.MeterRegistryCloser; +import org.springframework.boot.observation.autoconfigure.ObservationHandlerGroup; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link MetricsAutoConfiguration}. + * + * @author Andy Wilkinson + * @author Moritz Halbritter + * @author Phillip Webb + */ +class MetricsAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)); + + @Test + void autoConfiguresAClock() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(Clock.class)); + } + + @Test + void allowsACustomClockToBeUsed() { + this.contextRunner.withUserConfiguration(CustomClockConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(Clock.class).hasBean("customClock")); + } + + @SuppressWarnings("unchecked") + @Test + void configuresMeterRegistries() { + this.contextRunner.withUserConfiguration(MeterRegistryConfiguration.class).run((context) -> { + MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); + MeterFilter[] filters = (MeterFilter[]) ReflectionTestUtils.getField(meterRegistry, "filters"); + assertThat(filters).hasSize(3); + assertThat(filters[0].accept((Meter.Id) null)).isEqualTo(MeterFilterReply.DENY); + assertThat(filters[1]).isInstanceOf(PropertiesMeterFilter.class); + assertThat(filters[2].accept((Meter.Id) null)).isEqualTo(MeterFilterReply.ACCEPT); + then((MeterBinder) context.getBean("meterBinder")).should().bindTo(meterRegistry); + then(context.getBean(MeterRegistryCustomizer.class)).should().customize(meterRegistry); + }); + } + + @Test + void shouldSupplyMeterRegistryCloser() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(MeterRegistryCloser.class)); + } + + @Test + void meterRegistryCloserShouldCloseRegistryOnShutdown() { + this.contextRunner.withUserConfiguration(MeterRegistryConfiguration.class).run((context) -> { + MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); + assertThat(meterRegistry.isClosed()).isFalse(); + context.close(); + assertThat(meterRegistry.isClosed()).isTrue(); + }); + } + + @Test + void supplyHandlerAndGroup() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ObservationHandlerGroup.class); + assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class); + ObservationHandlerGroup group = context.getBean(ObservationHandlerGroup.class); + assertThat(group.isMember(mock(ObservationHandler.class))).isFalse(); + assertThat(group.isMember(mock(MeterObservationHandler.class))).isTrue(); + }); + } + + @Test + void shouldEnableLongTaskTimerByDefault() { + this.contextRunner.run((context) -> { + DefaultMeterObservationHandler handler = context.getBean(DefaultMeterObservationHandler.class); + assertThat(handler).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", true); + }); + } + + @Test + void shouldDisableLongTaskTimerIfPropertyIsSet() { + this.contextRunner.withPropertyValues("management.metrics.observations.ignored-meters=long-task-timer") + .run((context) -> { + DefaultMeterObservationHandler handler = context.getBean(DefaultMeterObservationHandler.class); + assertThat(handler).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", false); + }); + } + + @Configuration(proxyBeanMethods = false) + static class CustomClockConfiguration { + + @Bean + Clock customClock() { + return Clock.SYSTEM; + } + + } + + @Configuration(proxyBeanMethods = false) + static class MeterRegistryConfiguration { + + @Bean + MeterRegistry meterRegistry() { + return new SimpleMeterRegistry(); + } + + @Bean + @SuppressWarnings("rawtypes") + MeterRegistryCustomizer meterRegistryCustomizer() { + return mock(MeterRegistryCustomizer.class); + } + + @Bean + MeterBinder meterBinder() { + return mock(MeterBinder.class); + } + + @Bean + @Order(1) + MeterFilter acceptMeterFilter() { + return MeterFilter.accept(); + } + + @Bean + @Order(-1) + MeterFilter denyMeterFilter() { + return MeterFilter.deny(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/PropertiesMeterFilterTests.java similarity index 99% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/PropertiesMeterFilterTests.java index d1b5b4a7c9d7..9888243095ba 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/PropertiesMeterFilterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.time.Duration; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/ServiceLevelObjectiveBoundaryTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ServiceLevelObjectiveBoundaryTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/ServiceLevelObjectiveBoundaryTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ServiceLevelObjectiveBoundaryTests.java index a6666df1432b..204947c72e7c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/ServiceLevelObjectiveBoundaryTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ServiceLevelObjectiveBoundaryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ConditionalOnEnabledMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ConditionalOnEnabledMetricsExportAutoConfigurationTests.java similarity index 78% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ConditionalOnEnabledMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ConditionalOnEnabledMetricsExportAutoConfigurationTests.java index ee9cdaf7993d..741fd831f76f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ConditionalOnEnabledMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ConditionalOnEnabledMetricsExportAutoConfigurationTests.java @@ -14,11 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export; +package org.springframework.boot.metrics.autoconfigure.export; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -30,7 +32,10 @@ */ class ConditionalOnEnabledMetricsExportAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(MetricsAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=false"); @Test void exporterIsEnabledByDefault() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsMetricsExportAutoConfigurationTests.java index 56d195715629..809940fa800b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics; +package org.springframework.boot.metrics.autoconfigure.export.appoptics; import io.micrometer.appoptics.AppOpticsConfig; import io.micrometer.appoptics.AppOpticsMeterRegistry; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesConfigAdapterTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesConfigAdapterTests.java index 458875d98555..0aff9c8af052 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesConfigAdapterTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics; +package org.springframework.boot.metrics.autoconfigure.export.appoptics; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapterTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapterTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesTests.java index c864d21ccd93..98d530ab7f97 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/appoptics/AppOpticsPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/appoptics/AppOpticsPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics; +package org.springframework.boot.metrics.autoconfigure.export.appoptics; import io.micrometer.appoptics.AppOpticsConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasMetricsExportAutoConfigurationTests.java index 684d5402607f..63412e16ac80 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas; +package org.springframework.boot.metrics.autoconfigure.export.atlas; import com.netflix.spectator.atlas.AtlasConfig; import io.micrometer.atlas.AtlasMeterRegistry; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesConfigAdapterTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesConfigAdapterTests.java index 4689f862d15b..a4309c427802 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas; +package org.springframework.boot.metrics.autoconfigure.export.atlas; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesTests.java index f56472030715..733d152eef52 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/atlas/AtlasPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas; +package org.springframework.boot.metrics.autoconfigure.export.atlas; import com.netflix.spectator.atlas.AtlasConfig; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogMetricsExportAutoConfigurationTests.java index 0ee532a20e4c..a7effa80d2e0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog; +package org.springframework.boot.metrics.autoconfigure.export.datadog; import io.micrometer.core.instrument.Clock; import io.micrometer.datadog.DatadogConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesConfigAdapterTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesConfigAdapterTests.java index 5cfdebd91459..a1e08a8a881c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesConfigAdapterTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog; +package org.springframework.boot.metrics.autoconfigure.export.datadog; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapterTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapterTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesTests.java index 6eef07ae7eb2..e085fd5d7f3f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/datadog/DatadogPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog; +package org.springframework.boot.metrics.autoconfigure.export.datadog; import io.micrometer.datadog.DatadogConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceMetricsExportAutoConfigurationTests.java index 9978081b5561..5743b2e9f2b1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatraceMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace; +package org.springframework.boot.metrics.autoconfigure.export.dynatrace; import java.util.function.Function; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesConfigAdapterTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesConfigAdapterTests.java index 8114f5dafcb6..cf18d07e9105 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace; +package org.springframework.boot.metrics.autoconfigure.export.dynatrace; import java.util.HashMap; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesTests.java index 92b1846a9362..78c6c3781592 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/dynatrace/DynatracePropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace; +package org.springframework.boot.metrics.autoconfigure.export.dynatrace; import io.micrometer.dynatrace.DynatraceConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticMetricsExportAutoConfigurationTests.java index ceea973aa433..268f363659e2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.elastic; +package org.springframework.boot.metrics.autoconfigure.export.elastic; import io.micrometer.core.instrument.Clock; import io.micrometer.elastic.ElasticConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesConfigAdapterTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesConfigAdapterTests.java index 2730e56f180e..f37ed1700055 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.elastic; +package org.springframework.boot.metrics.autoconfigure.export.elastic; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesTests.java index dd3c6f746b85..3adc362afe2c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/elastic/ElasticPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/elastic/ElasticPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.elastic; +package org.springframework.boot.metrics.autoconfigure.export.elastic; import io.micrometer.elastic.ElasticConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java index 53dd72952f7b..e6d77e3fc6ec 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia; +package org.springframework.boot.metrics.autoconfigure.export.ganglia; import io.micrometer.core.instrument.Clock; import io.micrometer.ganglia.GangliaConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesConfigAdapterTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesConfigAdapterTests.java index 09610f68675d..db4acf970bb7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia; +package org.springframework.boot.metrics.autoconfigure.export.ganglia; import java.time.Duration; import java.util.concurrent.TimeUnit; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesTests.java index 25e6c958d671..564c5dd02449 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/ganglia/GangliaPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia; +package org.springframework.boot.metrics.autoconfigure.export.ganglia; import io.micrometer.ganglia.GangliaConfig; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java index a94481cd86ec..b0d138af2242 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.graphite; +package org.springframework.boot.metrics.autoconfigure.export.graphite; import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.Tags; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesConfigAdapterTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesConfigAdapterTests.java index 5ddc46d30978..d2f82709d45a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.graphite; +package org.springframework.boot.metrics.autoconfigure.export.graphite; import java.time.Duration; import java.util.concurrent.TimeUnit; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesTests.java index abcd84fcf4c0..163bbb9da7f2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphitePropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/graphite/GraphitePropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.graphite; +package org.springframework.boot.metrics.autoconfigure.export.graphite; import io.micrometer.graphite.GraphiteConfig; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioMetricsExportAutoConfigurationTests.java index c2e66c8350f9..5b3af989bd11 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; +package org.springframework.boot.metrics.autoconfigure.export.humio; import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesConfigAdapterTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesConfigAdapterTests.java index 09d540043397..13637d3eb0f0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; +package org.springframework.boot.metrics.autoconfigure.export.humio; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesTests.java index fccea1c20787..de1c08130418 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/humio/HumioPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; +package org.springframework.boot.metrics.autoconfigure.export.humio; import io.micrometer.humio.HumioConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxMetricsExportAutoConfigurationTests.java index 73e34c857847..49f0cff7f904 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.influx; +package org.springframework.boot.metrics.autoconfigure.export.influx; import io.micrometer.core.instrument.Clock; import io.micrometer.influx.InfluxConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesConfigAdapterTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesConfigAdapterTests.java index fdc4fe392322..cb990acdeff6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.influx; +package org.springframework.boot.metrics.autoconfigure.export.influx; import io.micrometer.influx.InfluxApiVersion; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesTests.java index b50b661a23c9..f8c83ff60201 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/influx/InfluxPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.influx; +package org.springframework.boot.metrics.autoconfigure.export.influx; import io.micrometer.influx.InfluxConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxMetricsExportAutoConfigurationTests.java index f6632dac7b71..fcc4d87335af 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.jmx; +package org.springframework.boot.metrics.autoconfigure.export.jmx; import io.micrometer.core.instrument.Clock; import io.micrometer.jmx.JmxConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesConfigAdapterTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesConfigAdapterTests.java index d66f4937dd58..dfd34f8ba854 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.jmx; +package org.springframework.boot.metrics.autoconfigure.export.jmx; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesTests.java index 6651d24f4263..57a7b770253e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/jmx/JmxPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.jmx; +package org.springframework.boot.metrics.autoconfigure.export.jmx; import io.micrometer.jmx.JmxConfig; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosMetricsExportAutoConfigurationTests.java index 8739d374fa3c..babd546b9e54 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.kairos; +package org.springframework.boot.metrics.autoconfigure.export.kairos; import io.micrometer.core.instrument.Clock; import io.micrometer.kairos.KairosConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesConfigAdapterTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesConfigAdapterTests.java index f6713efe554a..3f2e80b31392 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesConfigAdapterTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.kairos; +package org.springframework.boot.metrics.autoconfigure.export.kairos; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapterTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapterTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesTests.java index 3c9160e01523..77e1546115cd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/kairos/KairosPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.kairos; +package org.springframework.boot.metrics.autoconfigure.export.kairos; import io.micrometer.kairos.KairosConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicMetricsExportAutoConfigurationTests.java index 28a7a149fea0..fd83ac15d9e2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic; +package org.springframework.boot.metrics.autoconfigure.export.newrelic; import io.micrometer.core.instrument.Clock; import io.micrometer.newrelic.NewRelicClientProvider; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesConfigAdapterTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesConfigAdapterTests.java index 4e604bd17cc7..491a6fcd8f7e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesConfigAdapterTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic; +package org.springframework.boot.metrics.autoconfigure.export.newrelic; import io.micrometer.newrelic.ClientProviderType; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapterTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesConfigAdapterTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesTests.java index e5e057320a50..bb20d85af282 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/newrelic/NewRelicPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/newrelic/NewRelicPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic; +package org.springframework.boot.metrics.autoconfigure.export.newrelic; import io.micrometer.newrelic.NewRelicConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsExportAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsExportAutoConfigurationTests.java index a957f78e7fe0..c46f27f790b5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp; +package org.springframework.boot.metrics.autoconfigure.export.otlp; import java.util.concurrent.ScheduledExecutorService; @@ -26,8 +26,8 @@ import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.JRE; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration.PropertiesOtlpMetricsConnectionDetails; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration.PropertiesOtlpMetricsConnectionDetails; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.assertj.ScheduledExecutorServiceAssert; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesConfigAdapterTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesConfigAdapterTests.java index abaf1eabde4a..9fa059661e08 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp; +package org.springframework.boot.metrics.autoconfigure.export.otlp; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -24,9 +24,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration.PropertiesOtlpMetricsConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsProperties.Meter; -import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryProperties; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsExportAutoConfiguration.PropertiesOtlpMetricsConnectionDetails; +import org.springframework.boot.metrics.autoconfigure.export.otlp.OtlpMetricsProperties.Meter; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetryProperties; import org.springframework.mock.env.MockEnvironment; import static org.assertj.core.api.Assertions.assertThat; @@ -190,21 +190,21 @@ void shouldUseDefaultApplicationNameIfApplicationNameIsNotSet() { } @Test - void serviceGroupOverridesApplicationGroup() { + void serviceNamespaceOverridesApplicationGroup() { this.environment.setProperty("spring.application.group", "alpha"); - this.openTelemetryProperties.setResourceAttributes(Map.of("service.group", "beta")); - assertThat(createAdapter().resourceAttributes()).containsEntry("service.group", "beta"); + this.openTelemetryProperties.setResourceAttributes(Map.of("service.namespace", "beta")); + assertThat(createAdapter().resourceAttributes()).containsEntry("service.namespace", "beta"); } @Test - void shouldUseApplicationGroupIfServiceGroupIsNotSet() { + void shouldUseApplicationGroupIfServiceNamspaceIsNotSet() { this.environment.setProperty("spring.application.group", "alpha"); - assertThat(createAdapter().resourceAttributes()).containsEntry("service.group", "alpha"); + assertThat(createAdapter().resourceAttributes()).containsEntry("service.namespace", "alpha"); } @Test void shouldUseDefaultApplicationGroupIfApplicationGroupIsNotSet() { - assertThat(createAdapter().resourceAttributes()).doesNotContainKey("service.group"); + assertThat(createAdapter().resourceAttributes()).doesNotContainKey("service.namespace"); } private OtlpMetricsPropertiesConfigAdapter createAdapter() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesTests.java index 27547a1f0372..c6511f1be559 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/otlp/OtlpMetricsPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/otlp/OtlpMetricsPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.otlp; +package org.springframework.boot.metrics.autoconfigure.export.otlp; import io.micrometer.registry.otlp.OtlpConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java index 98b0fe18e6ea..8c1259cbe23f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; +package org.springframework.boot.metrics.autoconfigure.export.prometheus; import java.net.MalformedURLException; import java.net.URI; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesConfigAdapterTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesConfigAdapterTests.java index 3e4e7d57dee5..4c5502cf181f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; +package org.springframework.boot.metrics.autoconfigure.export.prometheus; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesTests.java index 9421c701edd2..422d319cfeaa 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/prometheus/PrometheusPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; +package org.springframework.boot.metrics.autoconfigure.export.prometheus; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryPropertiesTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryPropertiesTests.java index 4fb07fd862ae..3cf0e24ae9eb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/PushRegistryPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; +package org.springframework.boot.metrics.autoconfigure.export.properties; import io.micrometer.core.instrument.push.PushRegistryConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesConfigAdapterTests.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesConfigAdapterTests.java index 79623253ab9b..71bd33ff28cf 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesConfigAdapterTests.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; +package org.springframework.boot.metrics.autoconfigure.export.properties; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryPropertiesConfigAdapterTests; /** * Base test for {@link StepRegistryPropertiesConfigAdapter} implementations. diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesTests.java index d1c41b9d1c34..94bcbd0397ff 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/StepRegistryPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/properties/StepRegistryPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.properties; +package org.springframework.boot.metrics.autoconfigure.export.properties; import io.micrometer.core.instrument.step.StepRegistryConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleMetricsExportAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleMetricsExportAutoConfigurationTests.java index 80bfbddc7005..0fb1de4434e1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimpleMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.simple; +package org.springframework.boot.metrics.autoconfigure.export.simple; import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.MeterRegistry; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesConfigAdapterTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesConfigAdapterTests.java index f61d71cd2dc5..fa98aa7f2a59 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.simple; +package org.springframework.boot.metrics.autoconfigure.export.simple; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesTests.java index e96683a8ca81..2d46c2dae057 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplePropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/simple/SimplePropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.simple; +package org.springframework.boot.metrics.autoconfigure.export.simple; import io.micrometer.core.instrument.simple.SimpleConfig; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverMetricsExportAutoConfigurationTests.java index d9275b8ca7f0..7204d579a865 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver; +package org.springframework.boot.metrics.autoconfigure.export.stackdriver; import io.micrometer.core.instrument.Clock; import io.micrometer.stackdriver.StackdriverConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesConfigAdapterTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesConfigAdapterTests.java index 7b9298dc0189..78bbec34b68c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver; +package org.springframework.boot.metrics.autoconfigure.export.stackdriver; import java.util.HashMap; import java.util.Map; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesTests.java index 916d559d7809..a6a5a5885e23 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/stackdriver/StackdriverPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/stackdriver/StackdriverPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver; +package org.springframework.boot.metrics.autoconfigure.export.stackdriver; import io.micrometer.stackdriver.StackdriverConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; +import org.springframework.boot.metrics.autoconfigure.export.properties.StepRegistryPropertiesTests; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdMetricsExportAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdMetricsExportAutoConfigurationTests.java index 27274e744d96..a09822dc7347 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdMetricsExportAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; +package org.springframework.boot.metrics.autoconfigure.export.statsd; import io.micrometer.core.instrument.Clock; import io.micrometer.statsd.StatsdConfig; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesConfigAdapterTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesConfigAdapterTests.java index d7d2c51e0f43..4f91253d8714 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesConfigAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; +package org.springframework.boot.metrics.autoconfigure.export.statsd; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesTests.java index 9dd78d0aa270..c02c616dc19d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/export/statsd/StatsdPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; +package org.springframework.boot.metrics.autoconfigure.export.statsd; import io.micrometer.statsd.StatsdConfig; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/jvm/JvmMetricsAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/jvm/JvmMetricsAutoConfigurationTests.java index e681082c7f16..8294d7d1b25a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/jvm/JvmMetricsAutoConfigurationTests.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.jvm; +import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; import io.micrometer.core.instrument.binder.jvm.JvmCompilationMetrics; @@ -24,6 +25,7 @@ import io.micrometer.core.instrument.binder.jvm.JvmInfoMetrics; import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.JRE; @@ -33,7 +35,6 @@ import org.springframework.aot.hint.TypeReference; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.beans.BeanUtils; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -53,7 +54,8 @@ */ class JvmMetricsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(MeterRegistry.class, () -> new SimpleMeterRegistry()) .withConfiguration(AutoConfigurations.of(JvmMetricsAutoConfiguration.class)); @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java index 6f0ed3590eed..a6ae14d9d0c5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.logging.log4j2; import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.apache.logging.log4j.LogManager; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.logging.ConfigureClasspathToPreferLog4j2; @@ -37,7 +37,8 @@ @ConfigureClasspathToPreferLog4j2 class Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) .withConfiguration(AutoConfigurations.of(Log4J2MetricsAutoConfiguration.class)); @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java index 76d8981593ee..88157a732301 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/log4j2/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.logging.log4j2; import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.apache.logging.log4j.LogManager; import org.apache.logging.slf4j.SLF4JLoggerContext; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -34,7 +34,8 @@ */ class Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) .withConfiguration(AutoConfigurations.of(Log4J2MetricsAutoConfiguration.class)); @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfigurationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfigurationTests.java index 5e706b2ca8a7..956e0a46e47a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfigurationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.logging.logback; import io.micrometer.core.instrument.binder.logging.LogbackMetrics; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -35,7 +35,8 @@ */ class LogbackMetricsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) .withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)); @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationWithLog4j2AndLogbackTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfigurationWithLog4j2AndLogbackTests.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationWithLog4j2AndLogbackTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfigurationWithLog4j2AndLogbackTests.java index aa4689820ba6..9bc08ddd4092 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationWithLog4j2AndLogbackTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/logging/logback/LogbackMetricsAutoConfigurationWithLog4j2AndLogbackTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.logging.logback; import io.micrometer.core.instrument.binder.logging.LogbackMetrics; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.logging.ConfigureClasspathToPreferLog4j2; @@ -36,8 +36,8 @@ class LogbackMetricsAutoConfigurationWithLog4j2AndLogbackTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, - SimpleMetricsExportAutoConfiguration.class, LogbackMetricsAutoConfiguration.class)); + .withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) + .withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)); @Test void doesNotConfigureLogbackMetrics() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslMeterBinderTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMeterBinderTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslMeterBinderTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMeterBinderTests.java index a029955949ec..9a8dadd494da 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/ssl/SslMeterBinderTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMeterBinderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.ssl; +package org.springframework.boot.metrics.autoconfigure.ssl; import java.time.Clock; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMetricsAutoConfigurationTests.java new file mode 100644 index 000000000000..35d7b4b22ade --- /dev/null +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/ssl/SslMetricsAutoConfigurationTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.metrics.autoconfigure.ssl; + +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SslMetricsAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class SslMetricsAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(SslMetricsAutoConfiguration.class)); + + @Test + void shouldSupplyMeterBinder() { + this.contextRunner.withConfiguration(AutoConfigurations.of(SslAutoConfiguration.class)) + .withBean(SimpleMeterRegistry.class) + .run((context) -> assertThat(context).hasSingleBean(SslMeterBinder.class)); + } + + @Test + void shouldBackOffIfSslBundlesIsMissing() { + this.contextRunner.withBean(SimpleMeterRegistry.class) + .run((context) -> assertThat(context).doesNotHaveBean(SslMeterBinder.class)); + } + + @Test + void shouldBackOffIfMeterRegistryIsMissing() { + this.contextRunner.withConfiguration(AutoConfigurations.of(SslAutoConfiguration.class)) + .run((context) -> assertThat(context).doesNotHaveBean(SslMeterBinder.class)); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/StartupTimeMetricsListenerAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/startup/StartupTimeMetricsListenerAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/StartupTimeMetricsListenerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/startup/StartupTimeMetricsListenerAutoConfigurationTests.java index d6a96b255931..437942ac2c07 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/startup/StartupTimeMetricsListenerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/startup/StartupTimeMetricsListenerAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.startup; +package org.springframework.boot.metrics.autoconfigure.startup; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -24,11 +24,11 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.SpringApplication; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.metrics.startup.StartupTimeMetricsListener; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.startup.StartupTimeMetricsListener; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -42,8 +42,11 @@ */ class StartupTimeMetricsListenerAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(StartupTimeMetricsListenerAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class) + .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, + StartupTimeMetricsListenerAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=false"); @Test void startupTimeMetricsAreRecorded() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/system/SystemMetricsAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/system/SystemMetricsAutoConfigurationTests.java index ca590cd73145..be168cf587e0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/system/SystemMetricsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics; +package org.springframework.boot.metrics.autoconfigure.system; import java.io.File; import java.util.Arrays; @@ -24,11 +24,11 @@ import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics; import io.micrometer.core.instrument.binder.system.ProcessorMetrics; import io.micrometer.core.instrument.binder.system.UptimeMetrics; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.metrics.system.DiskSpaceMetricsBinder; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.metrics.system.DiskSpaceMetricsBinder; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -44,7 +44,8 @@ */ class SystemMetricsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class, SimpleMeterRegistry::new) .withConfiguration(AutoConfigurations.of(SystemMetricsAutoConfiguration.class)); @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/task/TaskExecutorMetricsAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/task/TaskExecutorMetricsAutoConfigurationTests.java index b40217d75413..2dccbe6995d3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/autoconfigure/task/TaskExecutorMetricsAutoConfigurationTests.java @@ -14,20 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.task; +package org.springframework.boot.metrics.autoconfigure.task; import java.util.Collection; import io.micrometer.core.instrument.FunctionCounter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.search.MeterNotFoundException; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -48,8 +49,11 @@ */ class TaskExecutorMetricsAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(TaskExecutorMetricsAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(SimpleMeterRegistry.class) + .withConfiguration( + AutoConfigurations.of(TaskExecutorMetricsAutoConfiguration.class, MetricsAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=false"); @Test void taskExecutorUsingAutoConfigurationIsInstrumented() { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/startup/StartupTimeMetricsListenerTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/startup/StartupTimeMetricsListenerTests.java index 36b6cdfb7759..467ea16cf976 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/startup/StartupTimeMetricsListenerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.startup; +package org.springframework.boot.metrics.startup; import java.time.Duration; import java.util.concurrent.TimeUnit; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinderTests.java b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/system/DiskSpaceMetricsBinderTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinderTests.java rename to spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/system/DiskSpaceMetricsBinderTests.java index 11a049d51982..4a341bc97bec 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinderTests.java +++ b/spring-boot-project/spring-boot-metrics/src/test/java/org/springframework/boot/metrics/system/DiskSpaceMetricsBinderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.system; +package org.springframework.boot.metrics.system; import java.io.File; import java.util.Arrays; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/certificates/chains.p12 b/spring-boot-project/spring-boot-metrics/src/test/resources/certificates/chains.p12 similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/resources/certificates/chains.p12 rename to spring-boot-project/spring-boot-metrics/src/test/resources/certificates/chains.p12 diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/AbstractPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/AbstractPropertiesConfigAdapterTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/AbstractPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/AbstractPropertiesConfigAdapterTests.java index 4828d0b427cd..ac5ab005da2c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/AbstractPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/AbstractPropertiesConfigAdapterTests.java @@ -25,6 +25,7 @@ import io.micrometer.core.instrument.config.validate.Validated; import org.junit.jupiter.api.Test; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; import org.springframework.core.annotation.AnnotatedElementUtils; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-metrics/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java rename to spring-boot-project/spring-boot-metrics/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java index 17af3d3d3cc3..b285aa50cda0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-metrics/src/testFixtures/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java @@ -20,6 +20,10 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.metrics.autoconfigure.export.properties.PropertiesConfigAdapter; +import org.springframework.boot.metrics.autoconfigure.export.properties.PushRegistryProperties; +import org.springframework.boot.metrics.autoconfigure.export.properties.PushRegistryPropertiesConfigAdapter; + import static org.assertj.core.api.Assertions.assertThat; /** diff --git a/spring-boot-project/spring-boot-mongodb/build.gradle b/spring-boot-project/spring-boot-mongodb/build.gradle new file mode 100644 index 000000000000..b46001bc317f --- /dev/null +++ b/spring-boot-project/spring-boot-mongodb/build.gradle @@ -0,0 +1,52 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot MongoDB" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-reactor")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("io.netty:netty-transport") + optional("org.mongodb:mongodb-driver-reactivestreams") + optional("org.mongodb:mongodb-driver-sync") + optional("org.testcontainers:mongodb") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-testcontainers"))) + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("io.netty:netty-handler") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-mongodb/src/dockerTest/java/org/springframework/boot/mongodb/docker/compose/MongoDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-mongodb/src/dockerTest/java/org/springframework/boot/mongodb/docker/compose/MongoDockerComposeConnectionDetailsFactoryIntegrationTests.java index 1bf53e3915f0..504b0f45eb28 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/dockerTest/java/org/springframework/boot/mongodb/docker/compose/MongoDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mongo; +package org.springframework.boot.mongodb.docker.compose; import com.mongodb.ConnectionString; import org.junit.jupiter.api.condition.OS; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.junit.DisabledOnOs; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mongo/mongo-bitnami-compose.yaml b/spring-boot-project/spring-boot-mongodb/src/dockerTest/resources/org/springframework/boot/mongodb/docker/compose/mongo-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mongo/mongo-bitnami-compose.yaml rename to spring-boot-project/spring-boot-mongodb/src/dockerTest/resources/org/springframework/boot/mongodb/docker/compose/mongo-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mongo/mongo-compose.yaml b/spring-boot-project/spring-boot-mongodb/src/dockerTest/resources/org/springframework/boot/mongodb/docker/compose/mongo-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/mongo/mongo-compose.yaml rename to spring-boot-project/spring-boot-mongodb/src/dockerTest/resources/org/springframework/boot/mongodb/docker/compose/mongo-compose.yaml diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoAutoConfiguration.java index f5dd9b226dd0..ac195645517f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import com.mongodb.MongoClientSettings; import com.mongodb.client.MongoClient; @@ -38,7 +38,7 @@ * @author Mark Paluch * @author Stephane Nicoll * @author Scott Frederick - * @since 1.0.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(MongoClient.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactory.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactory.java index efdc33cb42ad..8f6ae671d4a1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.List; @@ -33,7 +33,7 @@ * @author Nasko Vasilev * @author Mark Paluch * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ public class MongoClientFactory extends MongoClientFactorySupport { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupport.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupport.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupport.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupport.java index 8c86c8c7c644..a96c205a8372 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupport.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupport.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.Collections; import java.util.List; @@ -30,7 +30,7 @@ * @param the mongo client type * @author Christoph Strobl * @author Scott Frederick - * @since 2.3.0 + * @since 4.0.0 */ public abstract class MongoClientFactorySupport { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientSettingsBuilderCustomizer.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientSettingsBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientSettingsBuilderCustomizer.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientSettingsBuilderCustomizer.java index 9c593998b679..46dc0634d6b7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientSettingsBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientSettingsBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import com.mongodb.MongoClientSettings.Builder; @@ -24,7 +24,7 @@ * MongoClientSettings.Builder} whilst retaining default auto-configuration. * * @author Mark Paluch - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface MongoClientSettingsBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoConnectionDetails.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoConnectionDetails.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoConnectionDetails.java index 23880565740a..1f8e45e2ce9b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoConnectionDetails.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import com.mongodb.ConnectionString; @@ -27,7 +27,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface MongoConnectionDetails extends ConnectionDetails { @@ -40,7 +40,6 @@ public interface MongoConnectionDetails extends ConnectionDetails { /** * SSL bundle to use. * @return the SSL bundle to use - * @since 3.5.0 */ default SslBundle getSslBundle() { return null; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoProperties.java index 2603ae7649e6..0c7c038b73e6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.List; @@ -36,7 +36,7 @@ * @author Mark Paluch * @author Artsiom Yudovin * @author Safeer Ansari - * @since 1.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.data.mongodb") public class MongoProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfiguration.java index ae1dccc76140..1728ad81b18d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import com.mongodb.MongoClientSettings; import com.mongodb.MongoClientSettings.Builder; @@ -45,7 +45,7 @@ * @author Mark Paluch * @author Stephane Nicoll * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ MongoClient.class, Flux.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetails.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetails.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetails.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetails.java index 5d7661e09854..fe8ea936158d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetails.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -23,7 +23,7 @@ import com.mongodb.ConnectionString; -import org.springframework.boot.autoconfigure.mongo.MongoProperties.Ssl; +import org.springframework.boot.mongodb.autoconfigure.MongoProperties.Ssl; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; import org.springframework.util.Assert; @@ -36,7 +36,7 @@ * @author Andy Wilkinson * @author Phillip Webb * @author Scott Frederick - * @since 3.1.0 + * @since 4.0.0 */ public class PropertiesMongoConnectionDetails implements MongoConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/ReactiveMongoClientFactory.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/ReactiveMongoClientFactory.java index a852b86c6882..e60c5f5cb521 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/ReactiveMongoClientFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.List; @@ -27,7 +27,7 @@ * @author Mark Paluch * @author Stephane Nicoll * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ public class ReactiveMongoClientFactory extends MongoClientFactorySupport { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/StandardMongoClientSettingsBuilderCustomizer.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/StandardMongoClientSettingsBuilderCustomizer.java similarity index 79% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/StandardMongoClientSettingsBuilderCustomizer.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/StandardMongoClientSettingsBuilderCustomizer.java index 975666274c19..05fe31ed3384 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/StandardMongoClientSettingsBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/StandardMongoClientSettingsBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; @@ -33,7 +33,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public class StandardMongoClientSettingsBuilderCustomizer implements MongoClientSettingsBuilderCustomizer, Ordered { @@ -49,25 +49,6 @@ public class StandardMongoClientSettingsBuilderCustomizer implements MongoClient private int order = 0; - /** - * Create a new instance. - * @param connectionString the connection string - * @param uuidRepresentation the uuid representation - * @param ssl the ssl properties - * @param sslBundles the ssl bundles - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #StandardMongoClientSettingsBuilderCustomizer(MongoConnectionDetails, UuidRepresentation)} - */ - @Deprecated(forRemoval = true, since = "3.5.0") - public StandardMongoClientSettingsBuilderCustomizer(ConnectionString connectionString, - UuidRepresentation uuidRepresentation, MongoProperties.Ssl ssl, SslBundles sslBundles) { - this.connectionDetails = null; - this.connectionString = connectionString; - this.uuidRepresentation = uuidRepresentation; - this.ssl = ssl; - this.sslBundles = sslBundles; - } - public StandardMongoClientSettingsBuilderCustomizer(MongoConnectionDetails connectionDetails, UuidRepresentation uuidRepresentation) { this.connectionString = null; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/MongoMetricsAutoConfiguration.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/MongoMetricsAutoConfiguration.java index 84dbc2f8a35e..40746aa1d27a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/MongoMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.mongo; +package org.springframework.boot.mongodb.autoconfigure.metrics; import com.mongodb.MongoClientSettings; import io.micrometer.core.instrument.MeterRegistry; @@ -25,16 +25,14 @@ import io.micrometer.core.instrument.binder.mongodb.MongoMetricsCommandListener; import io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoClientSettingsBuilderCustomizer; import org.springframework.context.annotation.Bean; /** @@ -42,11 +40,11 @@ * * @author Chris Bono * @author Jonatan Ivanov - * @since 2.5.0 + * @since 4.0.0 */ @AutoConfiguration(before = MongoAutoConfiguration.class, - after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) -@ConditionalOnClass(MongoClientSettings.class) + afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") +@ConditionalOnClass({ MongoClientSettings.class, MeterRegistry.class }) @ConditionalOnBean(MeterRegistry.class) public class MongoMetricsAutoConfiguration { diff --git a/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..e8e3d155c131 --- /dev/null +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for MongoDB metrics. + */ +package org.springframework.boot.mongodb.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/package-info.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/package-info.java new file mode 100644 index 000000000000..222728ddd49c --- /dev/null +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for MongoDB. + */ +package org.springframework.boot.mongodb.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoDockerComposeConnectionDetailsFactory.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoDockerComposeConnectionDetailsFactory.java index 7a97ba1c0c58..30800f63da2c 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoDockerComposeConnectionDetailsFactory.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mongo; +package org.springframework.boot.mongodb.docker.compose; import com.mongodb.ConnectionString; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link MongoConnectionDetails} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoEnvironment.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironment.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoEnvironment.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironment.java index 8219a37984ea..bb7739b9f800 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoEnvironment.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mongo; +package org.springframework.boot.mongodb.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/package-info.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/package-info.java new file mode 100644 index 000000000000..f6d86456114d --- /dev/null +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose MongoDB service connections. + */ +package org.springframework.boot.mongodb.docker.compose; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/MongoContainerConnectionDetailsFactory.java similarity index 93% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/MongoContainerConnectionDetailsFactory.java index bfec10ea5db5..828f28da81c6 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/MongoContainerConnectionDetailsFactory.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.mongo; +package org.springframework.boot.mongodb.testcontainers; import com.mongodb.ConnectionString; import org.testcontainers.containers.MongoDBContainer; -import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; +import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; diff --git a/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/package-info.java b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/package-info.java new file mode 100644 index 000000000000..96e6d12f118c --- /dev/null +++ b/spring-boot-project/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers MongoDB service connections. + */ +package org.springframework.boot.mongodb.testcontainers; diff --git a/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..17ab049e80b1 --- /dev/null +++ b/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,33 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.metrics.mongo.command.enabled", + "description": "Whether to enable Mongo client command metrics.", + "defaultValue": true + }, + { + "name": "management.metrics.mongo.connectionpool.enabled", + "description": "Whether to enable Mongo connection pool metrics.", + "defaultValue": true + }, + { + "name": "spring.data.mongodb.grid-fs-database", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.data.mongodb.gridfs.database", + "level": "error" + } + }, + { + "name": "spring.data.mongodb.repositories.type", + "type": "org.springframework.boot.autoconfigure.data.RepositoryType", + "description": "Type of Mongo repositories to enable.", + "defaultValue": "auto" + }, + { + "name": "spring.data.mongodb.uri", + "defaultValue": "mongodb://localhost/test" + } + ] +} diff --git a/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..a4e490f7958b --- /dev/null +++ b/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.mongodb.docker.compose.MongoDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.mongodb.testcontainers.MongoContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..4038ff363e19 --- /dev/null +++ b/spring-boot-project/spring-boot-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration +org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration +org.springframework.boot.mongodb.autoconfigure.metrics.MongoMetricsAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoAutoConfigurationTests.java index 66afbc9fb1f2..a21cdeb908e2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.concurrent.TimeUnit; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupportTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupportTests.java index 3a66cc836306..8bc8a2872576 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupportTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.Arrays; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactoryTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactoryTests.java index 81242a70fc8d..7574f1ad5b89 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfigurationTests.java index 4a5efc5f2438..e1729faee75a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetailsTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetailsTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetailsTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetailsTests.java index 7a57ba89fc14..ad980f32f6ad 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetailsTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetailsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/ReactiveMongoClientFactoryTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/ReactiveMongoClientFactoryTests.java index 756ee87ca6e5..373d70ab43ed 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/ReactiveMongoClientFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mongo; +package org.springframework.boot.mongodb.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/metrics/MongoMetricsAutoConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/metrics/MongoMetricsAutoConfigurationTests.java index 4f3d056510b5..57848a1bc678 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/autoconfigure/metrics/MongoMetricsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.mongo; +package org.springframework.boot.mongodb.autoconfigure.metrics; import java.util.List; @@ -29,12 +29,12 @@ import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; import io.micrometer.core.instrument.binder.mongodb.MongoMetricsCommandListener; import io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -57,7 +57,7 @@ class MongoMetricsAutoConfigurationTests { @Test void whenThereIsAMeterRegistryThenMetricsCommandListenerIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .run((context) -> { assertThat(context).hasSingleBean(MongoMetricsCommandListener.class); @@ -72,7 +72,7 @@ void whenThereIsAMeterRegistryThenMetricsCommandListenerIsAdded() { @Test void whenThereIsAMeterRegistryThenMetricsConnectionPoolListenerIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .run((context) -> { assertThat(context).hasSingleBean(MongoMetricsConnectionPoolListener.class); @@ -98,7 +98,7 @@ void whenThereIsNoMeterRegistryThenNoMetricsConnectionPoolListenerIsAdded() { @Test void whenThereIsACustomMetricsCommandTagsProviderItIsUsed() { final MongoCommandTagsProvider customTagsProvider = mock(MongoCommandTagsProvider.class); - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .withBean("customMongoCommandTagsProvider", MongoCommandTagsProvider.class, () -> customTagsProvider) .run((context) -> assertThat(getMongoCommandTagsProviderUsedToConstructListener(context)) @@ -108,7 +108,7 @@ void whenThereIsACustomMetricsCommandTagsProviderItIsUsed() { @Test void whenThereIsACustomMetricsConnectionPoolTagsProviderItIsUsed() { final MongoConnectionPoolTagsProvider customTagsProvider = mock(MongoConnectionPoolTagsProvider.class); - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .withBean("customMongoConnectionPoolTagsProvider", MongoConnectionPoolTagsProvider.class, () -> customTagsProvider) @@ -118,7 +118,7 @@ void whenThereIsACustomMetricsConnectionPoolTagsProviderItIsUsed() { @Test void whenThereIsNoMongoClientSettingsOnClasspathThenNoMetricsCommandListenerIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .withClassLoader(new FilteredClassLoader(MongoClientSettings.class)) .run(assertThatMetricsCommandListenerNotAdded()); @@ -126,7 +126,7 @@ void whenThereIsNoMongoClientSettingsOnClasspathThenNoMetricsCommandListenerIsAd @Test void whenThereIsNoMongoClientSettingsOnClasspathThenNoMetricsConnectionPoolListenerIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .withClassLoader(new FilteredClassLoader(MongoClientSettings.class)) .run(assertThatMetricsConnectionPoolListenerNotAdded()); @@ -134,7 +134,7 @@ void whenThereIsNoMongoClientSettingsOnClasspathThenNoMetricsConnectionPoolListe @Test void whenThereIsNoMongoMetricsCommandListenerOnClasspathThenNoMetricsCommandListenerIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .withClassLoader(new FilteredClassLoader(MongoMetricsCommandListener.class)) .run(assertThatMetricsCommandListenerNotAdded()); @@ -142,7 +142,7 @@ void whenThereIsNoMongoMetricsCommandListenerOnClasspathThenNoMetricsCommandList @Test void whenThereIsNoMongoMetricsConnectionPoolListenerOnClasspathThenNoMetricsConnectionPoolListenerIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .withClassLoader(new FilteredClassLoader(MongoMetricsConnectionPoolListener.class)) .run(assertThatMetricsConnectionPoolListenerNotAdded()); @@ -150,7 +150,7 @@ void whenThereIsNoMongoMetricsConnectionPoolListenerOnClasspathThenNoMetricsConn @Test void whenMetricsCommandListenerEnabledPropertyFalseThenNoMetricsCommandListenerIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .withPropertyValues("management.metrics.mongo.command.enabled:false") .run(assertThatMetricsCommandListenerNotAdded()); @@ -158,7 +158,7 @@ void whenMetricsCommandListenerEnabledPropertyFalseThenNoMetricsCommandListenerI @Test void whenMetricsConnectionPoolListenerEnabledPropertyFalseThenNoMetricsConnectionPoolListenerIsAdded() { - this.contextRunner.with(MetricsRun.simple()) + this.contextRunner.withBean(SimpleMeterRegistry.class) .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class)) .withPropertyValues("management.metrics.mongo.connectionpool.enabled:false") .run(assertThatMetricsConnectionPoolListenerNotAdded()); diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoEnvironmentTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironmentTests.java similarity index 97% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoEnvironmentTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironmentTests.java index dec466b3626a..68c47e59a6e5 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/mongo/MongoEnvironmentTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mongo; +package org.springframework.boot.mongodb.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/testcontainers/MongoContainerConnectionDetailsFactoryTests.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/testcontainers/MongoContainerConnectionDetailsFactoryTests.java index d33cbc9ac222..ed161ac59406 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-mongodb/src/test/java/org/springframework/boot/mongodb/testcontainers/MongoContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.mongo; +package org.springframework.boot.mongodb.testcontainers; import com.mongodb.ConnectionString; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mongo/test.jks b/spring-boot-project/spring-boot-mongodb/src/test/resources/org/springframework/boot/mongodb/autoconfigure/test.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mongo/test.jks rename to spring-boot-project/spring-boot-mongodb/src/test/resources/org/springframework/boot/mongodb/autoconfigure/test.jks diff --git a/spring-boot-project/spring-boot-mustache/build.gradle b/spring-boot-project/spring-boot-mustache/build.gradle new file mode 100644 index 000000000000..b0db99cf3812 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/build.gradle @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Mustache" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("com.samskivert:jmustache") + api("org.springframework:spring-web") + + optional("jakarta.servlet:jakarta.servlet-api") + optional("org.springframework:spring-webmvc") + optional("org.springframework:spring-webflux") + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) + testImplementation(project(":spring-boot-project:spring-boot-restclient")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) + testImplementation(project(":spring-boot-project:spring-boot-web-server-test")) + testImplementation("io.projectreactor:reactor-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfiguration.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfiguration.java rename to spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfiguration.java index b287e42d620c..3510d75c62ea 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfiguration.java +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Mustache.TemplateLoader; @@ -36,7 +36,7 @@ * * @author Dave Syer * @author Brian Clozel - * @since 1.2.2 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(Mustache.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheProperties.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheProperties.java rename to spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheProperties.java index 7b5a452c5cbf..a79a50c76b48 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheProperties.java +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -31,7 +31,7 @@ * {@link ConfigurationProperties @ConfigurationProperties} for Mustache. * * @author Dave Syer - * @since 1.2.2 + * @since 4.0.0 */ @ConfigurationProperties("spring.mustache") public class MustacheProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheReactiveWebConfiguration.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheReactiveWebConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheReactiveWebConfiguration.java rename to spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheReactiveWebConfiguration.java index bb0a7c26b59a..592f77338ed9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheReactiveWebConfiguration.java +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheReactiveWebConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import com.samskivert.mustache.Mustache.Compiler; @@ -23,7 +23,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.reactive.result.view.MustacheViewResolver; +import org.springframework.boot.mustache.reactive.view.MustacheViewResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheResourceTemplateLoader.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheResourceTemplateLoader.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheResourceTemplateLoader.java rename to spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheResourceTemplateLoader.java index e2ef5218fe9d..b388ff0b33c3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheResourceTemplateLoader.java +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheResourceTemplateLoader.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import java.io.InputStreamReader; import java.io.Reader; @@ -35,7 +35,7 @@ * partials (i.e. tiles-like features). * * @author Dave Syer - * @since 1.2.2 + * @since 4.0.0 * @see Mustache * @see Resource */ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheServletWebConfiguration.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheServletWebConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheServletWebConfiguration.java rename to spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheServletWebConfiguration.java index 5f5ffa8bf84a..531bc803eeab 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheServletWebConfiguration.java +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheServletWebConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import com.samskivert.mustache.Mustache.Compiler; @@ -23,7 +23,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.web.servlet.view.MustacheViewResolver; +import org.springframework.boot.mustache.servlet.view.MustacheViewResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheTemplateAvailabilityProvider.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheTemplateAvailabilityProvider.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheTemplateAvailabilityProvider.java rename to spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheTemplateAvailabilityProvider.java index 9f266f4bad19..1f596863e0b8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheTemplateAvailabilityProvider.java +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/MustacheTemplateAvailabilityProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; import org.springframework.core.env.Environment; @@ -27,7 +27,7 @@ * * @author Dave Syer * @author Madhura Bhave - * @since 1.2.2 + * @since 4.0.0 */ public class MustacheTemplateAvailabilityProvider implements TemplateAvailabilityProvider { diff --git a/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/package-info.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/package-info.java new file mode 100644 index 000000000000..26948cd6664f --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Mustache. + */ +package org.springframework.boot.mustache.autoconfigure; diff --git a/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/MustacheView.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/MustacheView.java new file mode 100644 index 000000000000..e2d789bede7c --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/MustacheView.java @@ -0,0 +1,122 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.reactive.view; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +import com.samskivert.mustache.Mustache.Compiler; +import com.samskivert.mustache.Template; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.core.io.Resource; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.result.view.AbstractUrlBasedView; +import org.springframework.web.reactive.result.view.View; +import org.springframework.web.server.ServerWebExchange; + +/** + * Spring WebFlux {@link View} using the Mustache template engine. + * + * @author Brian Clozel + * @since 4.0.0 + */ +public class MustacheView extends AbstractUrlBasedView { + + private Compiler compiler; + + private String charset; + + /** + * Set the JMustache compiler to be used by this view. Typically this property is not + * set directly. Instead a single {@link Compiler} is expected in the Spring + * application context which is used to compile Mustache templates. + * @param compiler the Mustache compiler + */ + public void setCompiler(Compiler compiler) { + this.compiler = compiler; + } + + /** + * Set the charset used for reading Mustache template files. + * @param charset the charset to use for reading template files + */ + public void setCharset(String charset) { + this.charset = charset; + } + + @Override + public boolean checkResourceExists(Locale locale) throws Exception { + return resolveResource() != null; + } + + @Override + protected Mono renderInternal(Map model, MediaType contentType, ServerWebExchange exchange) { + Resource resource = resolveResource(); + if (resource == null) { + return Mono + .error(new IllegalStateException("Could not find Mustache template with URL [" + getUrl() + "]")); + } + DataBuffer dataBuffer = exchange.getResponse() + .bufferFactory() + .allocateBuffer(DefaultDataBufferFactory.DEFAULT_INITIAL_CAPACITY); + try (Reader reader = getReader(resource)) { + Template template = this.compiler.compile(reader); + Charset charset = getCharset(contentType).orElseGet(this::getDefaultCharset); + try (Writer writer = new OutputStreamWriter(dataBuffer.asOutputStream(), charset)) { + template.execute(model, writer); + writer.flush(); + } + } + catch (Exception ex) { + DataBufferUtils.release(dataBuffer); + return Mono.error(ex); + } + return exchange.getResponse().writeWith(Flux.just(dataBuffer)); + } + + private Resource resolveResource() { + Resource resource = getApplicationContext().getResource(getUrl()); + if (resource == null || !resource.exists()) { + return null; + } + return resource; + } + + private Reader getReader(Resource resource) throws IOException { + if (this.charset != null) { + return new InputStreamReader(resource.getInputStream(), this.charset); + } + return new InputStreamReader(resource.getInputStream()); + } + + private Optional getCharset(MediaType mediaType) { + return Optional.ofNullable((mediaType != null) ? mediaType.getCharset() : null); + } + +} diff --git a/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/MustacheViewResolver.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/MustacheViewResolver.java new file mode 100644 index 000000000000..041e38027d98 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/MustacheViewResolver.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.reactive.view; + +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Mustache.Compiler; + +import org.springframework.web.reactive.result.view.AbstractUrlBasedView; +import org.springframework.web.reactive.result.view.UrlBasedViewResolver; +import org.springframework.web.reactive.result.view.ViewResolver; + +/** + * Spring WebFlux {@link ViewResolver} for Mustache. + * + * @author Brian Clozel + * @author Marten Deinum + * @since 4.0.0 + */ +public class MustacheViewResolver extends UrlBasedViewResolver { + + private final Compiler compiler; + + private String charset; + + /** + * Create a {@code MustacheViewResolver} backed by a default instance of a + * {@link Compiler}. + */ + public MustacheViewResolver() { + this.compiler = Mustache.compiler(); + setViewClass(requiredViewClass()); + } + + /** + * Create a {@code MustacheViewResolver} backed by a custom instance of a + * {@link Compiler}. + * @param compiler the Mustache compiler used to compile templates + */ + public MustacheViewResolver(Compiler compiler) { + this.compiler = compiler; + setViewClass(requiredViewClass()); + } + + /** + * Set the charset. + * @param charset the charset + */ + public void setCharset(String charset) { + this.charset = charset; + } + + @Override + protected Class requiredViewClass() { + return MustacheView.class; + } + + @Override + protected AbstractUrlBasedView createView(String viewName) { + MustacheView view = (MustacheView) super.createView(viewName); + view.setCompiler(this.compiler); + view.setCharset(this.charset); + return view; + } + + @Override + protected AbstractUrlBasedView instantiateView() { + return (getViewClass() == MustacheView.class) ? new MustacheView() : super.instantiateView(); + } + +} diff --git a/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/package-info.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/package-info.java new file mode 100644 index 000000000000..6ba6c1162dbe --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/reactive/view/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Additional {@link org.springframework.web.reactive.result.view.View Views} for use with + * WebFlux. + */ +package org.springframework.boot.mustache.reactive.view; diff --git a/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/MustacheView.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/MustacheView.java new file mode 100644 index 000000000000..7fad21240402 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/MustacheView.java @@ -0,0 +1,96 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.servlet.view; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Locale; +import java.util.Map; + +import com.samskivert.mustache.Mustache.Compiler; +import com.samskivert.mustache.Template; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.springframework.core.io.Resource; +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.view.AbstractTemplateView; + +/** + * Spring MVC {@link View} using the Mustache template engine. + * + * @author Brian Clozel + * @author Dave Syer + * @author Phillip Webb + * @since 4.0.0 + */ +public class MustacheView extends AbstractTemplateView { + + private Compiler compiler; + + private String charset; + + /** + * Set the Mustache compiler to be used by this view. + *

+ * Typically this property is not set directly. Instead a single {@link Compiler} is + * expected in the Spring application context which is used to compile Mustache + * templates. + * @param compiler the Mustache compiler + */ + public void setCompiler(Compiler compiler) { + this.compiler = compiler; + } + + /** + * Set the charset used for reading Mustache template files. + * @param charset the charset to use for reading template files + */ + public void setCharset(String charset) { + this.charset = charset; + } + + @Override + public boolean checkResource(Locale locale) throws Exception { + Resource resource = getApplicationContext().getResource(getUrl()); + return (resource != null && resource.exists()); + } + + @Override + protected void renderMergedTemplateModel(Map model, HttpServletRequest request, + HttpServletResponse response) throws Exception { + Template template = createTemplate(getApplicationContext().getResource(getUrl())); + if (template != null) { + template.execute(model, response.getWriter()); + } + } + + private Template createTemplate(Resource resource) throws IOException { + try (Reader reader = getReader(resource)) { + return this.compiler.compile(reader); + } + } + + private Reader getReader(Resource resource) throws IOException { + if (this.charset != null) { + return new InputStreamReader(resource.getInputStream(), this.charset); + } + return new InputStreamReader(resource.getInputStream()); + } + +} diff --git a/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/MustacheViewResolver.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/MustacheViewResolver.java new file mode 100644 index 000000000000..cbdf9586e1a2 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/MustacheViewResolver.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.servlet.view; + +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Mustache.Compiler; + +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.view.AbstractTemplateViewResolver; +import org.springframework.web.servlet.view.AbstractUrlBasedView; + +/** + * Spring MVC {@link ViewResolver} for Mustache. + * + * @author Brian Clozel + * @since 4.0.0 + */ +public class MustacheViewResolver extends AbstractTemplateViewResolver { + + private final Mustache.Compiler compiler; + + private String charset; + + /** + * Create a {@code MustacheViewResolver} backed by a default instance of a + * {@link Compiler}. + */ + public MustacheViewResolver() { + this.compiler = Mustache.compiler(); + setViewClass(requiredViewClass()); + } + + /** + * Create a {@code MustacheViewResolver} backed by a custom instance of a + * {@link Compiler}. + * @param compiler the Mustache compiler used to compile templates + */ + public MustacheViewResolver(Compiler compiler) { + this.compiler = compiler; + setViewClass(requiredViewClass()); + } + + @Override + protected Class requiredViewClass() { + return MustacheView.class; + } + + /** + * Set the charset. + * @param charset the charset + */ + public void setCharset(String charset) { + this.charset = charset; + } + + @Override + protected AbstractUrlBasedView buildView(String viewName) throws Exception { + MustacheView view = (MustacheView) super.buildView(viewName); + view.setCompiler(this.compiler); + view.setCharset(this.charset); + return view; + } + + @Override + protected AbstractUrlBasedView instantiateView() { + return (getViewClass() == MustacheView.class) ? new MustacheView() : super.instantiateView(); + } + +} diff --git a/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/package-info.java b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/package-info.java new file mode 100644 index 000000000000..b7c384a20c3e --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/java/org/springframework/boot/mustache/servlet/view/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Additional {@link org.springframework.web.servlet.View Views} for use with Web MVC. + */ +package org.springframework.boot.mustache.servlet.view; diff --git a/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..54227e0b4950 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,21 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.mustache.prefix", + "defaultValue": "classpath:/templates/" + }, + { + "name": "spring.mustache.reactive.media-types", + "defaultValue": "text/html;charset=UTF-8" + }, + { + "name": "spring.mustache.suffix", + "defaultValue": ".mustache" + } + ], + "hints": [], + "ignored": { + "properties": [] + } +} diff --git a/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..da8c7c32fe63 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ +org.springframework.boot.mustache.autoconfigure.MustacheTemplateAvailabilityProvider diff --git a/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..94e421b7af66 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration diff --git a/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationReactiveIntegrationTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationReactiveIntegrationTests.java new file mode 100644 index 000000000000..a5fa34a9187b --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationReactiveIntegrationTests.java @@ -0,0 +1,146 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.autoconfigure; + +import java.util.Date; + +import com.samskivert.mustache.Mustache; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.mustache.reactive.view.MustacheView; +import org.springframework.boot.mustache.reactive.view.MustacheViewResolver; +import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.stereotype.Controller; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.reactive.config.ViewResolverRegistry; +import org.springframework.web.reactive.config.WebFluxConfigurer; +import org.springframework.web.reactive.result.view.ViewResolver; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration Tests for {@link MustacheAutoConfiguration}, {@link MustacheViewResolver} + * and {@link MustacheView}. + * + * @author Brian Clozel + * @author Moritz Halbritter + */ +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=reactive") +class MustacheAutoConfigurationReactiveIntegrationTests { + + @Autowired + private WebTestClient client; + + @Test + void testHomePage() { + String result = this.client.get() + .uri("/") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .returnResult() + .getResponseBody(); + assertThat(result).contains("Hello App").contains("Hello World"); + } + + @Test + void testPartialPage() { + String result = this.client.get() + .uri("/partial") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .returnResult() + .getResponseBody(); + assertThat(result).contains("Hello App").contains("Hello World"); + } + + @Configuration(proxyBeanMethods = false) + @Import({ NettyReactiveWebServerAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) + @Controller + @EnableWebFlux + static class Application { + + @Bean + WebFluxConfigurer registerViewResolvers(ObjectProvider viewResolvers) { + return new WebFluxConfigurer() { + @Override + public void configureViewResolvers(ViewResolverRegistry registry) { + viewResolvers.orderedStream().forEach(registry::viewResolver); + } + }; + } + + @Bean + HttpHandler httpHandler(ApplicationContext context) { + return WebHttpHandlerBuilder.applicationContext(context).build(); + } + + @RequestMapping("/") + String home(Model model) { + model.addAttribute("time", new Date()); + model.addAttribute("message", "Hello World"); + model.addAttribute("title", "Hello App"); + return "home"; + } + + @RequestMapping("/partial") + String layout(Model model) { + model.addAttribute("time", new Date()); + model.addAttribute("message", "Hello World"); + model.addAttribute("title", "Hello App"); + return "partial"; + } + + @Bean + MustacheViewResolver viewResolver() { + Mustache.Compiler compiler = Mustache.compiler() + .withLoader(new MustacheResourceTemplateLoader( + "classpath:/org/springframework/boot/mustache/autoconfigure/", ".html")); + MustacheViewResolver resolver = new MustacheViewResolver(compiler); + resolver.setPrefix("classpath:/org/springframework/boot/mustache/autoconfigure/"); + resolver.setSuffix(".html"); + return resolver; + } + + static void main(String[] args) { + SpringApplication application = new SpringApplication(Application.class); + application.setWebApplicationType(WebApplicationType.REACTIVE); + application.run(args); + } + + } + +} diff --git a/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationServletIntegrationTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationServletIntegrationTests.java new file mode 100644 index 000000000000..86d62fa004db --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationServletIntegrationTests.java @@ -0,0 +1,139 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.autoconfigure; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Template; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.mustache.servlet.view.MustacheView; +import org.springframework.boot.mustache.servlet.view.MustacheViewResolver; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.server.test.client.TestRestTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.stereotype.Controller; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.DispatcherServlet; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration Tests for {@link MustacheAutoConfiguration}, {@link MustacheViewResolver} + * and {@link MustacheView}. + * + * @author Dave Syer + * @author Moritz Halbritter + */ +@DirtiesContext +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +class MustacheAutoConfigurationServletIntegrationTests { + + @Autowired + private ServletWebServerApplicationContext context; + + private int port; + + @BeforeEach + void init() { + this.port = this.context.getWebServer().getPort(); + } + + @Test + void shouldRenderTemplate() { + String source = "Hello {{arg}}!"; + Template tmpl = Mustache.compiler().compile(source); + Map context = new HashMap<>(); + context.put("arg", "world"); + Assertions.assertThat(tmpl.execute(context)).isEqualTo("Hello world!"); + } + + @Test + void testHomePage() { + String body = new TestRestTemplate().getForObject("http://localhost:" + this.port, String.class); + assertThat(body).contains("Hello World"); + } + + @Test + void testPartialPage() { + String body = new TestRestTemplate().getForObject("http://localhost:" + this.port + "/partial", String.class); + assertThat(body).contains("Hello World"); + } + + @Configuration(proxyBeanMethods = false) + @Import(MinimalWebConfiguration.class) + @Controller + static class Application { + + @RequestMapping("/") + String home(Map model) { + model.put("time", new Date()); + model.put("message", "Hello World"); + model.put("title", "Hello App"); + return "home"; + } + + @RequestMapping("/partial") + String layout(Map model) { + model.put("time", new Date()); + model.put("message", "Hello World"); + model.put("title", "Hello App"); + return "partial"; + } + + @Bean + MustacheViewResolver viewResolver() { + Mustache.Compiler compiler = Mustache.compiler() + .withLoader(new MustacheResourceTemplateLoader( + "classpath:/org/springframework/boot/mustache/autoconfigure/", ".html")); + MustacheViewResolver resolver = new MustacheViewResolver(compiler); + resolver.setPrefix("classpath:/org/springframework/boot/mustache/autoconfigure/"); + resolver.setSuffix(".html"); + return resolver; + } + + static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + } + + @Configuration(proxyBeanMethods = false) + @Import({ TomcatServletWebServerAutoConfiguration.class }) + static class MinimalWebConfiguration { + + @Bean + DispatcherServlet dispatcherServlet() { + return new DispatcherServlet(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationTests.java rename to spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationTests.java index 320d79de0fca..d5030c072fa3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationTests.java @@ -14,22 +14,23 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import java.util.Arrays; import java.util.function.Supplier; import com.samskivert.mustache.Mustache; +import org.assertj.core.api.Assertions; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.mustache.servlet.view.MustacheViewResolver; import org.springframework.boot.test.context.runner.AbstractApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.view.MustacheViewResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; @@ -70,7 +71,7 @@ void registerCompilerForServletApp() { assertThat(context).hasSingleBean(Mustache.Compiler.class); assertThat(context).hasSingleBean(MustacheResourceTemplateLoader.class); assertThat(context).hasSingleBean(MustacheViewResolver.class); - assertThat(context.getBean(Mustache.Compiler.class).standardsMode).isTrue(); + Assertions.assertThat(context.getBean(Mustache.Compiler.class).standardsMode).isTrue(); }); } @@ -81,7 +82,7 @@ void registerBeansForReactiveApp() { assertThat(context).hasSingleBean(MustacheResourceTemplateLoader.class); assertThat(context).doesNotHaveBean(MustacheViewResolver.class); assertThat(context) - .hasSingleBean(org.springframework.boot.web.reactive.result.view.MustacheViewResolver.class); + .hasSingleBean(org.springframework.boot.mustache.reactive.view.MustacheViewResolver.class); }); } @@ -92,7 +93,7 @@ void reactiveViewResolverCanBeDisabled() { assertThat(context).hasSingleBean(Mustache.Compiler.class); assertThat(context).hasSingleBean(MustacheResourceTemplateLoader.class); assertThat(context) - .doesNotHaveBean(org.springframework.boot.web.reactive.result.view.MustacheViewResolver.class); + .doesNotHaveBean(org.springframework.boot.mustache.reactive.view.MustacheViewResolver.class); }); } @@ -104,8 +105,8 @@ void registerCompilerForReactiveApp() { assertThat(context).hasSingleBean(MustacheResourceTemplateLoader.class); assertThat(context).doesNotHaveBean(MustacheViewResolver.class); assertThat(context) - .hasSingleBean(org.springframework.boot.web.reactive.result.view.MustacheViewResolver.class); - assertThat(context.getBean(Mustache.Compiler.class).standardsMode).isTrue(); + .hasSingleBean(org.springframework.boot.mustache.reactive.view.MustacheViewResolver.class); + Assertions.assertThat(context.getBean(Mustache.Compiler.class).standardsMode).isTrue(); }); } @@ -130,13 +131,13 @@ void defaultServletViewResolverConfiguration() { @Test void defaultReactiveViewResolverConfiguration() { configure(new ReactiveWebApplicationContextRunner()).run((context) -> { - org.springframework.boot.web.reactive.result.view.MustacheViewResolver viewResolver = context - .getBean(org.springframework.boot.web.reactive.result.view.MustacheViewResolver.class); + org.springframework.boot.mustache.reactive.view.MustacheViewResolver viewResolver = context + .getBean(org.springframework.boot.mustache.reactive.view.MustacheViewResolver.class); assertThat(viewResolver).extracting("charset").isEqualTo("UTF-8"); assertThat(viewResolver).extracting("prefix").isEqualTo("classpath:/templates/"); assertThat(viewResolver).extracting("requestContextAttribute").isNull(); assertThat(viewResolver).extracting("suffix").isEqualTo(".mustache"); - assertThat(viewResolver.getSupportedMediaTypes()) + Assertions.assertThat(viewResolver.getSupportedMediaTypes()) .containsExactly(MediaType.parseMediaType("text/html;charset=UTF-8")); }); } @@ -248,7 +249,7 @@ private enum ViewResolverKind { * Reactive MustacheViewResolver */ REACTIVE(ReactiveWebApplicationContextRunner::new, - org.springframework.boot.web.reactive.result.view.MustacheViewResolver.class); + org.springframework.boot.mustache.reactive.view.MustacheViewResolver.class); private final Supplier> runner; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationWithoutWebMvcTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationWithoutWebMvcTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationWithoutWebMvcTests.java rename to spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationWithoutWebMvcTests.java index e375b87ceb1c..4f8980041d33 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheAutoConfigurationWithoutWebMvcTests.java +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheAutoConfigurationWithoutWebMvcTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import com.samskivert.mustache.Mustache; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheStandaloneIntegrationTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheStandaloneIntegrationTests.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheStandaloneIntegrationTests.java rename to spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheStandaloneIntegrationTests.java index 8934d3858d25..98641b332527 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/MustacheStandaloneIntegrationTests.java +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/autoconfigure/MustacheStandaloneIntegrationTests.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.mustache; +package org.springframework.boot.mustache.autoconfigure; import java.util.Collections; import com.samskivert.mustache.Mustache; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -29,8 +30,6 @@ import org.springframework.context.annotation.Import; import org.springframework.test.annotation.DirtiesContext; -import static org.assertj.core.api.Assertions.assertThat; - /** * Integration Tests for {@link MustacheAutoConfiguration} outside of a web application. * @@ -45,7 +44,8 @@ class MustacheStandaloneIntegrationTests { @Test void directCompilation() { - assertThat(this.compiler.compile("Hello: {{world}}").execute(Collections.singletonMap("world", "World"))) + Assertions + .assertThat(this.compiler.compile("Hello: {{world}}").execute(Collections.singletonMap("world", "World"))) .isEqualTo("Hello: World"); } diff --git a/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/reactive/view/MustacheViewResolverTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/reactive/view/MustacheViewResolverTests.java new file mode 100644 index 000000000000..6e177a633fa3 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/reactive/view/MustacheViewResolverTests.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.reactive.view; + +import java.time.Duration; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.context.support.GenericApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MustacheViewResolver}. + * + * @author Brian Clozel + */ +class MustacheViewResolverTests { + + private final MustacheViewResolver resolver = new MustacheViewResolver(); + + @BeforeEach + void init() { + GenericApplicationContext applicationContext = new GenericApplicationContext(); + applicationContext.refresh(); + this.resolver.setApplicationContext(applicationContext); + this.resolver.setPrefix("classpath:"); + this.resolver.setSuffix(".html"); + } + + @Test + void resolveNonExistent() { + assertThat(this.resolver.resolveViewName("bar", null).block(Duration.ofSeconds(30))).isNull(); + } + + @Test + @WithResource(name = "template.html", content = "Hello {{World}}") + void resolveExisting() { + assertThat(this.resolver.resolveViewName("template", null).block(Duration.ofSeconds(30))).isNotNull(); + } + +} diff --git a/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/reactive/view/MustacheViewTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/reactive/view/MustacheViewTests.java new file mode 100644 index 000000000000..f45679f560d7 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/reactive/view/MustacheViewTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.reactive.view; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Collections; + +import com.samskivert.mustache.Mustache; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; + +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.http.MediaType; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; + +/** + * Tests for {@link MustacheView}. + * + * @author Brian Clozel + */ +class MustacheViewTests { + + private final StaticApplicationContext context = new StaticApplicationContext(); + + @Test + @WithResource(name = "template.html", content = "Hello {{World}}") + void viewResolvesHandlebars() { + MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test").build()); + MustacheView view = new MustacheView(); + view.setCompiler(Mustache.compiler()); + view.setUrl("classpath:template.html"); + view.setCharset(StandardCharsets.UTF_8.displayName()); + view.setApplicationContext(this.context); + view.render(Collections.singletonMap("World", "Spring"), MediaType.TEXT_HTML, exchange) + .block(Duration.ofSeconds(30)); + StepVerifier.create(exchange.getResponse().getBodyAsString()) + .assertNext((body) -> Assertions.assertThat(body).isEqualToIgnoringWhitespace("Hello Spring")) + .expectComplete() + .verify(Duration.ofSeconds(30)); + } + +} diff --git a/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/servlet/view/MustacheViewResolverTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/servlet/view/MustacheViewResolverTests.java new file mode 100644 index 000000000000..61b25d0daa20 --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/servlet/view/MustacheViewResolverTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.servlet.view; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.mock.web.MockServletContext; +import org.springframework.web.servlet.View; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MustacheViewResolver}. + * + * @author Dave Syer + * @author Andy Wilkinson + */ +class MustacheViewResolverTests { + + private final MustacheViewResolver resolver = new MustacheViewResolver(); + + @BeforeEach + void init() { + GenericApplicationContext applicationContext = new GenericApplicationContext(); + applicationContext.refresh(); + this.resolver.setApplicationContext(applicationContext); + this.resolver.setServletContext(new MockServletContext()); + this.resolver.setPrefix("classpath:"); + this.resolver.setSuffix(".html"); + } + + @Test + void resolveNonExistent() throws Exception { + assertThat(this.resolver.resolveViewName("bar", null)).isNull(); + } + + @Test + @WithResource(name = "template.html", content = "Hello {{World}}") + void resolveExisting() throws Exception { + assertThat(this.resolver.resolveViewName("template", null)).isNotNull(); + } + + @Test + @WithResource(name = "template.html", content = "Hello {{World}}") + void setsContentType() throws Exception { + this.resolver.setContentType("application/octet-stream"); + View view = this.resolver.resolveViewName("template", null); + Assertions.assertThat(view.getContentType()).isEqualTo("application/octet-stream"); + + } + +} diff --git a/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/servlet/view/MustacheViewTests.java b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/servlet/view/MustacheViewTests.java new file mode 100644 index 000000000000..f2d09572075c --- /dev/null +++ b/spring-boot-project/spring-boot-mustache/src/test/java/org/springframework/boot/mustache/servlet/view/MustacheViewTests.java @@ -0,0 +1,66 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.mustache.servlet.view; + +import java.util.Collections; + +import com.samskivert.mustache.Mustache; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockServletContext; +import org.springframework.web.context.WebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MustacheView}. + * + * @author Dave Syer + */ +class MustacheViewTests { + + private final MockHttpServletRequest request = new MockHttpServletRequest(); + + private final MockHttpServletResponse response = new MockHttpServletResponse(); + + private final AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext(); + + @BeforeEach + void init() { + this.context.refresh(); + MockServletContext servletContext = new MockServletContext(); + this.context.setServletContext(servletContext); + servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); + } + + @Test + @WithResource(name = "template.html", content = "Hello {{World}}") + void viewResolvesHandlebars() throws Exception { + MustacheView view = new MustacheView(); + view.setCompiler(Mustache.compiler()); + view.setUrl("classpath:template.html"); + view.setApplicationContext(this.context); + view.render(Collections.singletonMap("World", "Spring"), this.request, this.response); + assertThat(this.response.getContentAsString().trim()).isEqualTo("Hello Spring"); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/content.html b/spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/content.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/content.html rename to spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/content.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/foo.html b/spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/foo.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/foo.html rename to spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/foo.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/foo_de.html b/spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/foo_de.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/foo_de.html rename to spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/foo_de.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/home.html b/spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/home.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/home.html rename to spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/home.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/layout.html b/spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/layout.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/layout.html rename to spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/layout.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/partial.html b/spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/partial.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/mustache/partial.html rename to spring-boot-project/spring-boot-mustache/src/test/resources/org/springframework/boot/mustache/autoconfigure/partial.html diff --git a/spring-boot-project/spring-boot-neo4j/build.gradle b/spring-boot-project/spring-boot-neo4j/build.gradle new file mode 100644 index 000000000000..e6c9cfdefa33 --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/build.gradle @@ -0,0 +1,55 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Neo4j" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.neo4j.driver:neo4j-java-driver") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("org.testcontainers:neo4j") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:neo4j") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-testcontainers"))) + testImplementation("io.projectreactor:reactor-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorIntegrationTests.java b/spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4/health/Neo4jReactiveHealthIndicatorIntegrationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorIntegrationTests.java rename to spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4/health/Neo4jReactiveHealthIndicatorIntegrationTests.java index c2477b4f5ca4..e6f712546caa 100644 --- a/spring-boot-project/spring-boot-actuator/src/dockerTest/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorIntegrationTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4/health/Neo4jReactiveHealthIndicatorIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.neo4j; +package org.springframework.boot.neo4.health; import java.time.Duration; @@ -24,10 +24,11 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; +import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration; +import org.springframework.boot.neo4j.health.Neo4jReactiveHealthIndicator; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfigurationIntegrationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfigurationIntegrationTests.java index e84f6a10dc80..9fdca2c1d98a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/dockerTest/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure; import java.net.URI; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4j/docker/compose/Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4j/docker/compose/Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests.java index 1ac9acc37cb9..eb186f71a9e6 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/dockerTest/java/org/springframework/boot/neo4j/docker/compose/Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.neo4j; +package org.springframework.boot.neo4j.docker.compose; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; -import org.springframework.boot.autoconfigure.neo4j.Neo4jConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.neo4j.autoconfigure.Neo4jConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/neo4j/neo4j-bitnami-compose.yaml b/spring-boot-project/spring-boot-neo4j/src/dockerTest/resources/org/springframework/boot/neo4j/docker/compose/neo4j-bitnami-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/neo4j/neo4j-bitnami-compose.yaml rename to spring-boot-project/spring-boot-neo4j/src/dockerTest/resources/org/springframework/boot/neo4j/docker/compose/neo4j-bitnami-compose.yaml diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/neo4j/neo4j-compose.yaml b/spring-boot-project/spring-boot-neo4j/src/dockerTest/resources/org/springframework/boot/neo4j/docker/compose/neo4j-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/neo4j/neo4j-compose.yaml rename to spring-boot-project/spring-boot-neo4j/src/dockerTest/resources/org/springframework/boot/neo4j/docker/compose/neo4j-compose.yaml diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/ConfigBuilderCustomizer.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/ConfigBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/ConfigBuilderCustomizer.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/ConfigBuilderCustomizer.java index fd37d2b754b3..7fb4178bb47e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/ConfigBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/ConfigBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure; import org.neo4j.driver.Config; import org.neo4j.driver.Config.ConfigBuilder; @@ -25,7 +25,7 @@ * auto-configuration. * * @author Stephane Nicoll - * @since 2.4.0 + * @since 4.0.0 */ @FunctionalInterface public interface ConfigBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfiguration.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfiguration.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfiguration.java index 8610ec835ee1..45166da28868 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfiguration.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure; import java.io.File; import java.net.URI; @@ -37,11 +37,11 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.neo4j.Neo4jProperties.Authentication; -import org.springframework.boot.autoconfigure.neo4j.Neo4jProperties.Pool; -import org.springframework.boot.autoconfigure.neo4j.Neo4jProperties.Security; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; +import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Authentication; +import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Pool; +import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Security; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.util.Assert; @@ -55,7 +55,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 2.4.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(Driver.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jConnectionDetails.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jConnectionDetails.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jConnectionDetails.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jConnectionDetails.java index c876592ee1a2..da328aa0bd80 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jConnectionDetails.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure; import java.net.URI; @@ -30,7 +30,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface Neo4jConnectionDetails extends ConnectionDetails { @@ -54,7 +54,6 @@ default AuthToken getAuthToken() { * Returns the {@link AuthTokenManager} to use for authentication. Defaults to * {@code null} in which case the {@link #getAuthToken() auth token} should be used. * @return the auth token manager - * @since 3.2.0 */ default AuthTokenManager getAuthTokenManager() { return null; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jProperties.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jProperties.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jProperties.java index 403d04ca36d2..25ed6e42a0fb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jProperties.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure; import java.io.File; import java.net.URI; @@ -27,7 +27,7 @@ * * @author Michael J. Simons * @author Stephane Nicoll - * @since 2.4.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.neo4j") public class Neo4jProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jSpringJclLogging.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jSpringJclLogging.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jSpringJclLogging.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jSpringJclLogging.java index 97d2ddced424..822433d16119 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/neo4j/Neo4jSpringJclLogging.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/Neo4jSpringJclLogging.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorAutoConfiguration.java new file mode 100644 index 000000000000..dbbbd9245682 --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorAutoConfiguration.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.neo4j.autoconfigure.health; + +import org.neo4j.driver.Driver; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration; +import org.springframework.boot.neo4j.autoconfigure.health.Neo4jHealthContributorConfigurations.Neo4jConfiguration; +import org.springframework.boot.neo4j.autoconfigure.health.Neo4jHealthContributorConfigurations.Neo4jReactiveConfiguration; +import org.springframework.boot.neo4j.health.Neo4jHealthIndicator; +import org.springframework.boot.neo4j.health.Neo4jReactiveHealthIndicator; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link Neo4jReactiveHealthIndicator} and {@link Neo4jHealthIndicator}. + * + * @author Eric Spiegelberg + * @author Stephane Nicoll + * @author Michael J. Simons + * @since 4.0.0 + */ +@AutoConfiguration(after = Neo4jAutoConfiguration.class) +@ConditionalOnClass({ Driver.class, ConditionalOnEnabledHealthIndicator.class }) +@ConditionalOnBean(Driver.class) +@ConditionalOnEnabledHealthIndicator("neo4j") +@Import({ Neo4jReactiveConfiguration.class, Neo4jConfiguration.class }) +public class Neo4jHealthContributorAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorConfigurations.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorConfigurations.java similarity index 76% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorConfigurations.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorConfigurations.java index 537243f27c1d..0b5f2ad8f3c2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorConfigurations.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorConfigurations.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure.health; import org.neo4j.driver.Driver; import reactor.core.publisher.Flux; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.actuate.neo4j.Neo4jHealthIndicator; -import org.springframework.boot.actuate.neo4j.Neo4jReactiveHealthIndicator; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfiguration; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.neo4j.health.Neo4jHealthIndicator; +import org.springframework.boot.neo4j.health.Neo4jReactiveHealthIndicator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -40,6 +40,7 @@ class Neo4jHealthContributorConfigurations { @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(Neo4jHealthIndicator.class) static class Neo4jConfiguration extends CompositeHealthContributorConfiguration { Neo4jConfiguration() { @@ -55,7 +56,7 @@ HealthContributor neo4jHealthContributor(ConfigurableListableBeanFactory beanFac } @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Flux.class) + @ConditionalOnClass({ Flux.class, Neo4jReactiveHealthIndicator.class }) static class Neo4jReactiveConfiguration extends CompositeReactiveHealthContributorConfiguration { diff --git a/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..2ea10f016c51 --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Neo4j health. + */ +package org.springframework.boot.neo4j.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/package-info.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/package-info.java new file mode 100644 index 000000000000..0ad30d64d4d5 --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Neo4j. + */ +package org.springframework.boot.neo4j.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/Neo4jDockerComposeConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/Neo4jDockerComposeConnectionDetailsFactory.java index 075dfb967e2d..4886a28ed4a9 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/Neo4jDockerComposeConnectionDetailsFactory.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.neo4j; +package org.springframework.boot.neo4j.docker.compose; import java.net.URI; import org.neo4j.driver.AuthToken; -import org.springframework.boot.autoconfigure.neo4j.Neo4jConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.neo4j.autoconfigure.Neo4jConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link Neo4jConnectionDetails} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jEnvironment.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/Neo4jEnvironment.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jEnvironment.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/Neo4jEnvironment.java index 202e5183face..52ef83c0bf2f 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jEnvironment.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/Neo4jEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.neo4j; +package org.springframework.boot.neo4j.docker.compose; import java.util.Map; diff --git a/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/package-info.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/package-info.java new file mode 100644 index 000000000000..ee809d69b358 --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Neo4J service connections. + */ +package org.springframework.boot.neo4j.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthDetails.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthDetails.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthDetails.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthDetails.java index f8c5e2a2a8a6..ce43f5c838d1 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthDetails.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.neo4j; +package org.springframework.boot.neo4j.health; import org.neo4j.driver.Record; import org.neo4j.driver.summary.ResultSummary; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthDetailsHandler.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthDetailsHandler.java similarity index 86% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthDetailsHandler.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthDetailsHandler.java index 49f2d195a8c8..2b4211caed86 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthDetailsHandler.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthDetailsHandler.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.neo4j; +package org.springframework.boot.neo4j.health; import org.neo4j.driver.summary.DatabaseInfo; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.summary.ServerInfo; -import org.springframework.boot.actuate.health.Health.Builder; +import org.springframework.boot.health.contributor.Health; import org.springframework.util.StringUtils; /** @@ -32,10 +32,10 @@ class Neo4jHealthDetailsHandler { /** * Add health details for the specified {@link ResultSummary} and {@code edition}. - * @param builder the {@link Builder} to use + * @param builder the builder to use * @param healthDetails the health details of the server */ - void addHealthDetails(Builder builder, Neo4jHealthDetails healthDetails) { + void addHealthDetails(Health.Builder builder, Neo4jHealthDetails healthDetails) { ResultSummary summary = healthDetails.getSummary(); ServerInfo serverInfo = summary.server(); builder.up() diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthIndicator.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthIndicator.java similarity index 92% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthIndicator.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthIndicator.java index faa60b6f6eca..2bc69c79a3df 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthIndicator.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.neo4j; +package org.springframework.boot.neo4j.health; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -27,9 +27,9 @@ import org.neo4j.driver.exceptions.SessionExpiredException; import org.neo4j.driver.summary.ResultSummary; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; /** * {@link HealthIndicator} that tests the status of a Neo4j by executing a Cypher @@ -38,7 +38,7 @@ * @author Eric Spiegelberg * @author Stephane Nicoll * @author Michael J. Simons - * @since 2.0.0 + * @since 4.0.0 */ public class Neo4jHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicator.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jReactiveHealthIndicator.java similarity index 92% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicator.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jReactiveHealthIndicator.java index 15050b2f8b40..ca23f5861375 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/Neo4jReactiveHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.neo4j; +package org.springframework.boot.neo4j.health; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -28,9 +28,9 @@ import reactor.core.publisher.Mono; import reactor.util.retry.Retry; -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; /** * {@link ReactiveHealthIndicator} that tests the status of a Neo4j by executing a Cypher @@ -39,7 +39,7 @@ * @author Michael J. Simons * @author Stephane Nicoll * @author Phillip Webb - * @since 2.4.0 + * @since 4.0.0 */ public final class Neo4jReactiveHealthIndicator extends AbstractReactiveHealthIndicator { diff --git a/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/package-info.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/package-info.java new file mode 100644 index 000000000000..de96196cf626 --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for Neo4j. + */ +package org.springframework.boot.neo4j.health; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/testcontainers/Neo4jContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/testcontainers/Neo4jContainerConnectionDetailsFactory.java index 6c2f7753d389..45bb06873cd1 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/testcontainers/Neo4jContainerConnectionDetailsFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.neo4j; +package org.springframework.boot.neo4j.testcontainers; import java.net.URI; @@ -22,7 +22,7 @@ import org.neo4j.driver.AuthTokens; import org.testcontainers.containers.Neo4jContainer; -import org.springframework.boot.autoconfigure.neo4j.Neo4jConnectionDetails; +import org.springframework.boot.neo4j.autoconfigure.Neo4jConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/testcontainers/package-info.java b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/testcontainers/package-info.java new file mode 100644 index 000000000000..b363d0069fa4 --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/java/org/springframework/boot/neo4j/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Neo4J service connections. + */ +package org.springframework.boot.neo4j.testcontainers; diff --git a/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..84461cc911eb --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,15 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.health.neo4j.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Neo4j health check.", + "defaultValue": true + }, + { + "name": "spring.neo4j.uri", + "defaultValue": "bolt://localhost:7687" + } + ] +} diff --git a/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..98d3b5dfdbed --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.neo4j.docker.compose.Neo4jDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.neo4j.testcontainers.Neo4jContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..b39844ff1117 --- /dev/null +++ b/spring-boot-project/spring-boot-neo4j/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration +org.springframework.boot.neo4j.autoconfigure.health.Neo4jHealthContributorAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationTests.java b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationTests.java rename to spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfigurationTests.java index b58ab7526a0d..e5bbdc209983 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/Neo4jAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure; import java.io.File; import java.io.IOException; @@ -33,10 +33,10 @@ import org.neo4j.driver.Driver; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration.PropertiesNeo4jConnectionDetails; -import org.springframework.boot.autoconfigure.neo4j.Neo4jProperties.Authentication; -import org.springframework.boot.autoconfigure.neo4j.Neo4jProperties.Security.TrustStrategy; import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; +import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration.PropertiesNeo4jConnectionDetails; +import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Authentication; +import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Security.TrustStrategy; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jPropertiesTests.java b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/Neo4jPropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jPropertiesTests.java rename to spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/Neo4jPropertiesTests.java index f0f4e28c2e5b..3e73edfe4574 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jPropertiesTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/Neo4jPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure; import java.time.Duration; @@ -22,7 +22,7 @@ import org.neo4j.driver.Config; import org.neo4j.driver.internal.retry.RetrySettings; -import org.springframework.boot.autoconfigure.neo4j.Neo4jProperties.Pool; +import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Pool; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorAutoConfigurationTests.java index e7432dd19dd5..d4da6993f1a7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/neo4j/Neo4jHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/autoconfigure/health/Neo4jHealthContributorAutoConfigurationTests.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.neo4j; +package org.springframework.boot.neo4j.autoconfigure.health; import org.junit.jupiter.api.Test; import org.neo4j.driver.Driver; import reactor.core.publisher.Flux; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.neo4j.Neo4jHealthIndicator; -import org.springframework.boot.actuate.neo4j.Neo4jReactiveHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.neo4j.health.Neo4jHealthIndicator; +import org.springframework.boot.neo4j.health.Neo4jReactiveHealthIndicator; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jEnvironmentTests.java b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/docker/compose/Neo4jEnvironmentTests.java similarity index 96% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jEnvironmentTests.java rename to spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/docker/compose/Neo4jEnvironmentTests.java index 8a054687aaf1..dbf6701a0545 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/neo4j/Neo4jEnvironmentTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/docker/compose/Neo4jEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.neo4j; +package org.springframework.boot.neo4j.docker.compose; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jHealthIndicatorTests.java b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/Neo4jHealthIndicatorTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jHealthIndicatorTests.java rename to spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/Neo4jHealthIndicatorTests.java index f44757fc314f..109334cc2e55 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/Neo4jHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.neo4j; +package org.springframework.boot.neo4j.health; import java.util.concurrent.atomic.AtomicInteger; @@ -29,8 +29,8 @@ import org.neo4j.driver.exceptions.SessionExpiredException; import org.neo4j.driver.summary.ResultSummary; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/Neo4jReactiveHealthIndicatorTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorTests.java rename to spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/Neo4jReactiveHealthIndicatorTests.java index 247db9f49253..f593c7b0b952 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/Neo4jReactiveHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.neo4j; +package org.springframework.boot.neo4j.health; import java.time.Duration; import java.util.concurrent.atomic.AtomicInteger; @@ -33,7 +33,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/ResultSummaryMock.java b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/ResultSummaryMock.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/ResultSummaryMock.java rename to spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/ResultSummaryMock.java index bcbf5d1ee7be..758b39348365 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/ResultSummaryMock.java +++ b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/health/ResultSummaryMock.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.neo4j; +package org.springframework.boot.neo4j.health; import org.neo4j.driver.summary.DatabaseInfo; import org.neo4j.driver.summary.ResultSummary; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/testcontainers/Neo4jContainerConnectionDetailsFactoryTests.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/testcontainers/Neo4jContainerConnectionDetailsFactoryTests.java index 6609fe2cd02d..520b50323866 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-neo4j/src/test/java/org/springframework/boot/neo4j/testcontainers/Neo4jContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.neo4j; +package org.springframework.boot.neo4j.testcontainers; import org.junit.jupiter.api.Test; import org.neo4j.driver.AuthToken; diff --git a/spring-boot-project/spring-boot-netty/build.gradle b/spring-boot-project/spring-boot-netty/build.gradle new file mode 100644 index 000000000000..fec2d608b4b3 --- /dev/null +++ b/spring-boot-project/spring-boot-netty/build.gradle @@ -0,0 +1,39 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Netty" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + + implementation("io.netty:netty-common") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/NettyAutoConfiguration.java b/spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/NettyAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/NettyAutoConfiguration.java rename to spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/NettyAutoConfiguration.java index c18f2d56678e..5d897a60607a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/NettyAutoConfiguration.java +++ b/spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/NettyAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.netty; +package org.springframework.boot.netty.autoconfigure; import io.netty.util.NettyRuntime; import io.netty.util.ResourceLeakDetector; @@ -28,7 +28,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for Netty. * * @author Brian Clozel - * @since 2.5.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(NettyRuntime.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/NettyProperties.java b/spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/NettyProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/NettyProperties.java rename to spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/NettyProperties.java index 92cba3de4c11..1bafaa004898 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/netty/NettyProperties.java +++ b/spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/NettyProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.netty; +package org.springframework.boot.netty.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -24,7 +24,7 @@ * These properties apply globally to the Netty library, used as a client or a server. * * @author Brian Clozel - * @since 2.5.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.netty") public class NettyProperties { diff --git a/spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/package-info.java b/spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/package-info.java new file mode 100644 index 000000000000..ee697617198f --- /dev/null +++ b/spring-boot-project/spring-boot-netty/src/main/java/org/springframework/boot/netty/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for the Netty library. + */ +package org.springframework.boot.netty.autoconfigure; diff --git a/spring-boot-project/spring-boot-netty/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-netty/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-netty/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-netty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-netty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..94f931820c1d --- /dev/null +++ b/spring-boot-project/spring-boot-netty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.netty.autoconfigure.NettyAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/netty/NettyAutoConfigurationTests.java b/spring-boot-project/spring-boot-netty/src/test/java/org/springframework/boot/netty/autoconfigure/NettyAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/netty/NettyAutoConfigurationTests.java rename to spring-boot-project/spring-boot-netty/src/test/java/org/springframework/boot/netty/autoconfigure/NettyAutoConfigurationTests.java index 7e6f112d11a0..cf31def13395 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/netty/NettyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-netty/src/test/java/org/springframework/boot/netty/autoconfigure/NettyAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.netty; +package org.springframework.boot.netty.autoconfigure; import io.netty.util.ResourceLeakDetector; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/netty/NettyPropertiesTests.java b/spring-boot-project/spring-boot-netty/src/test/java/org/springframework/boot/netty/autoconfigure/NettyPropertiesTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/netty/NettyPropertiesTests.java rename to spring-boot-project/spring-boot-netty/src/test/java/org/springframework/boot/netty/autoconfigure/NettyPropertiesTests.java index 8cb05186889e..2cda77dda7b0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/netty/NettyPropertiesTests.java +++ b/spring-boot-project/spring-boot-netty/src/test/java/org/springframework/boot/netty/autoconfigure/NettyPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.netty; +package org.springframework.boot.netty.autoconfigure; import io.netty.util.ResourceLeakDetector; import io.netty.util.ResourceLeakDetector.Level; diff --git a/spring-boot-project/spring-boot-observation/build.gradle b/spring-boot-project/spring-boot-observation/build.gradle new file mode 100644 index 000000000000..7ecc16ecd92b --- /dev/null +++ b/spring-boot-project/spring-boot-observation/build.gradle @@ -0,0 +1,39 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Observation" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("io.micrometer:micrometer-observation") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("org.aspectj:aspectjweaver") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationAutoConfiguration.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationAutoConfiguration.java new file mode 100644 index 000000000000..92341398a9a8 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationAutoConfiguration.java @@ -0,0 +1,89 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.observation.autoconfigure; + +import io.micrometer.observation.GlobalObservationConvention; +import io.micrometer.observation.ObservationFilter; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationPredicate; +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.aspectj.weaver.Advice; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for the Micrometer Observation API. + * + * @author Moritz Halbritter + * @author Brian Clozel + * @author Jonatan Ivanov + * @author Vedran Pavic + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass(ObservationRegistry.class) +@EnableConfigurationProperties(ObservationProperties.class) +public class ObservationAutoConfiguration { + + @Bean + static ObservationRegistryPostProcessor observationRegistryPostProcessor( + ObjectProvider> observationRegistryCustomizers, + ObjectProvider observationPredicates, + ObjectProvider> observationConventions, + ObjectProvider> observationHandlers, + ObjectProvider observationHandlerGroups, + ObjectProvider observationFilters) { + return new ObservationRegistryPostProcessor(observationRegistryCustomizers, observationPredicates, + observationConventions, observationHandlers, observationHandlerGroups, observationFilters); + } + + @Bean + @ConditionalOnMissingBean + ObservationRegistry observationRegistry() { + return ObservationRegistry.create(); + } + + @Bean + @Order(0) + PropertiesObservationFilterPredicate propertiesObservationFilter(ObservationProperties properties) { + return new PropertiesObservationFilterPredicate(properties); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(Advice.class) + @ConditionalOnBooleanProperty("management.observations.annotations.enabled") + static class ObservedAspectConfiguration { + + @Bean + @ConditionalOnMissingBean + ObservedAspect observedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } + + } + +} diff --git a/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroup.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroup.java new file mode 100644 index 000000000000..fb318c0ca449 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroup.java @@ -0,0 +1,79 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.observation.autoconfigure; + +import java.util.List; + +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; +import io.micrometer.observation.ObservationRegistry.ObservationConfig; + +import org.springframework.util.Assert; + +/** + * Group of {@link ObservationHandler ObservationHandlers} that can be registered + * together. The first group claiming membership of a handler is responsible for + * registering it. Groups are {@link Comparable} so that they can be ordered against each + * other. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public interface ObservationHandlerGroup extends Comparable { + + /** + * Return if the given handler is a member of this group. + * @param handler the handler to check + * @return if the handler is a member + */ + default boolean isMember(ObservationHandler handler) { + return handlerType().isInstance(handler); + } + + /** + * Register group members against the given {@link ObservationConfig}. + * @param config the config used to register members + * @param members the group members to register + */ + default void registerMembers(ObservationConfig config, List> members) { + config.observationHandler(new FirstMatchingCompositeObservationHandler(members)); + } + + @Override + default int compareTo(ObservationHandlerGroup other) { + return 0; + } + + /** + * Return the primary type of handler that this group accepts. + * @return the accepted handler type + */ + Class handlerType(); + + /** + * Static factory method to create a {@link ObservationHandlerGroup} with members of + * the given handler type. + * @param the handler type + * @param handlerType the handler type + * @return a new {@link ObservationHandlerGroup} + */ + static > ObservationHandlerGroup of(Class handlerType) { + Assert.notNull(handlerType, "'handlerType' must not be null"); + return () -> handlerType; + } + +} diff --git a/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroups.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroups.java new file mode 100644 index 000000000000..688dc705e889 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroups.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.observation.autoconfigure; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationRegistry.ObservationConfig; + +import org.springframework.util.CollectionUtils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +/** + * A collection {@link ObservationHandlerGroup} instance and supporting registration + * logic. + * + * @author Andy Wilkinson + * @author Moritz Halbritter + * @author Phillip Webb + */ +class ObservationHandlerGroups { + + private final List groups; + + ObservationHandlerGroups(Collection groups) { + this.groups = Collections.unmodifiableList(sort(groups)); + } + + private static List sort(Collection groups) { + ArrayList sortedGroups = new ArrayList<>(groups); + Collections.sort(sortedGroups); + return sortedGroups; + } + + void register(ObservationConfig config, List> handlers) { + MultiValueMap> grouped = new LinkedMultiValueMap<>(); + for (ObservationHandler handler : handlers) { + grouped.add(findGroup(handler), handler); + } + for (ObservationHandlerGroup group : this.groups) { + List> members = grouped.get(group); + if (!CollectionUtils.isEmpty(members)) { + group.registerMembers(config, members); + } + } + List> unclaimed = grouped.get(null); + if (!CollectionUtils.isEmpty(unclaimed)) { + for (ObservationHandler handler : unclaimed) { + config.observationHandler(handler); + } + } + } + + private ObservationHandlerGroup findGroup(ObservationHandler handler) { + for (ObservationHandlerGroup group : this.groups) { + if (group.isMember(handler)) { + return group; + } + } + return null; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationProperties.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java rename to spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationProperties.java index 4ad8725a7831..ecdf016e5b57 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation; +package org.springframework.boot.observation.autoconfigure; import java.util.LinkedHashMap; import java.util.Map; @@ -27,7 +27,7 @@ * * @author Brian Clozel * @author Moritz Halbritter - * @since 3.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.observations") public class ObservationProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryConfigurer.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java rename to spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryConfigurer.java index 7b0e9a69d03a..8e86bbfed122 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryConfigurer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation; +package org.springframework.boot.observation.autoconfigure; import java.util.List; @@ -32,7 +32,7 @@ * {@link ObservationRegistry observation registries}. Installs * {@link ObservationPredicate observation predicates} and * {@link GlobalObservationConvention global observation conventions} into the - * {@link ObservationRegistry}. Also uses a {@link ObservationHandlerGrouping} to group + * {@link ObservationRegistry}. Also uses a {@link ObservationHandlerGroups} to group * handlers, which are then added to the {@link ObservationRegistry}. * * @author Moritz Halbritter @@ -47,7 +47,7 @@ class ObservationRegistryConfigurer { private final ObjectProvider> observationHandlers; - private final ObjectProvider observationHandlerGrouping; + private final ObjectProvider observationHandlerGroups; private final ObjectProvider observationFilters; @@ -55,13 +55,13 @@ class ObservationRegistryConfigurer { ObjectProvider observationPredicates, ObjectProvider> observationConventions, ObjectProvider> observationHandlers, - ObjectProvider observationHandlerGrouping, + ObjectProvider observationHandlerGroups, ObjectProvider observationFilters) { this.customizers = customizers; this.observationPredicates = observationPredicates; this.observationConventions = observationConventions; this.observationHandlers = observationHandlers; - this.observationHandlerGrouping = observationHandlerGrouping; + this.observationHandlerGroups = observationHandlerGroups; this.observationFilters = observationFilters; } @@ -74,8 +74,9 @@ void configure(ObservationRegistry registry) { } private void registerHandlers(ObservationRegistry registry) { - this.observationHandlerGrouping.ifAvailable( - (grouping) -> grouping.apply(asOrderedList(this.observationHandlers), registry.observationConfig())); + ObservationHandlerGroups groups = new ObservationHandlerGroups(this.observationHandlerGroups.stream().toList()); + List> orderedHandlers = this.observationHandlers.orderedStream().toList(); + groups.register(registry.observationConfig(), orderedHandlers); } private void registerObservationPredicates(ObservationRegistry registry) { @@ -92,13 +93,9 @@ private void registerFilters(ObservationRegistry registry) { @SuppressWarnings("unchecked") private void customize(ObservationRegistry registry) { - LambdaSafe.callbacks(ObservationRegistryCustomizer.class, asOrderedList(this.customizers), registry) + LambdaSafe.callbacks(ObservationRegistryCustomizer.class, this.customizers.orderedStream().toList(), registry) .withLogger(ObservationRegistryConfigurer.class) .invoke((customizer) -> customizer.customize(registry)); } - private List asOrderedList(ObjectProvider provider) { - return provider.orderedStream().toList(); - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryCustomizer.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryCustomizer.java rename to spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryCustomizer.java index 4581ebd6e12e..b4a54e0f2329 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryCustomizer.java +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation; +package org.springframework.boot.observation.autoconfigure; import io.micrometer.observation.ObservationRegistry; @@ -24,7 +24,7 @@ * * @param the registry type to customize * @author Moritz Halbritter - * @since 3.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface ObservationRegistryCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryPostProcessor.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java rename to spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryPostProcessor.java index 4eb8a6d4d6f0..4c10d172093d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation; +package org.springframework.boot.observation.autoconfigure; import io.micrometer.observation.GlobalObservationConvention; import io.micrometer.observation.ObservationFilter; @@ -43,7 +43,7 @@ class ObservationRegistryPostProcessor implements BeanPostProcessor { private final ObjectProvider> observationHandlers; - private final ObjectProvider observationHandlerGrouping; + private final ObjectProvider observationHandlerGroups; private final ObjectProvider observationFilters; @@ -53,13 +53,13 @@ class ObservationRegistryPostProcessor implements BeanPostProcessor { ObjectProvider observationPredicates, ObjectProvider> observationConventions, ObjectProvider> observationHandlers, - ObjectProvider observationHandlerGrouping, + ObjectProvider observationHandlerGroups, ObjectProvider observationFilters) { this.observationRegistryCustomizers = observationRegistryCustomizers; this.observationPredicates = observationPredicates; this.observationConventions = observationConventions; this.observationHandlers = observationHandlers; - this.observationHandlerGrouping = observationHandlerGrouping; + this.observationHandlerGroups = observationHandlerGroups; this.observationFilters = observationFilters; } @@ -75,7 +75,7 @@ private ObservationRegistryConfigurer getConfigurer() { if (this.configurer == null) { this.configurer = new ObservationRegistryConfigurer(this.observationRegistryCustomizers, this.observationPredicates, this.observationConventions, this.observationHandlers, - this.observationHandlerGrouping, this.observationFilters); + this.observationHandlerGroups, this.observationFilters); } return this.configurer; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicate.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/PropertiesObservationFilterPredicate.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicate.java rename to spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/PropertiesObservationFilterPredicate.java index 5a1bb464497c..602268afc062 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicate.java +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/PropertiesObservationFilterPredicate.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation; +package org.springframework.boot.observation.autoconfigure; import java.util.Map; import java.util.Map.Entry; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfiguration.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ScheduledTasksObservabilityAutoConfiguration.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfiguration.java rename to spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ScheduledTasksObservabilityAutoConfiguration.java index b6a6753633cf..4ce81aaac1b6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksObservabilityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/ScheduledTasksObservabilityAutoConfiguration.java @@ -14,11 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.scheduling; +package org.springframework.boot.observation.autoconfigure; import io.micrometer.observation.ObservationRegistry; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -33,7 +32,7 @@ * scheduled tasks. * * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ @AutoConfiguration(after = ObservationAutoConfiguration.class) @ConditionalOnBean(ObservationRegistry.class) diff --git a/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/package-info.java b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/package-info.java new file mode 100644 index 000000000000..bd061e75fd00 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/main/java/org/springframework/boot/observation/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Micrometer Observation. + */ +package org.springframework.boot.observation.autoconfigure; diff --git a/spring-boot-project/spring-boot-observation/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-observation/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..a2ff31258e04 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,21 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.observations.annotations.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of Micrometer annotations is enabled.", + "defaultValue": false + }, + { + "name": "management.observations.annotations.long-lask-timer.enabled", + "type": "java.lang.boolean", + "description": "Whether to create a LongTaskTimer for every observation.", + "defaultValue": true, + "deprecation": { + "level": "error", + "replacement": "management.metrics.observations.ignored-meters" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-observation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-observation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..c77230e70de6 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration +org.springframework.boot.observation.autoconfigure.ScheduledTasksObservabilityAutoConfiguration diff --git a/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationAutoConfigurationTests.java new file mode 100644 index 000000000000..f0c418883524 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationAutoConfigurationTests.java @@ -0,0 +1,255 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.observation.autoconfigure; + +import io.micrometer.common.KeyValue; +import io.micrometer.common.KeyValues; +import io.micrometer.observation.GlobalObservationConvention; +import io.micrometer.observation.Observation; +import io.micrometer.observation.Observation.Context; +import io.micrometer.observation.ObservationFilter; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationHandler.AllMatchingCompositeObservationHandler; +import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; +import io.micrometer.observation.ObservationPredicate; +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.aspectj.weaver.Advice; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ObservationAutoConfiguration}. + * + * @author Moritz Halbritter + * @author Jonatan Ivanov + * @author Vedran Pavic + */ +class ObservationAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("management.observations.annotations.enabled=true") + .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class)) + .withUserConfiguration(ObservationHandlers.class); + + @Test + void beansShouldNotBeSuppliedWhenMicrometerObservationIsNotOnClassPath() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.observation")).run((context) -> { + assertThat(context).doesNotHaveBean(ObservationRegistry.class); + assertThat(context).doesNotHaveBean(ObservedAspect.class); + }); + } + + @Test + void supplyObservationRegistry() { + this.contextRunner.run((context) -> { + ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); + Observation.start("test-observation", observationRegistry).stop(); + assertThat(context).hasSingleBean(ObservedAspect.class); + }); + } + + @Test + void allowsObservedAspectToBeDisabled() { + this.contextRunner.withClassLoader(new FilteredClassLoader(Advice.class)) + .run((context) -> assertThat(context).doesNotHaveBean(ObservedAspect.class)); + } + + @Test + void allowsObservedAspectToBeDisabledWithProperty() { + this.contextRunner.withPropertyValues("management.observations.annotations.enabled=false") + .run((context) -> assertThat(context).doesNotHaveBean(ObservedAspect.class)); + } + + @Test + void allowsObservedAspectToBeCustomized() { + this.contextRunner.withUserConfiguration(CustomObservedAspectConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ObservedAspect.class) + .getBean(ObservedAspect.class) + .isSameAs(context.getBean("customObservedAspect"))); + } + + @Test + void autoConfiguresObservationPredicates() { + this.contextRunner.withUserConfiguration(ObservationPredicates.class).run((context) -> { + ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); + // This is allowed by ObservationPredicates.customPredicate + Observation observation = Observation.start("observation1", observationRegistry); + assertThat(observation).isNotEqualTo(Observation.NOOP); + observation.stop(); + // This isn't allowed by ObservationPredicates.customPredicate + observation = Observation.start("observation2", observationRegistry); + assertThat(observation).isEqualTo(Observation.NOOP); + observation.stop(); + }); + } + + @Test + void autoConfiguresObservationFilters() { + this.contextRunner.withUserConfiguration(ObservationFilters.class).run((context) -> { + ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); + Observation observation = Observation.start("filtered", observationRegistry); + observation.stop(); + observation.getContext().getLowCardinalityKeyValues().forEach((kv) -> System.out.println(kv.getKey())); + assertThat(observation.getContext().getLowCardinalityKeyValue("filter").getValue()).isEqualTo("one"); + }); + } + + @Test + void shouldSupplyPropertiesObservationFilterBean() { + this.contextRunner + .run((context) -> assertThat(context).hasSingleBean(PropertiesObservationFilterPredicate.class)); + } + + @Test + void shouldApplyCommonKeyValuesToObservations() { + this.contextRunner.withPropertyValues("management.observations.key-values.a=alpha").run((context) -> { + ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); + Observation observation = Observation.start("keyvalues", observationRegistry); + observation.stop(); + assertThat(observation.getContext().getLowCardinalityKeyValue("a").getValue()).isEqualTo("alpha"); + }); + } + + @Test + void autoConfiguresGlobalObservationConventions() { + this.contextRunner.withUserConfiguration(CustomGlobalObservationConvention.class).run((context) -> { + ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); + Context micrometerContext = new Context(); + Observation.start("test-observation", () -> micrometerContext, observationRegistry).stop(); + assertThat(micrometerContext.getAllKeyValues()).containsExactly(KeyValue.of("key1", "value1")); + }); + } + + @Test + void shouldNotDisableSpringSecurityObservationsByDefault() { + this.contextRunner.run((context) -> { + ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); + Observation observation = Observation.start("spring.security.filterchains", observationRegistry); + assertThat(observation).isNotEqualTo(Observation.NOOP); + observation.stop(); + }); + } + + @Test + void shouldDisableSpringSecurityObservationsIfPropertyIsSet() { + this.contextRunner.withPropertyValues("management.observations.enable.spring.security=false").run((context) -> { + ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); + Observation observation = Observation.start("spring.security.filterchains", observationRegistry); + assertThat(observation).isEqualTo(Observation.NOOP); + observation.stop(); + }); + } + + @Configuration(proxyBeanMethods = false) + static class ObservationPredicates { + + @Bean + ObservationPredicate customPredicate() { + return (s, context) -> s.equals("observation1"); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ObservationFilters { + + @Bean + @Order(1) + ObservationFilter observationFilterOne() { + return (context) -> context.addLowCardinalityKeyValue(KeyValue.of("filter", "one")); + } + + @Bean + @Order(0) + ObservationFilter observationFilterTwo() { + return (context) -> context.addLowCardinalityKeyValue(KeyValue.of("filter", "two")); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomObservedAspectConfiguration { + + @Bean + ObservedAspect customObservedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomGlobalObservationConvention { + + @Bean + GlobalObservationConvention customConvention() { + return new GlobalObservationConvention<>() { + @Override + public boolean supportsContext(Context context) { + return true; + } + + @Override + public KeyValues getLowCardinalityKeyValues(Context context) { + return KeyValues.of("key1", "value1"); + } + }; + } + + } + + @Configuration(proxyBeanMethods = false) + static class ObservationHandlers { + + @Bean + @Order(4) + AllMatchingCompositeObservationHandler customAllMatchingCompositeObservationHandler() { + return new AllMatchingCompositeObservationHandler(); + } + + @Bean + @Order(3) + FirstMatchingCompositeObservationHandler customFirstMatchingCompositeObservationHandler() { + return new FirstMatchingCompositeObservationHandler(); + } + + @Bean + @Order(2) + ObservationHandler customObservationHandler() { + return new CustomObservationHandler(); + } + + } + + private static final class CustomObservationHandler implements ObservationHandler { + + @Override + public boolean supportsContext(Context context) { + return true; + } + + } + +} diff --git a/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroupTests.java b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroupTests.java new file mode 100644 index 000000000000..dd11ebcddc92 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroupTests.java @@ -0,0 +1,96 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.observation.autoconfigure; + +import java.util.List; + +import io.micrometer.observation.Observation.Context; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; +import io.micrometer.observation.ObservationRegistry.ObservationConfig; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link ObservationHandlerGroup}. + * + * @author Phillip Webb + */ +class ObservationHandlerGroupTests { + + @Test + void isMemberWhenHandlerIsInstanceOfHandlerTypeReturnsTrue() { + ObservationHandlerGroup group = ObservationHandlerGroup.of(TestObservationHandler.class); + assertThat(group.isMember(mock(TestObservationHandler.class))).isTrue(); + assertThat(group.isMember(mock(TestObservationHandlerSubclass.class))).isTrue(); + } + + @Test + void isMemberWhenHandlerIsNotInstanceOfHandlerTypeReturnsFalse() { + ObservationHandlerGroup group = ObservationHandlerGroup.of(TestObservationHandler.class); + assertThat(group.isMember(mock(ObservationHandler.class))).isFalse(); + assertThat(group.isMember(mock(OtherObservationHandler.class))).isFalse(); + } + + @Test + void registerMembersRegistersUsingFirstMatchingCompositeObservationHandler() { + ObservationHandlerGroup group = ObservationHandlerGroup.of(TestObservationHandler.class); + TestObservationHandler handler1 = mock(TestObservationHandler.class); + TestObservationHandler handler2 = mock(TestObservationHandler.class); + ObservationConfig config = mock(ObservationConfig.class); + group.registerMembers(config, List.of(handler1, handler2)); + ArgumentCaptor> registeredHandler = ArgumentCaptor.captor(); + then(config).should().observationHandler(registeredHandler.capture()); + assertThat(registeredHandler.getValue()).isInstanceOf(FirstMatchingCompositeObservationHandler.class) + .extracting("handlers") + .asInstanceOf(InstanceOfAssertFactories.LIST) + .containsExactly(handler1, handler2); + } + + @Test + void compareToReturnsZero() { + ObservationHandlerGroup group1 = ObservationHandlerGroup.of(TestObservationHandler.class); + ObservationHandlerGroup group2 = ObservationHandlerGroup.of(TestObservationHandler.class); + assertThat(group1.compareTo(group1)).isZero(); + assertThat(group1.compareTo(group2)).isZero(); + assertThat(group2.compareTo(group1)).isZero(); + } + + @Test + void ofCreatesHandlerGroup() { + ObservationHandlerGroup group = ObservationHandlerGroup.of(TestObservationHandler.class); + assertThat(group.handlerType()).isEqualTo(TestObservationHandler.class); + } + + interface TestObservationHandler extends ObservationHandler { + + } + + interface TestObservationHandlerSubclass extends TestObservationHandler { + + } + + interface OtherObservationHandler extends ObservationHandler { + + } + +} diff --git a/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroupsTests.java b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroupsTests.java new file mode 100644 index 000000000000..5df4682a1e16 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationHandlerGroupsTests.java @@ -0,0 +1,129 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.observation.autoconfigure; + +import java.lang.reflect.Method; +import java.util.List; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.Observation.Context; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; +import io.micrometer.observation.ObservationRegistry.ObservationConfig; +import org.junit.jupiter.api.Test; + +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ObservationHandlerGroups}. + * + * @author Moritz Halbritter + */ +class ObservationHandlerGroupsTests { + + private static final ObservationHandlerGroup GROUP_A = ObservationHandlerGroup.of(ObservationHandlerA.class); + + private static final ObservationHandlerGroup GROUP_B = ObservationHandlerGroup.of(ObservationHandlerB.class); + + @Test + void shouldGroupCategoriesIntoFirstMatchingHandlerAndRespectCategoryOrder() { + ObservationHandlerGroups grouping = new ObservationHandlerGroups(List.of(GROUP_A, GROUP_B)); + ObservationConfig config = new ObservationConfig(); + ObservationHandlerA handlerA1 = new ObservationHandlerA("a1"); + ObservationHandlerA handlerA2 = new ObservationHandlerA("a2"); + ObservationHandlerB handlerB1 = new ObservationHandlerB("b1"); + ObservationHandlerB handlerB2 = new ObservationHandlerB("b2"); + grouping.register(config, List.of(handlerB1, handlerB2, handlerA1, handlerA2)); + List> handlers = getObservationHandlers(config); + assertThat(handlers).hasSize(2); + // Category A is first + assertThat(handlers.get(0)).isInstanceOf(FirstMatchingCompositeObservationHandler.class); + FirstMatchingCompositeObservationHandler firstMatching0 = (FirstMatchingCompositeObservationHandler) handlers + .get(0); + assertThat(firstMatching0.getHandlers()).containsExactly(handlerA1, handlerA2); + // Category B is second + assertThat(handlers.get(1)).isInstanceOf(FirstMatchingCompositeObservationHandler.class); + FirstMatchingCompositeObservationHandler firstMatching1 = (FirstMatchingCompositeObservationHandler) handlers + .get(1); + assertThat(firstMatching1.getHandlers()).containsExactly(handlerB1, handlerB2); + } + + @Test + void uncategorizedHandlersShouldBeOrderedAfterCategories() { + ObservationHandlerGroups grouping = new ObservationHandlerGroups(List.of(GROUP_A)); + ObservationConfig config = new ObservationConfig(); + ObservationHandlerA handlerA1 = new ObservationHandlerA("a1"); + ObservationHandlerA handlerA2 = new ObservationHandlerA("a2"); + ObservationHandlerB handlerB1 = new ObservationHandlerB("b1"); + grouping.register(config, List.of(handlerB1, handlerA1, handlerA2)); + List> handlers = getObservationHandlers(config); + assertThat(handlers).hasSize(2); + // Category A is first + assertThat(handlers.get(0)).isInstanceOf(FirstMatchingCompositeObservationHandler.class); + FirstMatchingCompositeObservationHandler firstMatching0 = (FirstMatchingCompositeObservationHandler) handlers + .get(0); + // Uncategorized handlers follow + assertThat(firstMatching0.getHandlers()).containsExactly(handlerA1, handlerA2); + assertThat(handlers.get(1)).isEqualTo(handlerB1); + } + + @SuppressWarnings("unchecked") + private static List> getObservationHandlers(ObservationConfig config) { + Method method = ReflectionUtils.findMethod(ObservationConfig.class, "getObservationHandlers"); + ReflectionUtils.makeAccessible(method); + return (List>) ReflectionUtils.invokeMethod(method, config); + } + + private static class NamedObservationHandler implements ObservationHandler { + + private final String name; + + NamedObservationHandler(String name) { + this.name = name; + } + + @Override + public boolean supportsContext(Context context) { + return true; + } + + @Override + public String toString() { + return getClass().getSimpleName() + "{name='" + this.name + "'}"; + } + + } + + private static class ObservationHandlerA extends NamedObservationHandler { + + ObservationHandlerA(String name) { + super(name); + } + + } + + private static class ObservationHandlerB extends NamedObservationHandler { + + ObservationHandlerB(String name) { + super(name); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurerIntegrationTests.java b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryConfigurerIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurerIntegrationTests.java rename to spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryConfigurerIntegrationTests.java index 22361a6e539d..a98c461dfffc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurerIntegrationTests.java +++ b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ObservationRegistryConfigurerIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation; +package org.springframework.boot.observation.autoconfigure; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicateTests.java b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/PropertiesObservationFilterPredicateTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicateTests.java rename to spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/PropertiesObservationFilterPredicateTests.java index a94addee054a..9826efc1c04d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/PropertiesObservationFilterPredicateTests.java +++ b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/PropertiesObservationFilterPredicateTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation; +package org.springframework.boot.observation.autoconfigure; import io.micrometer.common.KeyValue; import io.micrometer.common.KeyValues; diff --git a/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ScheduledTasksObservabilityAutoConfigurationTests.java b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ScheduledTasksObservabilityAutoConfigurationTests.java new file mode 100644 index 000000000000..14c9d290c826 --- /dev/null +++ b/spring-boot-project/spring-boot-observation/src/test/java/org/springframework/boot/observation/autoconfigure/ScheduledTasksObservabilityAutoConfigurationTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.observation.autoconfigure; + +import io.micrometer.observation.ObservationRegistry; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.observation.autoconfigure.ScheduledTasksObservabilityAutoConfiguration.ObservabilitySchedulingConfigurer; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ScheduledTasksObservabilityAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class ScheduledTasksObservabilityAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner().withConfiguration(AutoConfigurations + .of(ObservationAutoConfiguration.class, ScheduledTasksObservabilityAutoConfiguration.class)); + + @Test + void shouldProvideObservabilitySchedulingConfigurer() { + this.runner.run((context) -> assertThat(context).hasSingleBean(ObservabilitySchedulingConfigurer.class)); + } + + @Test + void observabilitySchedulingConfigurerShouldConfigureObservationRegistry() { + ObservationRegistry observationRegistry = ObservationRegistry.create(); + ObservabilitySchedulingConfigurer configurer = new ObservabilitySchedulingConfigurer(observationRegistry); + ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar(); + configurer.configureTasks(registrar); + assertThat(registrar.getObservationRegistry()).isEqualTo(observationRegistry); + } + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/build.gradle b/spring-boot-project/spring-boot-opentelemetry/build.gradle new file mode 100644 index 000000000000..dad6aed4bdaa --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/build.gradle @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Open Telemetry" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("io.opentelemetry:opentelemetry-api") + api("io.opentelemetry:opentelemetry-sdk") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("io.opentelemetry:opentelemetry-exporter-otlp") + optional("org.testcontainers:grafana") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("com.squareup.okhttp3:mockwebserver") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("io.grpc:grpc-api:1.72.0") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/GrafanaOpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 80% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/GrafanaOpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java index 420098e73703..b6c3a3919a58 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/GrafanaOpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.opentelemetry.docker.compose; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; @@ -32,7 +32,7 @@ class GrafanaOpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests { @DockerComposeTest(composeFile = "otlp-compose.yaml", image = TestImage.GRAFANA_OTEL_LGTM) - void runCreatesConnectionDetails(OtlpLoggingConnectionDetails connectionDetails) { + void runCreatesConnectionDetails(OpenTelemetryLoggingConnectionDetails connectionDetails) { assertThat(connectionDetails.getUrl(Transport.HTTP)).startsWith("http://").endsWith("/v1/logs"); assertThat(connectionDetails.getUrl(Transport.GRPC)).startsWith("http://").endsWith("/v1/logs"); } diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/OpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 79% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/OpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java index a522f0a8eb7a..2bb997348f13 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/OpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.opentelemetry.docker.compose; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; @@ -32,7 +32,7 @@ class OpenTelemetryLoggingDockerComposeConnectionDetailsFactoryIntegrationTests { @DockerComposeTest(composeFile = "otlp-compose.yaml", image = TestImage.OPENTELEMETRY) - void runCreatesConnectionDetails(OtlpLoggingConnectionDetails connectionDetails) { + void runCreatesConnectionDetails(OpenTelemetryLoggingConnectionDetails connectionDetails) { assertThat(connectionDetails.getUrl(Transport.HTTP)).startsWith("http://").endsWith("/v1/logs"); assertThat(connectionDetails.getUrl(Transport.GRPC)).startsWith("http://").endsWith("/v1/logs"); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java similarity index 80% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java index 7ef150a8af73..ce2147e4e9ad 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.opentelemetry.testcontainers; import org.junit.jupiter.api.Test; import org.testcontainers.grafana.LgtmStackContainer; @@ -22,10 +22,10 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingExportAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; @@ -47,7 +47,7 @@ class GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTes static final LgtmStackContainer container = TestImage.container(LgtmStackContainer.class); @Autowired - private OtlpLoggingConnectionDetails connectionDetails; + private OpenTelemetryLoggingConnectionDetails connectionDetails; @Test void connectionCanBeMadeToOpenTelemetryContainer() { @@ -58,7 +58,7 @@ void connectionCanBeMadeToOpenTelemetryContainer() { } @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration(OtlpLoggingAutoConfiguration.class) + @ImportAutoConfiguration(OpenTelemetryLoggingExportAutoConfiguration.class) static class TestConfiguration { } diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/OpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java similarity index 81% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/OpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java index beb207f7650e..5b7b075ef072 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/OpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.opentelemetry.testcontainers; import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; @@ -22,10 +22,10 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingExportAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; @@ -48,7 +48,7 @@ class OpenTelemetryLoggingContainerConnectionDetailsFactoryIntegrationTests { .withExposedPorts(4317, 4318); @Autowired - private OtlpLoggingConnectionDetails connectionDetails; + private OpenTelemetryLoggingConnectionDetails connectionDetails; @Test void connectionCanBeMadeToOpenTelemetryContainer() { @@ -59,7 +59,7 @@ void connectionCanBeMadeToOpenTelemetryContainer() { } @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration(OtlpTracingAutoConfiguration.class) + @ImportAutoConfiguration(OpenTelemetryLoggingExportAutoConfiguration.class) static class TestConfiguration { } diff --git a/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/resources/org/springframework/boot/opentelemetry/docker/compose/otlp-compose.yaml b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/resources/org/springframework/boot/opentelemetry/docker/compose/otlp-compose.yaml new file mode 100644 index 000000000000..86e05475417d --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/dockerTest/resources/org/springframework/boot/opentelemetry/docker/compose/otlp-compose.yaml @@ -0,0 +1,6 @@ +services: + otlp: + image: '{imageName}' + ports: + - '4317' + - '4318' diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryProperties.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryProperties.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryProperties.java rename to spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryProperties.java index 220e5d920fff..228331ff3518 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryProperties.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.opentelemetry; +package org.springframework.boot.opentelemetry.autoconfigure; import java.util.HashMap; import java.util.Map; @@ -25,7 +25,7 @@ * Configuration properties for OpenTelemetry. * * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ @ConfigurationProperties("management.opentelemetry") public class OpenTelemetryProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryResourceAttributes.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryResourceAttributes.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryResourceAttributes.java rename to spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryResourceAttributes.java index cda30f679185..4e808199d4fd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryResourceAttributes.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryResourceAttributes.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.opentelemetry; +package org.springframework.boot.opentelemetry.autoconfigure; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; @@ -39,9 +39,9 @@ * Resource Specification * * @author Dmytro Nosan - * @since 3.5.0 + * @since 4.0.0 */ -public final class OpenTelemetryResourceAttributes { +public class OpenTelemetryResourceAttributes { /** * Default value for service name if {@code service.name} is not set. @@ -52,7 +52,7 @@ public final class OpenTelemetryResourceAttributes { private final Map resourceAttributes; - private final Function getEnv; + private final Function systemEnvironment; /** * Creates a new instance of {@link OpenTelemetryResourceAttributes}. @@ -67,14 +67,14 @@ public OpenTelemetryResourceAttributes(Environment environment, Map resourceAttributes, - Function getEnv) { + Function systemEnvironment) { Assert.notNull(environment, "'environment' must not be null"); this.environment = environment; this.resourceAttributes = (resourceAttributes != null) ? resourceAttributes : Collections.emptyMap(); - this.getEnv = (getEnv != null) ? getEnv : System::getenv; + this.systemEnvironment = (systemEnvironment != null) ? systemEnvironment : System::getenv; } /** @@ -98,7 +98,6 @@ public void applyTo(BiConsumer consumer) { } }); attributes.computeIfAbsent("service.name", (key) -> getApplicationName()); - attributes.computeIfAbsent("service.group", (key) -> getApplicationGroup()); attributes.computeIfAbsent("service.namespace", (key) -> getServiceNamespace()); attributes.forEach(consumer); } @@ -107,17 +106,6 @@ private String getApplicationName() { return this.environment.getProperty("spring.application.name", DEFAULT_SERVICE_NAME); } - /** - * Returns the application group. - * @return the application group - * @deprecated since 3.5.0 for removal in 4.0.0 - */ - @Deprecated(since = "3.5.0", forRemoval = true) - private String getApplicationGroup() { - String applicationGroup = this.environment.getProperty("spring.application.group"); - return (StringUtils.hasLength(applicationGroup)) ? applicationGroup : null; - } - private String getServiceNamespace() { return this.environment.getProperty("spring.application.group"); } @@ -150,7 +138,7 @@ private Map getResourceAttributesFromEnv() { } private String getEnv(String name) { - return this.getEnv.apply(name); + return this.systemEnvironment.apply(name); } /** @@ -166,17 +154,17 @@ private static String decode(String value) { return value; } byte[] bytes = value.getBytes(StandardCharsets.UTF_8); - ByteArrayOutputStream bos = new ByteArrayOutputStream(bytes.length); + ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; if (b != '%') { - bos.write(b); + out.write(b); continue; } int u = decodeHex(bytes, i + 1); int l = decodeHex(bytes, i + 2); if (u >= 0 && l >= 0) { - bos.write((u << 4) + l); + out.write((u << 4) + l); } else { throw new IllegalArgumentException( @@ -185,7 +173,7 @@ private static String decode(String value) { } i += 2; } - return bos.toString(StandardCharsets.UTF_8); + return out.toString(StandardCharsets.UTF_8); } private static int decodeHex(byte[] bytes, int index) { diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfiguration.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfiguration.java new file mode 100644 index 000000000000..5d6a09124957 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfiguration.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; +import io.opentelemetry.sdk.logs.LogRecordProcessor; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; +import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.resources.ResourceBuilder; +import io.opentelemetry.sdk.trace.SdkTracerProvider; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for the OpenTelemetry SDK. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ OpenTelemetry.class, OpenTelemetrySdk.class }) +@EnableConfigurationProperties(OpenTelemetryProperties.class) +public class OpenTelemetrySdkAutoConfiguration { + + OpenTelemetrySdkAutoConfiguration() { + } + + @Bean + @ConditionalOnMissingBean(OpenTelemetry.class) + OpenTelemetrySdk openTelemetrySdk(ObjectProvider openTelemetrySdkTracerProvider, + ObjectProvider openTelemetryContextPropagators, + ObjectProvider openTelemetrySdkLoggerProvider, + ObjectProvider openTelemetrySdkMeterProvider) { + OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder(); + openTelemetrySdkTracerProvider.ifAvailable(builder::setTracerProvider); + openTelemetryContextPropagators.ifAvailable(builder::setPropagators); + openTelemetrySdkLoggerProvider.ifAvailable(builder::setLoggerProvider); + openTelemetrySdkMeterProvider.ifAvailable(builder::setMeterProvider); + return builder.build(); + } + + @Bean + @ConditionalOnMissingBean + Resource openTelemetryResource(Environment environment, OpenTelemetryProperties properties) { + return Resource.getDefault().merge(toResource(environment, properties)); + } + + private Resource toResource(Environment environment, OpenTelemetryProperties properties) { + ResourceBuilder builder = Resource.builder(); + new OpenTelemetryResourceAttributes(environment, properties.getResourceAttributes()).applyTo(builder::put); + return builder.build(); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(SdkLoggerProvider.class) + static class LoggerConfiguration { + + @Bean + @ConditionalOnMissingBean + BatchLogRecordProcessor openTelemetryBatchLogRecordProcessor( + ObjectProvider logRecordExporters) { + LogRecordExporter exporter = LogRecordExporter.composite(logRecordExporters.orderedStream().toList()); + return BatchLogRecordProcessor.builder(exporter).build(); + } + + @Bean + @ConditionalOnMissingBean + SdkLoggerProvider openTelemetrySdkLoggerProvider(Resource openTelemetryResource, + ObjectProvider logRecordProcessors, + ObjectProvider customizers) { + SdkLoggerProviderBuilder builder = SdkLoggerProvider.builder(); + builder.setResource(openTelemetryResource); + logRecordProcessors.orderedStream().forEach(builder::addLogRecordProcessor); + customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); + return builder.build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/SdkLoggerProviderBuilderCustomizer.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/SdkLoggerProviderBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/SdkLoggerProviderBuilderCustomizer.java rename to spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/SdkLoggerProviderBuilderCustomizer.java index 6ee18531f63f..23beda196730 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/SdkLoggerProviderBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/SdkLoggerProviderBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.logging; +package org.springframework.boot.opentelemetry.autoconfigure; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; @@ -24,7 +24,7 @@ * that is used to create the auto-configured {@link SdkLoggerProvider}. * * @author Toshiaki Maki - * @since 3.4.0 + * @since 4.0.0 */ @FunctionalInterface public interface SdkLoggerProviderBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingConnectionDetails.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingConnectionDetails.java new file mode 100644 index 000000000000..e8bfb1eacde1 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingConnectionDetails.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; + +/** + * Details required for actuator to establish a connection to an OpenTelemetry logging + * service. + * + * @author Toshiaki Maki + * @since 4.0.0 + */ +public interface OpenTelemetryLoggingConnectionDetails extends ConnectionDetails { + + /** + * Address to where logs will be published. + * @param transport the transport to use + * @return the address to where logs will be published + */ + String getUrl(Transport transport); + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingConnectionDetailsConfiguration.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingConnectionDetailsConfiguration.java new file mode 100644 index 000000000000..619fdf99503d --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingConnectionDetailsConfiguration.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.Assert; + +/** + * {@link Configuration @Configuration} for {@link OpenTelemetryLoggingConnectionDetails}. + * + * @author Toshiaki Maki + */ +@Configuration(proxyBeanMethods = false) +class OpenTelemetryLoggingConnectionDetailsConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty("management.opentelemetry.logging.export.endpoint") + PropertiesOpenTelemetryLoggingConnectionDetails openTelemetryLoggingConnectionDetails( + OpenTelemetryLoggingExportProperties properties) { + return new PropertiesOpenTelemetryLoggingConnectionDetails(properties); + } + + /** + * Adapts {@link OpenTelemetryLoggingExportProperties} to + * {@link OpenTelemetryLoggingConnectionDetails}. + */ + static class PropertiesOpenTelemetryLoggingConnectionDetails implements OpenTelemetryLoggingConnectionDetails { + + private final OpenTelemetryLoggingExportProperties properties; + + PropertiesOpenTelemetryLoggingConnectionDetails(OpenTelemetryLoggingExportProperties properties) { + this.properties = properties; + } + + @Override + public String getUrl(Transport transport) { + Assert.state(transport == this.properties.getTransport(), + "Requested transport %s doesn't match configured transport %s".formatted(transport, + this.properties.getTransport())); + return this.properties.getEndpoint(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfiguration.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfiguration.java new file mode 100644 index 000000000000..d52f890e95af --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; + +import org.springframework.boot.actuate.autoconfigure.logging.ConditionalOnEnabledLoggingExport; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry logging exports. + * + * @author Toshiaki Maki + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ConditionalOnEnabledLoggingExport.class, OpenTelemetry.class, SdkLoggerProvider.class }) +@ConditionalOnEnabledLoggingExport("opentelemetry") +@EnableConfigurationProperties(OpenTelemetryLoggingExportProperties.class) +@Import({ OpenTelemetryLoggingConnectionDetailsConfiguration.class, OpenTelemetryLoggingTransportConfiguration.class }) +public class OpenTelemetryLoggingExportAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportProperties.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportProperties.java new file mode 100644 index 000000000000..4dd81ade1d9c --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportProperties.java @@ -0,0 +1,125 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for exporting logs using OpenTelemetry. + * + * @author Jonatan Ivanov + * @since 4.0.0 + */ +@ConfigurationProperties("management.opentelemetry.logging.export") +public class OpenTelemetryLoggingExportProperties { + + /** + * URL to the OTel collector's HTTP API. + */ + private String endpoint; + + /** + * Call timeout for the OTel Collector to process an exported batch of data. This + * timeout spans the entire call: resolving DNS, connecting, writing the request body, + * server processing, and reading the response body. If the call requires redirects or + * retries all must complete within one timeout period. + */ + private Duration timeout = Duration.ofSeconds(10); + + /** + * Connect timeout for the OTel collector connection. + */ + private Duration connectTimeout = Duration.ofSeconds(10); + + /** + * Transport used to send the logs. + */ + private Transport transport = Transport.HTTP; + + /** + * Method used to compress the payload. + */ + private Compression compression = Compression.NONE; + + /** + * Custom HTTP headers you want to pass to the collector, for example auth headers. + */ + private final Map headers = new HashMap<>(); + + public String getEndpoint() { + return this.endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public Duration getTimeout() { + return this.timeout; + } + + public void setTimeout(Duration timeout) { + this.timeout = timeout; + } + + public Duration getConnectTimeout() { + return this.connectTimeout; + } + + public void setConnectTimeout(Duration connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public Transport getTransport() { + return this.transport; + } + + public void setTransport(Transport transport) { + this.transport = transport; + } + + public Compression getCompression() { + return this.compression; + } + + public void setCompression(Compression compression) { + this.compression = compression; + } + + public Map getHeaders() { + return this.headers; + } + + public enum Compression { + + /** + * Gzip compression. + */ + GZIP, + + /** + * No compression. + */ + NONE + + } + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingTransportConfiguration.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingTransportConfiguration.java new file mode 100644 index 000000000000..8bcebb5b5b5c --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingTransportConfiguration.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import java.util.Locale; + +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link Configuration @Configuration} for OpenTelemetry log record exporters. + * + * @author Toshiaki Maki + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(OtlpHttpLogRecordExporter.class) +@ConditionalOnMissingBean({ OtlpGrpcLogRecordExporter.class, OtlpHttpLogRecordExporter.class }) +@ConditionalOnBean(OpenTelemetryLoggingConnectionDetails.class) +class OpenTelemetryLoggingTransportConfiguration { + + @Bean + @ConditionalOnProperty(name = "management.opentelemetry.logging.export.transport", havingValue = "http", + matchIfMissing = true) + OtlpHttpLogRecordExporter otlpHttpLogRecordExporter(OpenTelemetryLoggingExportProperties properties, + OpenTelemetryLoggingConnectionDetails connectionDetails, ObjectProvider meterProvider) { + OtlpHttpLogRecordExporterBuilder builder = OtlpHttpLogRecordExporter.builder() + .setEndpoint(connectionDetails.getUrl(Transport.HTTP)) + .setTimeout(properties.getTimeout()) + .setConnectTimeout(properties.getConnectTimeout()) + .setCompression(properties.getCompression().name().toLowerCase(Locale.US)); + properties.getHeaders().forEach(builder::addHeader); + meterProvider.ifAvailable(builder::setMeterProvider); + return builder.build(); + } + + @Bean + @ConditionalOnProperty(name = "management.opentelemetry.logging.export.transport", havingValue = "grpc") + OtlpGrpcLogRecordExporter otlpGrpcLogRecordExporter(OpenTelemetryLoggingExportProperties properties, + OpenTelemetryLoggingConnectionDetails connectionDetails, ObjectProvider meterProvider) { + OtlpGrpcLogRecordExporterBuilder builder = OtlpGrpcLogRecordExporter.builder() + .setEndpoint(connectionDetails.getUrl(Transport.GRPC)) + .setTimeout(properties.getTimeout()) + .setConnectTimeout(properties.getConnectTimeout()) + .setCompression(properties.getCompression().name().toLowerCase(Locale.US)); + properties.getHeaders().forEach(builder::addHeader); + meterProvider.ifAvailable(builder::setMeterProvider); + return builder.build(); + } + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/Transport.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/Transport.java new file mode 100644 index 000000000000..cfea5cee1be9 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/Transport.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +/** + * Transport used to send OTLP log data. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +public enum Transport { + + /** + * HTTP transport. + */ + HTTP, + + /** + * gRPC transport. + */ + GRPC + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/package-info.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/package-info.java new file mode 100644 index 000000000000..54e426a37e09 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for exporting logs with OpenTelemetry. + */ +package org.springframework.boot.opentelemetry.autoconfigure.logging; diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/package-info.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/package-info.java new file mode 100644 index 000000000000..b0630c538e92 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for OpenTelemetry. + */ +package org.springframework.boot.opentelemetry.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryLoggingDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/OpenTelemetryLoggingDockerComposeConnectionDetailsFactory.java similarity index 75% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryLoggingDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/OpenTelemetryLoggingDockerComposeConnectionDetailsFactory.java index 4c420a35f72a..39965e5eceb0 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryLoggingDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/OpenTelemetryLoggingDockerComposeConnectionDetailsFactory.java @@ -14,22 +14,22 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.opentelemetry.docker.compose; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; /** * {@link DockerComposeConnectionDetailsFactory} to create - * {@link OtlpLoggingConnectionDetails} for an OTLP service. + * {@link OpenTelemetryLoggingConnectionDetails} for an OTLP service. * * @author Eddú Meléndez */ class OpenTelemetryLoggingDockerComposeConnectionDetailsFactory - extends DockerComposeConnectionDetailsFactory { + extends DockerComposeConnectionDetailsFactory { private static final String[] OPENTELEMETRY_IMAGE_NAMES = { "otel/opentelemetry-collector-contrib", "grafana/otel-lgtm" }; @@ -40,16 +40,17 @@ class OpenTelemetryLoggingDockerComposeConnectionDetailsFactory OpenTelemetryLoggingDockerComposeConnectionDetailsFactory() { super(OPENTELEMETRY_IMAGE_NAMES, - "org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration"); + "org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingExportAutoConfiguration"); } @Override - protected OtlpLoggingConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) { + protected OpenTelemetryLoggingConnectionDetails getDockerComposeConnectionDetails( + DockerComposeConnectionSource source) { return new OpenTelemetryLoggingDockerComposeConnectionDetails(source.getRunningService()); } private static final class OpenTelemetryLoggingDockerComposeConnectionDetails extends DockerComposeConnectionDetails - implements OtlpLoggingConnectionDetails { + implements OpenTelemetryLoggingConnectionDetails { private final String host; diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/package-info.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/package-info.java new file mode 100644 index 000000000000..1cff1f0adf4c --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose OpenTelemetry logging service connections. + */ +package org.springframework.boot.opentelemetry.docker.compose; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory.java similarity index 78% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory.java index c3dc2392bcd0..c4e5c48841af 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory.java @@ -14,40 +14,39 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.opentelemetry.testcontainers; import org.testcontainers.grafana.LgtmStackContainer; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; /** * {@link ContainerConnectionDetailsFactory} to create - * {@link OtlpLoggingConnectionDetails} from a + * {@link OpenTelemetryLoggingConnectionDetails} from a * {@link ServiceConnection @ServiceConnection}-annotated {@link LgtmStackContainer} using * the {@code "grafana/otel-lgtm"} image. * * @author Eddú Meléndez */ class GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory - extends ContainerConnectionDetailsFactory { + extends ContainerConnectionDetailsFactory { GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory() { - super(ANY_CONNECTION_NAME, - "org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration"); + super(ANY_CONNECTION_NAME); } @Override - protected OtlpLoggingConnectionDetails getContainerConnectionDetails( + protected OpenTelemetryLoggingConnectionDetails getContainerConnectionDetails( ContainerConnectionSource source) { return new OpenTelemetryLoggingContainerConnectionDetails(source); } private static final class OpenTelemetryLoggingContainerConnectionDetails - extends ContainerConnectionDetails implements OtlpLoggingConnectionDetails { + extends ContainerConnectionDetails implements OpenTelemetryLoggingConnectionDetails { private OpenTelemetryLoggingContainerConnectionDetails(ContainerConnectionSource source) { super(source); diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryLoggingContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/OpenTelemetryLoggingContainerConnectionDetailsFactory.java similarity index 77% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryLoggingContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/OpenTelemetryLoggingContainerConnectionDetailsFactory.java index ed7f757f3b00..8c8a95b01a40 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryLoggingContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/OpenTelemetryLoggingContainerConnectionDetailsFactory.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.opentelemetry.testcontainers; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.logging.otlp.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; /** * {@link ContainerConnectionDetailsFactory} to create - * {@link OtlpLoggingConnectionDetails} from a + * {@link OpenTelemetryLoggingConnectionDetails} from a * {@link ServiceConnection @ServiceConnection}-annotated {@link GenericContainer} using * the {@code "otel/opentelemetry-collector-contrib"} image. * @@ -35,25 +35,24 @@ * @author Moritz Halbritter */ class OpenTelemetryLoggingContainerConnectionDetailsFactory - extends ContainerConnectionDetailsFactory, OtlpLoggingConnectionDetails> { + extends ContainerConnectionDetailsFactory, OpenTelemetryLoggingConnectionDetails> { private static final int OTLP_GRPC_PORT = 4317; private static final int OTLP_HTTP_PORT = 4318; OpenTelemetryLoggingContainerConnectionDetailsFactory() { - super("otel/opentelemetry-collector-contrib", - "org.springframework.boot.actuate.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration"); + super("otel/opentelemetry-collector-contrib"); } @Override - protected OtlpLoggingConnectionDetails getContainerConnectionDetails( + protected OpenTelemetryLoggingConnectionDetails getContainerConnectionDetails( ContainerConnectionSource> source) { return new OpenTelemetryLoggingContainerConnectionDetails(source); } private static final class OpenTelemetryLoggingContainerConnectionDetails - extends ContainerConnectionDetails> implements OtlpLoggingConnectionDetails { + extends ContainerConnectionDetails> implements OpenTelemetryLoggingConnectionDetails { private OpenTelemetryLoggingContainerConnectionDetails(ContainerConnectionSource> source) { super(source); diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/package-info.java b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/package-info.java new file mode 100644 index 000000000000..e8fa0b18e4a4 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Testcontainers OpenTelemetry logging service connections. + */ +package org.springframework.boot.opentelemetry.testcontainers; diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..316a51d4f842 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,103 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.logging.export.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of logging is enabled to export logs.", + "defaultValue": true, + "deprecation": { + "replacement": "management.opentelemetry.logging.export.enabled", + "level": "error" + } + }, + { + "name": "management.opentelemetry.logging.export.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of logging is enabled to export logs over OTLP." + }, + { + "name": "management.otlp.logging", + "type": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", + "sourceType": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", + "deprecation": { + "replacement": "management.opentelemetry.logging.export", + "level": "error" + } + }, + { + "name": "management.otlp.logging.compression", + "type": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties$Compression", + "description": "Method used to compress the payload.", + "sourceType": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", + "defaultValue": "none", + "deprecation": { + "replacement": "management.opentelemetry.logging.export.compression", + "level": "error" + } + }, + { + "name": "management.otlp.logging.connect-timeout", + "type": "java.time.Duration", + "description": "Connect timeout for the OTel collector connection.", + "sourceType": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", + "defaultValue": "10s", + "deprecation": { + "replacement": "management.opentelemetry.logging.export.connect-timeout", + "level": "error" + } + }, + { + "name": "management.otlp.logging.endpoint", + "type": "java.lang.String", + "description": "URL to the OTel collector's HTTP API.", + "sourceType": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", + "deprecation": { + "replacement": "management.opentelemetry.logging.export.endpoint", + "level": "error" + } + }, + { + "name": "management.otlp.logging.export.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of logging is enabled to export OTLP logs.", + "deprecation": { + "replacement": "management.opentelemetry.logging.export.enabled", + "level": "error" + } + }, + { + "name": "management.otlp.logging.headers", + "type": "java.util.Map", + "description": "Custom HTTP headers you want to pass to the collector, for example auth headers.", + "sourceType": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", + "deprecation": { + "replacement": "management.opentelemetry.logging.export.headers", + "level": "error" + } + }, + { + "name": "management.otlp.logging.timeout", + "type": "java.time.Duration", + "description": "Call timeout for the OTel Collector to process an exported batch of data. This timeout spans the entire call: resolving DNS, connecting, writing the request body, server processing, and reading the response body. If the call requires redirects or retries all must complete within one timeout period.", + "sourceType": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", + "defaultValue": "10s", + "deprecation": { + "replacement": "management.opentelemetry.logging.export.timeout", + "level": "error" + } + }, + { + "name": "management.otlp.logging.transport", + "type": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.Transport", + "description": "Transport used to send the logs.", + "sourceType": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", + "defaultValue": "http", + "deprecation": { + "replacement": "management.opentelemetry.logging.export.transport", + "level": "error" + } + } + ], + "hints": [] +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..c0e36edc185d --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/spring.factories @@ -0,0 +1,5 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.opentelemetry.docker.compose.OpenTelemetryLoggingDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.opentelemetry.testcontainers.GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory,\ +org.springframework.boot.opentelemetry.testcontainers.OpenTelemetryLoggingContainerConnectionDetailsFactory \ No newline at end of file diff --git a/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..f94012057d25 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration +org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingExportAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryPropertiesTests.java b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryPropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryPropertiesTests.java rename to spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryPropertiesTests.java index 1d94f8a5c07d..99e70b62636c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryPropertiesTests.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.opentelemetry; +package org.springframework.boot.opentelemetry.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryResourceAttributesTests.java b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryResourceAttributesTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryResourceAttributesTests.java rename to spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryResourceAttributesTests.java index 5e27d3c52eb0..7d5d245bdf0b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryResourceAttributesTests.java +++ b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryResourceAttributesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.opentelemetry; +package org.springframework.boot.opentelemetry.autoconfigure; import java.util.LinkedHashMap; import java.util.Map; @@ -99,7 +99,7 @@ void invalidResourceAttributesShouldBeIgnored() { @SuppressWarnings("unchecked") void systemGetEnvShouldBeUsedAsDefaultEnvFunction() { OpenTelemetryResourceAttributes attributes = new OpenTelemetryResourceAttributes(this.environment, null); - Function getEnv = assertThat(attributes).extracting("getEnv") + Function getEnv = assertThat(attributes).extracting("systemEnvironment") .asInstanceOf(InstanceOfAssertFactories.type(Function.class)) .actual(); System.getenv().forEach((key, value) -> assertThat(getEnv.apply(key)).isEqualTo(value)); @@ -159,11 +159,10 @@ void unknownServiceShouldBeUsedAsDefaultServiceName() { } @Test - void springApplicationGroupNameShouldBeUsedAsDefaultServiceGroup() { + void springApplicationGroupNameShouldBeUsedAsDefaultServiceNamespace() { this.environment.setProperty("spring.application.group", "spring-boot"); - assertThat(getAttributes()).hasSize(3) + assertThat(getAttributes()).hasSize(2) .containsEntry("service.name", "unknown_service") - .containsEntry("service.group", "spring-boot") .containsEntry("service.namespace", "spring-boot"); } @@ -212,28 +211,26 @@ void resourceAttributesShouldTakePrecedenceOverSpringApplicationGroupName() { void resourceAttributesShouldTakePrecedenceOverApplicationGroupNameForPopulatingServiceNamespace() { this.resourceAttributes.put("service.namespace", "spring-boot-app"); this.environment.setProperty("spring.application.group", "overridden"); - assertThat(getAttributes()).hasSize(3) + assertThat(getAttributes()).hasSize(2) .containsEntry("service.name", "unknown_service") - .containsEntry("service.group", "overridden") .containsEntry("service.namespace", "spring-boot-app"); } @Test void otelResourceAttributesShouldTakePrecedenceOverSpringApplicationGroupName() { - this.environmentVariables.put("OTEL_RESOURCE_ATTRIBUTES", "service.group=spring-boot"); + this.environmentVariables.put("OTEL_RESOURCE_ATTRIBUTES", "service.namespace=spring-boot"); this.environment.setProperty("spring.application.group", "spring-boot-app"); - assertThat(getAttributes()).hasSize(3) + assertThat(getAttributes()).hasSize(2) .containsEntry("service.name", "unknown_service") - .containsEntry("service.group", "spring-boot") - .containsEntry("service.namespace", "spring-boot-app"); + .containsEntry("service.namespace", "spring-boot"); } @Test void otelResourceAttributesShouldTakePrecedenceOverSpringApplicationGroupNameForServiceNamespace() { this.environmentVariables.put("OTEL_RESOURCE_ATTRIBUTES", "service.namespace=spring-boot"); this.environment.setProperty("spring.application.group", "overridden"); - assertThat(getAttributes()).hasSize(3) - .containsEntry("service.group", "overridden") + assertThat(getAttributes()).hasSize(2) + .containsEntry("service.name", "unknown_service") .containsEntry("service.namespace", "spring-boot"); } diff --git a/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfigurationTests.java b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfigurationTests.java new file mode 100644 index 000000000000..af28a1a84b50 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfigurationTests.java @@ -0,0 +1,355 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicInteger; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.logs.LogRecordProcessor; +import io.opentelemetry.sdk.logs.ReadWriteLogRecord; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.context.annotation.ImportCandidates; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link OpenTelemetrySdkAutoConfiguration}. + * + * @author Moritz Halbritter + * @author Toshiaki Maki + * @author Phillip Webb + */ +class OpenTelemetrySdkAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class)); + + @Test + void registeredInAutoConfigurationImports() { + assertThat(ImportCandidates.load(AutoConfiguration.class, null).getCandidates()) + .contains(OpenTelemetrySdkAutoConfiguration.class.getName()); + } + + @Test + void providesBeans() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(OpenTelemetrySdk.class); + assertThat(context).hasSingleBean(Resource.class); + assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context).hasSingleBean(SdkLoggerProvider.class); + }); + } + + @ParameterizedTest + @ValueSource(strings = { "io.opentelemetry", "io.opentelemetry.api" }) + void whenOpenTelemetryIsNotOnClasspathDoesNotProvideBeans(String packageName) { + this.contextRunner.withClassLoader(new FilteredClassLoader(packageName)).run((context) -> { + assertThat(context).doesNotHaveBean(OpenTelemetrySdk.class); + assertThat(context).doesNotHaveBean(Resource.class); + assertThat(context).doesNotHaveBean(BatchLogRecordProcessor.class); + assertThat(context).doesNotHaveBean(SdkLoggerProvider.class); + }); + } + + @Test + void whenOpenTelemetryLogsIsNotOnClasspathDoesNotProvideBeans() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk.logs")).run((context) -> { + assertThat(context).hasSingleBean(OpenTelemetrySdk.class); + assertThat(context).hasSingleBean(Resource.class); + assertThat(context).doesNotHaveBean(BatchLogRecordProcessor.class); + assertThat(context).doesNotHaveBean(SdkLoggerProvider.class); + }); + } + + @Test + void whenHasUserSuppliedBeansDoesNotProvideBeans() { + this.contextRunner.withUserConfiguration(UserConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(OpenTelemetry.class); + assertThat(context).hasBean("customOpenTelemetry"); + assertThat(context).hasSingleBean(Resource.class); + assertThat(context).hasBean("customResource"); + assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context).hasBean("customBatchLogRecordProcessor").hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context).hasSingleBean(LogRecordProcessor.class); + assertThat(context).hasBean("customSdkLoggerProvider").hasSingleBean(SdkLoggerProvider.class); + }); + } + + @Test + void whenHasApplicationNamePropertyProvidesServiceNameResourceAttribute() { + this.contextRunner.withPropertyValues("spring.application.name=my-application").run((context) -> { + Resource resource = context.getBean(Resource.class); + assertThat(resource.getAttributes().asMap()) + .contains(entry(AttributeKey.stringKey("service.name"), "my-application")); + }); + } + + @Test + void whenHasApplicationGroupPropertyProvidesServiceNamespaceResourceAttribute() { + this.contextRunner.withPropertyValues("spring.application.group=my-group").run((context) -> { + Resource resource = context.getBean(Resource.class); + assertThat(resource.getAttributes().asMap()).containsEntry(AttributeKey.stringKey("service.namespace"), + "my-group"); + }); + } + + @Test + void whenHasNoApplicationGroupPropertyProvidesNoServiceGroupResourceAttribute() { + this.contextRunner.run((context) -> { + Resource resource = context.getBean(Resource.class); + assertThat(resource.getAttributes().asMap()).doesNotContainKey(AttributeKey.stringKey("service.group")); + }); + } + + @Test + void whenHasNoApplicationGroupPropertyProvidesNoServiceNamespaceResourceAttribute() { + this.contextRunner.run(((context) -> { + Resource resource = context.getBean(Resource.class); + assertThat(resource.getAttributes().asMap()).doesNotContainKey(AttributeKey.stringKey("service.namespace")); + })); + } + + @Test + void whenHasNoApplicationNamePropertyProvidesDefaultApplicationName() { + this.contextRunner.run((context) -> { + Resource resource = context.getBean(Resource.class); + assertThat(resource.getAttributes().asMap()) + .contains(entry(AttributeKey.stringKey("service.name"), "unknown_service")); + }); + } + + @Test + void whenHasResourceAttributesPropertyProvidesResourceAttributes() { + this.contextRunner.withPropertyValues("management.opentelemetry.resource-attributes.region=us-west") + .run((context) -> { + Resource resource = context.getBean(Resource.class); + assertThat(resource.getAttributes().asMap()) + .contains(entry(AttributeKey.stringKey("region"), "us-west")); + }); + } + + @Test + void whenHasSdkTracerProviderBeanProvidesTracerProvider() { + this.contextRunner.withBean(SdkTracerProvider.class, () -> SdkTracerProvider.builder().build()) + .run((context) -> { + OpenTelemetry openTelemetry = context.getBean(OpenTelemetry.class); + assertThat(openTelemetry.getTracerProvider()).isNotNull(); + }); + } + + @Test + void whenHasContextPropagatorsBeanProvidesPropagators() { + this.contextRunner.withBean(ContextPropagators.class, ContextPropagators::noop).run((context) -> { + OpenTelemetry openTelemetry = context.getBean(OpenTelemetry.class); + assertThat(openTelemetry.getPropagators()).isNotNull(); + }); + } + + @Test + void whenHasSdkLoggerProviderBeanProvidesLogsBridge() { + this.contextRunner.withBean(SdkLoggerProvider.class, () -> SdkLoggerProvider.builder().build()) + .run((context) -> { + OpenTelemetry openTelemetry = context.getBean(OpenTelemetry.class); + assertThat(openTelemetry.getLogsBridge()).isNotNull(); + }); + } + + @Test + void whenHasSdkMeterProviderProvidesMeterProvider() { + this.contextRunner.withBean(SdkMeterProvider.class, () -> SdkMeterProvider.builder().build()).run((context) -> { + OpenTelemetry openTelemetry = context.getBean(OpenTelemetry.class); + assertThat(openTelemetry.getMeterProvider()).isNotNull(); + }); + } + + @Test + void whenHasMultipleLogRecordExportersProvidesBatchLogRecordProcessor() { + this.contextRunner.withUserConfiguration(MultipleLogRecordExportersConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context.getBeansOfType(LogRecordExporter.class)).hasSize(2); + assertThat(context).hasBean("customLogRecordExporter1"); + assertThat(context).hasBean("customLogRecordExporter2"); + }); + } + + @Test + void whenHasMultipleLogRecordProcessorsStillProvidesBatchLogRecordProcessor() { + this.contextRunner.withUserConfiguration(MultipleLogRecordProcessorsConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context).hasSingleBean(SdkLoggerProvider.class); + assertThat(context.getBeansOfType(LogRecordProcessor.class)).hasSize(3); + assertThat(context).hasBean("openTelemetryBatchLogRecordProcessor"); + assertThat(context).hasBean("customLogRecordProcessor1"); + assertThat(context).hasBean("customLogRecordProcessor2"); + }); + } + + @Test + void whenHasMultipleSdkLoggerProviderBuilderCustomizersCallsCustomizeMethod() { + this.contextRunner.withUserConfiguration(MultipleSdkLoggerProviderBuilderCustomizersConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(SdkLoggerProvider.class); + assertThat(context.getBeansOfType(SdkLoggerProviderBuilderCustomizer.class)).hasSize(2); + assertThat(context).hasBean("customSdkLoggerProviderBuilderCustomizer1"); + assertThat(context).hasBean("customSdkLoggerProviderBuilderCustomizer2"); + assertThat(context + .getBean("customSdkLoggerProviderBuilderCustomizer1", NoopSdkLoggerProviderBuilderCustomizer.class) + .called()).isEqualTo(1); + assertThat(context + .getBean("customSdkLoggerProviderBuilderCustomizer2", NoopSdkLoggerProviderBuilderCustomizer.class) + .called()).isEqualTo(1); + }); + } + + @Configuration(proxyBeanMethods = false) + static class UserConfiguration { + + @Bean + OpenTelemetry customOpenTelemetry() { + return mock(OpenTelemetry.class); + } + + @Bean + Resource customResource() { + return Resource.getDefault(); + } + + @Bean + BatchLogRecordProcessor customBatchLogRecordProcessor() { + return BatchLogRecordProcessor.builder(new NoopLogRecordExporter()).build(); + } + + @Bean + SdkLoggerProvider customSdkLoggerProvider() { + return SdkLoggerProvider.builder().build(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MultipleLogRecordExportersConfiguration { + + @Bean + LogRecordExporter customLogRecordExporter1() { + return new NoopLogRecordExporter(); + } + + @Bean + LogRecordExporter customLogRecordExporter2() { + return new NoopLogRecordExporter(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MultipleLogRecordProcessorsConfiguration { + + @Bean + LogRecordProcessor customLogRecordProcessor1() { + return new NoopLogRecordProcessor(); + } + + @Bean + LogRecordProcessor customLogRecordProcessor2() { + return new NoopLogRecordProcessor(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MultipleSdkLoggerProviderBuilderCustomizersConfiguration { + + @Bean + SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer1() { + return new NoopSdkLoggerProviderBuilderCustomizer(); + } + + @Bean + SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer2() { + return new NoopSdkLoggerProviderBuilderCustomizer(); + } + + } + + static class NoopLogRecordExporter implements LogRecordExporter { + + @Override + public CompletableResultCode export(Collection logs) { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode flush() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + + } + + static class NoopLogRecordProcessor implements LogRecordProcessor { + + @Override + public void onEmit(Context context, ReadWriteLogRecord logRecord) { + } + + } + + static class NoopSdkLoggerProviderBuilderCustomizer implements SdkLoggerProviderBuilderCustomizer { + + final AtomicInteger called = new AtomicInteger(0); + + @Override + public void customize(SdkLoggerProviderBuilder builder) { + this.called.incrementAndGet(); + } + + int called() { + return this.called.get(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfigurationIntegrationTests.java new file mode 100644 index 000000000000..ca6b0b54b567 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfigurationIntegrationTests.java @@ -0,0 +1,127 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.util.concurrent.TimeUnit; + +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import okio.Buffer; +import okio.GzipSource; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.ApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link OpenTelemetryLoggingExportAutoConfiguration}. + * + * @author Toshiaki Maki + */ +class OpenTelemetryLoggingExportAutoConfigurationIntegrationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("spring.application.name=otlp-logs-test", + "management.opentelemetry.logging.export.headers.Authorization=Bearer my-token") + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, + OpenTelemetryLoggingExportAutoConfiguration.class)); + + private final MockWebServer mockWebServer = new MockWebServer(); + + @BeforeEach + void setUp() throws IOException { + this.mockWebServer.start(); + } + + @AfterEach + void tearDown() throws IOException { + this.mockWebServer.close(); + } + + @Test + void httpLogRecordExporterShouldUseProtobufAndNoCompressionByDefault() { + this.mockWebServer.enqueue(new MockResponse()); + this.contextRunner + .withPropertyValues("management.opentelemetry.logging.export.endpoint=http://localhost:%d/v1/logs" + .formatted(this.mockWebServer.getPort())) + .run((context) -> { + logMessage(context); + RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS); + assertThat(request).isNotNull(); + assertThat(request.getRequestLine()).contains("/v1/logs"); + assertThat(request.getHeader("Content-Type")).isEqualTo("application/x-protobuf"); + assertThat(request.getHeader("Content-Encoding")).isNull(); + assertThat(request.getBodySize()).isPositive(); + try (Buffer body = request.getBody()) { + assertLogMessage(body); + } + }); + } + + @Test + void httpLogRecordExporterCanBeConfiguredToUseGzipCompression() { + this.mockWebServer.enqueue(new MockResponse()); + this.contextRunner + .withPropertyValues("management.opentelemetry.logging.export.endpoint=http://localhost:%d/v1/logs" + .formatted(this.mockWebServer.getPort()), "management.opentelemetry.logging.export.compression=gzip") + .run((context) -> { + logMessage(context); + RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS); + assertThat(request).isNotNull(); + assertThat(request.getRequestLine()).contains("/v1/logs"); + assertThat(request.getHeader("Content-Type")).isEqualTo("application/x-protobuf"); + assertThat(request.getHeader("Content-Encoding")).isEqualTo("gzip"); + assertThat(request.getBodySize()).isPositive(); + try (Buffer uncompressed = new Buffer(); Buffer body = request.getBody()) { + uncompressed.writeAll(new GzipSource(body)); + assertLogMessage(uncompressed); + } + }); + } + + private static void logMessage(ApplicationContext context) { + SdkLoggerProvider loggerProvider = context.getBean(SdkLoggerProvider.class); + loggerProvider.get("test") + .logRecordBuilder() + .setSeverity(Severity.INFO) + .setSeverityText("INFO") + .setBody("Hello") + .setTimestamp(Instant.now()) + .emit(); + } + + private static void assertLogMessage(Buffer body) { + String string = body.readString(StandardCharsets.UTF_8); + assertThat(string).contains("otlp-logs-test"); + assertThat(string).contains("test"); + assertThat(string).contains("INFO"); + assertThat(string).contains("Hello"); + } + +} diff --git a/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfigurationTests.java new file mode 100644 index 000000000000..1123e2345721 --- /dev/null +++ b/spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingExportAutoConfigurationTests.java @@ -0,0 +1,282 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; + +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; +import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; +import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import okhttp3.HttpUrl; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.context.annotation.ImportCandidates; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.SdkLoggerProviderBuilderCustomizer; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingConnectionDetailsConfiguration.PropertiesOpenTelemetryLoggingConnectionDetails; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OpenTelemetryLoggingExportAutoConfiguration}. + * + * @author Toshiaki Maki + * @author Moritz Halbritter + */ +class OpenTelemetryLoggingExportAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner; + + OpenTelemetryLoggingExportAutoConfigurationTests() { + this.contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations + .of(OpenTelemetrySdkAutoConfiguration.class, OpenTelemetryLoggingExportAutoConfiguration.class)); + } + + @Test + void registeredInAutoConfigurationImports() { + assertThat(ImportCandidates.load(AutoConfiguration.class, null).getCandidates()) + .contains(OpenTelemetryLoggingExportAutoConfiguration.class.getName()); + } + + @ParameterizedTest + @ValueSource(strings = { "io.opentelemetry.sdk.logs", "io.opentelemetry.api", + "io.opentelemetry.exporter.otlp.http.logs" }) + void whenOpenTelemetryIsNotOnClasspathDoesNotProvideBeans(String packageName) { + this.contextRunner.withClassLoader(new FilteredClassLoader(packageName)).run((context) -> { + assertThat(context).doesNotHaveBean(OpenTelemetryLoggingConnectionDetails.class); + assertThat(context).doesNotHaveBean(OtlpHttpLogRecordExporter.class); + }); + } + + @Test + void whenHasEndpointPropertyProvidesBeans() { + this.contextRunner + .withPropertyValues("management.opentelemetry.logging.export.endpoint=http://localhost:4318/v1/logs") + .run((context) -> { + assertThat(context).hasSingleBean(OpenTelemetryLoggingConnectionDetails.class); + OpenTelemetryLoggingConnectionDetails connectionDetails = context + .getBean(OpenTelemetryLoggingConnectionDetails.class); + assertThat(connectionDetails.getUrl(Transport.HTTP)).isEqualTo("http://localhost:4318/v1/logs"); + assertThat(context).hasSingleBean(OtlpHttpLogRecordExporter.class); + assertThat(context).hasSingleBean(LogRecordExporter.class); + }); + } + + @Test + void whenHasNoEndpointPropertyDoesNotProvideBeans() { + this.contextRunner.run((context) -> { + assertThat(context).doesNotHaveBean(OpenTelemetryLoggingConnectionDetails.class); + assertThat(context).doesNotHaveBean(OtlpHttpLogRecordExporter.class); + }); + } + + @Test + void whenOpenTelemetryLoggingExportEnabledPropertyIsFalseProvidesExpectedBeans() { + this.contextRunner + .withPropertyValues("management.opentelemetry.logging.export.enabled=false", + "management.opentelemetry.logging.export.endpoint=http://localhost:4318/v1/logs") + .run((context) -> { + assertThat(context).doesNotHaveBean(OpenTelemetryLoggingConnectionDetails.class); + assertThat(context).doesNotHaveBean(LogRecordExporter.class); + }); + } + + @Test + void whenLoggingExportEnabledPropertyIsFalseNoProvideExpectedBeans() { + this.contextRunner + .withPropertyValues("management.logging.export.enabled=false", + "management.opentelemetry.logging.export.endpoint=http://localhost:4318/v1/logs") + .run((context) -> { + assertThat(context).doesNotHaveBean(OpenTelemetryLoggingConnectionDetails.class); + assertThat(context).doesNotHaveBean(LogRecordExporter.class); + }); + } + + @Test + void whenHasCustomHttpExporterDoesNotProvideExporterBean() { + this.contextRunner.withUserConfiguration(CustomHttpExporterConfiguration.class) + .run((context) -> assertThat(context).hasBean("customOtlpHttpLogRecordExporter") + .hasSingleBean(LogRecordExporter.class)); + } + + @Test + void whenHasCustomGrpcExporterDoesNotProvideExporterBean() { + this.contextRunner.withUserConfiguration(CustomGrpcExporterConfiguration.class) + .run((context) -> assertThat(context).hasBean("customOtlpGrpcLogRecordExporter") + .hasSingleBean(LogRecordExporter.class)); + } + // FIXME + + @Test + void whenHasCustomLoggingConnectionDetailsDoesNotProvideExporterBean() { + this.contextRunner.withUserConfiguration(CustomOtlpLoggingConnectionDetailsConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(OpenTelemetryLoggingConnectionDetails.class) + .doesNotHaveBean(PropertiesOpenTelemetryLoggingConnectionDetails.class); + OtlpHttpLogRecordExporter otlpHttpLogRecordExporter = context.getBean(OtlpHttpLogRecordExporter.class); + assertThat(otlpHttpLogRecordExporter).extracting("delegate.httpSender.url") + .isEqualTo(HttpUrl.get("https://otel.example.com/v1/logs")); + }); + } + + @Test + void whenHasNoTransportPropertySetUsesHttpExporter() { + this.contextRunner + .withPropertyValues("management.opentelemetry.logging.export.endpoint=http://localhost:4318/v1/logs") + .run((context) -> { + assertThat(context).hasSingleBean(OtlpHttpLogRecordExporter.class); + assertThat(context).hasSingleBean(LogRecordExporter.class); + assertThat(context).doesNotHaveBean(OtlpGrpcLogRecordExporter.class); + }); + } + + @Test + void whenHasTransportPropertySetToHttpUsesHttpExporter() { + this.contextRunner + .withPropertyValues("management.opentelemetry.logging.export.endpoint=http://localhost:4318/v1/logs", + "management.opentelemetry.logging.export.transport=http") + .run((context) -> { + assertThat(context).hasSingleBean(OtlpHttpLogRecordExporter.class); + assertThat(context).hasSingleBean(LogRecordExporter.class); + assertThat(context).doesNotHaveBean(OtlpGrpcLogRecordExporter.class); + }); + } + + @Test + void whenHasTransportPropertySetToGrpcUsesGrpcExporter() { + this.contextRunner + .withPropertyValues("management.opentelemetry.logging.export.endpoint=http://localhost:4318/v1/logs", + "management.opentelemetry.logging.export.transport=grpc") + .run((context) -> { + assertThat(context).hasSingleBean(OtlpGrpcLogRecordExporter.class); + assertThat(context).hasSingleBean(LogRecordExporter.class); + assertThat(context).doesNotHaveBean(OtlpHttpLogRecordExporter.class); + }); + } + + @Test + void whenHasMeterProviderBeanAddsItToHttpExporter() { + this.contextRunner.withUserConfiguration(MeterProviderConfiguration.class) + .withPropertyValues("management.opentelemetry.logging.export.endpoint=http://localhost:4318/v1/logs") + .run((context) -> { + OtlpHttpLogRecordExporter otlpHttpLogRecordExporter = context.getBean(OtlpHttpLogRecordExporter.class); + assertThat(otlpHttpLogRecordExporter.toBuilder()) + .extracting("delegate.meterProviderSupplier", InstanceOfAssertFactories.type(Supplier.class)) + .satisfies((meterProviderSupplier) -> assertThat(meterProviderSupplier.get()) + .isSameAs(MeterProviderConfiguration.meterProvider)); + }); + } + + @Test + void whenHasMeterProviderBeanAddsItToGrpcExporter() { + this.contextRunner.withUserConfiguration(MeterProviderConfiguration.class) + .withPropertyValues("management.opentelemetry.logging.export.endpoint=http://localhost:4318/v1/logs", + "management.opentelemetry.logging.export.transport=grpc") + .run((context) -> { + OtlpGrpcLogRecordExporter otlpGrpcLogRecordExporter = context.getBean(OtlpGrpcLogRecordExporter.class); + assertThat(otlpGrpcLogRecordExporter.toBuilder()) + .extracting("delegate.meterProviderSupplier", InstanceOfAssertFactories.type(Supplier.class)) + .satisfies((meterProviderSupplier) -> assertThat(meterProviderSupplier.get()) + .isSameAs(MeterProviderConfiguration.meterProvider)); + }); + } + + @Configuration(proxyBeanMethods = false) + public static class MultipleSdkLoggerProviderBuilderCustomizersConfig { + + @Bean + public SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer1() { + return new NoopSdkLoggerProviderBuilderCustomizer(); + } + + @Bean + public SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer2() { + return new NoopSdkLoggerProviderBuilderCustomizer(); + } + + } + + static class NoopSdkLoggerProviderBuilderCustomizer implements SdkLoggerProviderBuilderCustomizer { + + final AtomicInteger called = new AtomicInteger(0); + + @Override + public void customize(SdkLoggerProviderBuilder builder) { + this.called.incrementAndGet(); + } + + int called() { + return this.called.get(); + } + + } + + @Configuration(proxyBeanMethods = false) + private static final class MeterProviderConfiguration { + + static final MeterProvider meterProvider = (instrumentationScopeName) -> null; + + @Bean + MeterProvider meterProvider() { + return meterProvider; + } + + } + + @Configuration(proxyBeanMethods = false) + private static final class CustomHttpExporterConfiguration { + + @Bean + OtlpHttpLogRecordExporter customOtlpHttpLogRecordExporter() { + return OtlpHttpLogRecordExporter.builder().build(); + } + + } + + @Configuration(proxyBeanMethods = false) + private static final class CustomGrpcExporterConfiguration { + + @Bean + OtlpGrpcLogRecordExporter customOtlpGrpcLogRecordExporter() { + return OtlpGrpcLogRecordExporter.builder().build(); + } + + } + + @Configuration(proxyBeanMethods = false) + private static final class CustomOtlpLoggingConnectionDetailsConfiguration { + + @Bean + OpenTelemetryLoggingConnectionDetails customOtlpLoggingConnectionDetails() { + return (transport) -> "https://otel.example.com/v1/logs"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-parent/build.gradle b/spring-boot-project/spring-boot-parent/build.gradle index 270b2be19eee..9ee51abac484 100644 --- a/spring-boot-project/spring-boot-parent/build.gradle +++ b/spring-boot-project/spring-boot-parent/build.gradle @@ -84,6 +84,13 @@ bom { ] } } + library("Findbugs JSR 305", "3.0.2") { + group("com.google.code.findbugs") { + modules = [ + "jsr305" + ] + } + } library("Janino", "3.1.12") { group("org.codehaus.janino") { bom("janino") { diff --git a/spring-boot-project/spring-boot-pulsar/build.gradle b/spring-boot-project/spring-boot-pulsar/build.gradle new file mode 100644 index 000000000000..dcd51153315d --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/build.gradle @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Pulsar" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.pulsar:spring-pulsar") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("org.springframework.pulsar:spring-pulsar-reactive") + optional("org.testcontainers:pulsar") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:pulsar") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("com.github.ben-manes.caffeine:caffeine") + testImplementation("org.springframework.pulsar:spring-pulsar-cache-provider-caffeine") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationIntegrationTests.java new file mode 100644 index 000000000000..a6fccaccf6b5 --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationIntegrationTests.java @@ -0,0 +1,105 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.pulsar; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.PulsarContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.pulsar.autoconfigure.PulsarAutoConfiguration; +import org.springframework.boot.pulsar.autoconfigure.PulsarReactiveAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.pulsar.annotation.PulsarListener; +import org.springframework.pulsar.core.PulsarTemplate; +import org.springframework.stereotype.Service; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link PulsarAutoConfiguration}. + * + * @author Chris Bono + * @author Phillip Webb + */ +@SpringBootTest +@Testcontainers(disabledWithoutDocker = true) +class PulsarAutoConfigurationIntegrationTests { + + @Container + static final PulsarContainer pulsar = TestImage.container(PulsarContainer.class); + + private static final CountDownLatch listenLatch = new CountDownLatch(1); + + private static final String TOPIC = "pacit-hello-topic"; + + @DynamicPropertySource + static void pulsarProperties(DynamicPropertyRegistry registry) { + registry.add("spring.pulsar.client.service-url", pulsar::getPulsarBrokerUrl); + registry.add("spring.pulsar.admin.service-url", pulsar::getHttpServiceUrl); + } + + @Test + void appStartsWithAutoConfiguredSpringPulsarComponents( + @Autowired(required = false) PulsarTemplate pulsarTemplate) { + assertThat(pulsarTemplate).isNotNull(); + } + + @Test + void sendAndReceive(@Autowired TestService testService) throws InterruptedException { + assertThat(testService.sayHello()).startsWith("Hello World -> "); + assertThat(listenLatch.await(5, TimeUnit.SECONDS)).isTrue(); + } + + @Configuration(proxyBeanMethods = false) + @ImportAutoConfiguration({ PulsarAutoConfiguration.class, PulsarReactiveAutoConfiguration.class }) + @Import(TestService.class) + static class TestConfiguration { + + @PulsarListener(subscriptionName = TOPIC + "-sub", topics = TOPIC) + void listen(String ignored) { + listenLatch.countDown(); + } + + } + + @Service + static class TestService { + + private final PulsarTemplate pulsarTemplate; + + TestService(PulsarTemplate pulsarTemplate) { + this.pulsarTemplate = pulsarTemplate; + } + + String sayHello() { + return "Hello World -> " + this.pulsarTemplate.send(TOPIC, "hello"); + } + + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/pulsar/PulsarDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/pulsar/docker/compose/PulsarDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 90% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/pulsar/PulsarDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/pulsar/docker/compose/PulsarDockerComposeConnectionDetailsFactoryIntegrationTests.java index 48fe9c59591a..709ab3107c92 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/pulsar/PulsarDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/pulsar/docker/compose/PulsarDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.pulsar; +package org.springframework.boot.pulsar.docker.compose; -import org.springframework.boot.autoconfigure.pulsar.PulsarConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.pulsar.autoconfigure.PulsarConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/pulsar/PulsarContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/pulsar/testcontainers/PulsarContainerConnectionDetailsFactoryIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/pulsar/PulsarContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/pulsar/testcontainers/PulsarContainerConnectionDetailsFactoryIntegrationTests.java index 06fe31adc556..532c2941a5ce 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/pulsar/PulsarContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/dockerTest/java/org/springframework/boot/pulsar/testcontainers/PulsarContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.pulsar; +package org.springframework.boot.pulsar.testcontainers; import java.time.Duration; import java.util.ArrayList; @@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.pulsar.PulsarAutoConfiguration; +import org.springframework.boot.pulsar.autoconfigure.PulsarAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-pulsar/src/dockerTest/resources/logback-test.xml b/spring-boot-project/spring-boot-pulsar/src/dockerTest/resources/logback-test.xml new file mode 100644 index 000000000000..b8a41480d7d6 --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/dockerTest/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/pulsar/pulsar-compose.yaml b/spring-boot-project/spring-boot-pulsar/src/dockerTest/resources/org/springframework/boot/pulsar/docker/compose/pulsar-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/pulsar/pulsar-compose.yaml rename to spring-boot-project/spring-boot-pulsar/src/dockerTest/resources/org/springframework/boot/pulsar/docker/compose/pulsar-compose.yaml diff --git a/spring-boot-project/spring-boot-pulsar/src/dockerTest/resources/spring.properties b/spring-boot-project/spring-boot-pulsar/src/dockerTest/resources/spring.properties new file mode 100644 index 000000000000..47dff33f0bb5 --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/dockerTest/resources/spring.properties @@ -0,0 +1 @@ +spring.test.context.cache.maxSize=1 \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/DeadLetterPolicyMapper.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/DeadLetterPolicyMapper.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/DeadLetterPolicyMapper.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/DeadLetterPolicyMapper.java index bc87c07112ea..15cb85ad8254 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/DeadLetterPolicyMapper.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/DeadLetterPolicyMapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import org.apache.pulsar.client.api.DeadLetterPolicy; import org.apache.pulsar.client.api.DeadLetterPolicy.DeadLetterPolicyBuilder; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PropertiesPulsarConnectionDetails.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PropertiesPulsarConnectionDetails.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PropertiesPulsarConnectionDetails.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PropertiesPulsarConnectionDetails.java index 38ab9c631e9e..31b538bd44dc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PropertiesPulsarConnectionDetails.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PropertiesPulsarConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; /** * Adapts {@link PulsarProperties} to {@link PulsarConnectionDetails}. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfiguration.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarAutoConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfiguration.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarAutoConfiguration.java index 153f81dbf658..244dd89644ad 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfiguration.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.util.ArrayList; import java.util.List; @@ -69,7 +69,7 @@ * @author Alexander Preuß * @author Phillip Webb * @author Jonas Geiregat - * @since 3.2.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ PulsarClient.class, PulsarTemplate.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarConfiguration.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarConfiguration.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarConfiguration.java index adefeda707d9..322832803695 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarConfiguration.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.util.ArrayList; import java.util.List; @@ -30,9 +30,9 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Defaults.SchemaInfo; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Defaults.TypeMapping; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Defaults.SchemaInfo; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Defaults.TypeMapping; import org.springframework.boot.util.LambdaSafe; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarConnectionDetails.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarConnectionDetails.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarConnectionDetails.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarConnectionDetails.java index a8abdbd07328..73802daa1d81 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarConnectionDetails.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; @@ -22,7 +22,7 @@ * Details required to establish a connection to a Pulsar service. * * @author Chris Bono - * @since 3.2.0 + * @since 4.0.0 */ public interface PulsarConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizer.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizer.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizer.java index bdcfa2ffc513..17e13f10772e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import org.springframework.pulsar.config.PulsarContainerFactory; @@ -25,7 +25,7 @@ * * @param the type of the {@link PulsarContainerFactory} * @author Chris Bono - * @since 3.4.0 + * @since 4.0.0 */ @FunctionalInterface public interface PulsarContainerFactoryCustomizer> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizers.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizers.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizers.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizers.java index 5ed31e44752a..bb07d5b08e6d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizers.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizers.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.util.ArrayList; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarProperties.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarProperties.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarProperties.java index d2a8967f0967..9437aeae084d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarProperties.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -45,7 +45,7 @@ * @author Phillip Webb * @author Swamy Mavuri * @author Vedran Pavic - * @since 3.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.pulsar") public class PulsarProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesMapper.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesMapper.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesMapper.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesMapper.java index 9d75b1953620..4f18f4dea00b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesMapper.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesMapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.time.Duration; import java.util.ArrayList; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactiveAutoConfiguration.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactiveAutoConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactiveAutoConfiguration.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactiveAutoConfiguration.java index 20589fc54f8d..6bbb01a7fa5f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactiveAutoConfiguration.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactiveAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -65,7 +65,7 @@ * * @author Chris Bono * @author Christophe Bornet - * @since 3.2.0 + * @since 4.0.0 */ @AutoConfiguration(after = PulsarAutoConfiguration.class) @ConditionalOnClass({ PulsarClient.class, ReactivePulsarClient.class, ReactivePulsarTemplate.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactivePropertiesMapper.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactivePropertiesMapper.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactivePropertiesMapper.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactivePropertiesMapper.java index 5b0640ae167a..4300ff4d23b8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactivePropertiesMapper.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactivePropertiesMapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.util.ArrayList; diff --git a/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/package-info.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/package-info.java new file mode 100644 index 000000000000..276d47adcb2a --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring for Apache Pulsar. + */ +package org.springframework.boot.pulsar.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/pulsar/PulsarDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/docker/compose/PulsarDockerComposeConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/pulsar/PulsarDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/docker/compose/PulsarDockerComposeConnectionDetailsFactory.java index 3c69dc6aab1c..d41d6d78bec5 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/pulsar/PulsarDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/docker/compose/PulsarDockerComposeConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.pulsar; +package org.springframework.boot.pulsar.docker.compose; -import org.springframework.boot.autoconfigure.pulsar.PulsarConnectionDetails; import org.springframework.boot.docker.compose.core.ConnectionPorts; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.pulsar.autoconfigure.PulsarConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link PulsarConnectionDetails} diff --git a/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/docker/compose/package-info.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/docker/compose/package-info.java new file mode 100644 index 000000000000..d81d5d8e1ff4 --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Pulsar service connections. + */ +package org.springframework.boot.pulsar.docker.compose; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/pulsar/PulsarContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/testcontainers/PulsarContainerConnectionDetailsFactory.java similarity index 93% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/pulsar/PulsarContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/testcontainers/PulsarContainerConnectionDetailsFactory.java index cfc0acfa5d85..6bc45179a5e9 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/pulsar/PulsarContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/testcontainers/PulsarContainerConnectionDetailsFactory.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.pulsar; +package org.springframework.boot.pulsar.testcontainers; import org.testcontainers.containers.PulsarContainer; -import org.springframework.boot.autoconfigure.pulsar.PulsarConnectionDetails; +import org.springframework.boot.pulsar.autoconfigure.PulsarConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/testcontainers/package-info.java b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/testcontainers/package-info.java new file mode 100644 index 000000000000..8cde01f0ddcf --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/main/java/org/springframework/boot/pulsar/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Pulsar service connections. + */ +package org.springframework.boot.pulsar.testcontainers; diff --git a/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..1f37b2f6abc0 --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,22 @@ +{ + "properties": [ + { + "name": "spring.pulsar.defaults.topic.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable default tenant and namespace support for topics.", + "defaultValue": true + }, + { + "name": "spring.pulsar.function.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable function support.", + "defaultValue": true + }, + { + "name": "spring.pulsar.producer.cache.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable caching in the PulsarProducerFactory.", + "defaultValue": true + } + ] +} diff --git a/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..ceb868e08f08 --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.pulsar.docker.compose.PulsarDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.pulsar.testcontainers.PulsarContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..97d91ee0c43a --- /dev/null +++ b/spring-boot-project/spring-boot-pulsar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.pulsar.autoconfigure.PulsarAutoConfiguration +org.springframework.boot.pulsar.autoconfigure.PulsarReactiveAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/Customizers.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/Customizers.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/Customizers.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/Customizers.java index 0a8c54d6499e..9a7f35a8a104 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/Customizers.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/Customizers.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.util.List; import java.util.function.BiConsumer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/DeadLetterPolicyMapperTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/DeadLetterPolicyMapperTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/DeadLetterPolicyMapperTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/DeadLetterPolicyMapperTests.java index 20dbf8f67ef4..7f4acdd6151c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/DeadLetterPolicyMapperTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/DeadLetterPolicyMapperTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import org.apache.pulsar.client.api.DeadLetterPolicy; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/MockAuthentication.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/MockAuthentication.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/MockAuthentication.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/MockAuthentication.java index 0fe4b1e6c868..6f35a0a659cb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/MockAuthentication.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/MockAuthentication.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.io.IOException; import java.util.HashMap; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PropertiesPulsarConnectionDetailsTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PropertiesPulsarConnectionDetailsTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PropertiesPulsarConnectionDetailsTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PropertiesPulsarConnectionDetailsTests.java index 5f256cbf0f81..7d0740e13bb2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PropertiesPulsarConnectionDetailsTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PropertiesPulsarConnectionDetailsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarAutoConfigurationTests.java index abf3318c2013..3435fb72f42b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarConfigurationTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarConfigurationTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarConfigurationTests.java index e59d8738c609..1f37f474b142 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarConfigurationTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -139,7 +139,8 @@ void whenHasUserDefinedFailoverPropertiesAddsToClient() { "spring.pulsar.client.failover.switch-back-delay=30s", "spring.pulsar.client.failover.check-interval=5s", "spring.pulsar.client.failover.backup-clusters[1].service-url=backup-cluster-2", - "spring.pulsar.client.failover.backup-clusters[1].authentication.plugin-class-name=org.springframework.boot.autoconfigure.pulsar.MockAuthentication", + "spring.pulsar.client.failover.backup-clusters[1].authentication.plugin-class-name=" + + MockAuthentication.class.getName(), "spring.pulsar.client.failover.backup-clusters[1].authentication.param.token=1234") .run((context) -> { DefaultPulsarClientFactory clientFactory = context.getBean(DefaultPulsarClientFactory.class); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizersTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizersTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizersTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizersTests.java index 5de7cf4afafe..b6893ba84f4c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarContainerFactoryCustomizersTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarContainerFactoryCustomizersTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.util.ArrayList; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesMapperTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesMapperTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesMapperTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesMapperTests.java index 7df9b8347883..f77c55420c44 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesMapperTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesMapperTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.time.Duration; import java.util.List; @@ -39,8 +39,8 @@ import org.apache.pulsar.common.schema.SchemaType; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Consumer; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Failover.BackupCluster; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Consumer; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Failover.BackupCluster; import org.springframework.pulsar.core.PulsarProducerFactory; import org.springframework.pulsar.core.PulsarTemplate; import org.springframework.pulsar.listener.PulsarContainerProperties; @@ -134,8 +134,7 @@ void customizeClientBuilderWhenHasFailover() { BackupCluster backupCluster1 = new BackupCluster(); backupCluster1.setServiceUrl("backup-cluster-1"); Map params = Map.of("param", "name"); - backupCluster1.getAuthentication() - .setPluginClassName("org.springframework.boot.autoconfigure.pulsar.MockAuthentication"); + backupCluster1.getAuthentication().setPluginClassName(MockAuthentication.class.getName()); backupCluster1.getAuthentication().setParam(params); BackupCluster backupCluster2 = new BackupCluster(); backupCluster2.setServiceUrl("backup-cluster-2"); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesTests.java index cfdde52dab5f..0c26ce7654c0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarPropertiesTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.time.Duration; import java.util.HashMap; @@ -34,13 +34,13 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Defaults.SchemaInfo; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Defaults.TypeMapping; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Failover; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Failover.BackupCluster; import org.springframework.boot.context.properties.bind.BindException; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Defaults.SchemaInfo; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Defaults.TypeMapping; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Failover; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Failover.BackupCluster; import org.springframework.pulsar.core.PulsarTopicBuilder; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactiveAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactiveAutoConfigurationTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactiveAutoConfigurationTests.java index e0be4b6c97c6..64174ba01426 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactiveAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.time.Duration; import java.util.ArrayList; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactivePropertiesMapperTests.java b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactivePropertiesMapperTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactivePropertiesMapperTests.java rename to spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactivePropertiesMapperTests.java index 325352473713..9c8a6bf74c27 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/pulsar/PulsarReactivePropertiesMapperTests.java +++ b/spring-boot-project/spring-boot-pulsar/src/test/java/org/springframework/boot/pulsar/autoconfigure/PulsarReactivePropertiesMapperTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.pulsar; +package org.springframework.boot.pulsar.autoconfigure; import java.time.Duration; import java.util.List; @@ -35,8 +35,8 @@ import org.apache.pulsar.reactive.client.api.ReactiveMessageSenderBuilder; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Consumer; -import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Consumer.Subscription; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Consumer; +import org.springframework.boot.pulsar.autoconfigure.PulsarProperties.Consumer.Subscription; import org.springframework.pulsar.reactive.listener.ReactivePulsarContainerProperties; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-quartz/build.gradle b/spring-boot-project/spring-boot-quartz/build.gradle new file mode 100644 index 000000000000..913624aab3ab --- /dev/null +++ b/spring-boot-project/spring-boot-quartz/build.gradle @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Quartz" + +dependencies { + api(project(":spring-boot-project:spring-boot-tx")) + api("org.quartz-scheduler:quartz") + api("org.springframework:spring-context-support") + + implementation(project(":spring-boot-project:spring-boot-sql")) + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-jdbc")) + optional(project(":spring-boot-project:spring-boot-hibernate")) + + testImplementation(project(":spring-boot-project:spring-boot-flyway")) + testImplementation(project(":spring-boot-project:spring-boot-liquibase")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) + testImplementation("net.minidev:json-smart") + testImplementation("org.springframework:spring-web") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.h2database:h2") + testRuntimeOnly("com.zaxxer:HikariCP") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/JobStoreType.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/JobStoreType.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/JobStoreType.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/JobStoreType.java index 596e0ec676d1..4ef05755e47f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/JobStoreType.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/JobStoreType.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; /** * Define the supported Quartz {@code JobStore}. * * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public enum JobStoreType { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzAutoConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzAutoConfiguration.java index a06d965b3dc4..f8e693aa01f0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import java.util.Map; import java.util.Properties; @@ -33,12 +33,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.sql.autoconfigure.init.OnDatabaseInitializationCondition; import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -55,10 +51,10 @@ * * @author Vedran Pavic * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, - LiquibaseAutoConfiguration.class, FlywayAutoConfiguration.class }) +@AutoConfiguration(afterName = { "org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration", + "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration" }) @ConditionalOnClass({ Scheduler.class, SchedulerFactoryBean.class, PlatformTransactionManager.class }) @EnableConfigurationProperties(QuartzProperties.class) public class QuartzAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSource.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSource.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSource.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSource.java index 3f4422f91ff7..32ff091b3794 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSource.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSource.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -31,7 +31,7 @@ * * @author Madhura Bhave * @see QuartzDataSource - * @since 2.0.2 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSourceScriptDatabaseInitializer.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializer.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSourceScriptDatabaseInitializer.java index 705fa6240699..a457b4d90332 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSourceScriptDatabaseInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import java.util.List; @@ -35,7 +35,7 @@ * @author Vedran Pavic * @author Andy Wilkinson * @author Phillip Webb - * @since 2.6.0 + * @since 4.0.0 */ public class QuartzDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzProperties.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzProperties.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzProperties.java index fa2bc10f32f3..58a94836f8b9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzProperties.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -31,7 +31,7 @@ * * @author Vedran Pavic * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.quartz") public class QuartzProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzTransactionManager.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzTransactionManager.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzTransactionManager.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzTransactionManager.java index 2836aeb2e6c2..42eff3f35ce2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzTransactionManager.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/QuartzTransactionManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -31,7 +31,7 @@ * * @author Andy Wilkinson * @see QuartzDataSource - * @since 2.2.11 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerDependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/SchedulerDependsOnDatabaseInitializationDetector.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerDependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/SchedulerDependsOnDatabaseInitializationDetector.java index 7c99301b7f38..f71117c86555 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerDependsOnDatabaseInitializationDetector.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/SchedulerDependsOnDatabaseInitializationDetector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import java.util.Arrays; import java.util.HashSet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerFactoryBeanCustomizer.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/SchedulerFactoryBeanCustomizer.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerFactoryBeanCustomizer.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/SchedulerFactoryBeanCustomizer.java index ebc004cb5172..d6375d0739a5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerFactoryBeanCustomizer.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/SchedulerFactoryBeanCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import javax.sql.DataSource; @@ -31,7 +31,7 @@ * {@link QuartzDataSourceScriptDatabaseInitializer}. * * @author Vedran Pavic - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface SchedulerFactoryBeanCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointAutoConfiguration.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointAutoConfiguration.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointAutoConfiguration.java index 9dbf90d0fb63..e10ec24d85ab 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure.endpoint; import org.quartz.Scheduler; @@ -22,15 +22,15 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; import org.springframework.boot.actuate.endpoint.SanitizingFunction; -import org.springframework.boot.actuate.quartz.QuartzEndpoint; -import org.springframework.boot.actuate.quartz.QuartzEndpointWebExtension; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.quartz.autoconfigure.QuartzAutoConfiguration; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint; +import org.springframework.boot.quartz.endpoint.QuartzEndpointWebExtension; import org.springframework.context.annotation.Bean; /** @@ -38,10 +38,10 @@ * * @author Vedran Pavic * @author Stephane Nicoll - * @since 2.5.0 + * @since 4.0.0 */ @AutoConfiguration(after = QuartzAutoConfiguration.class) -@ConditionalOnClass(Scheduler.class) +@ConditionalOnClass({ Scheduler.class, QuartzEndpoint.class, ConditionalOnAvailableEndpoint.class }) @ConditionalOnAvailableEndpoint(QuartzEndpoint.class) @EnableConfigurationProperties(QuartzEndpointProperties.class) public class QuartzEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointProperties.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointProperties.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointProperties.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointProperties.java index 77b7780c70d2..02347d01441d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointProperties.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointProperties.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure.endpoint; import java.util.HashSet; import java.util.Set; import org.springframework.boot.actuate.endpoint.Show; -import org.springframework.boot.actuate.quartz.QuartzEndpoint; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint; /** * Configuration properties for {@link QuartzEndpoint}. * * @author Madhura Bhave - * @since 3.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.endpoint.quartz") public class QuartzEndpointProperties { diff --git a/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/package-info.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/package-info.java new file mode 100644 index 000000000000..19ae3c80eb6b --- /dev/null +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Quartz Scheduler endpoint. + */ +package org.springframework.boot.quartz.autoconfigure.endpoint; diff --git a/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/package-info.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/package-info.java new file mode 100644 index 000000000000..87fc620b97de --- /dev/null +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Quartz Scheduler. + */ +package org.springframework.boot.quartz.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpoint.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/QuartzEndpoint.java similarity index 99% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpoint.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/QuartzEndpoint.java index 99de336db049..f7ba6d944e11 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpoint.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/QuartzEndpoint.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.quartz; +package org.springframework.boot.quartz.endpoint; import java.time.Duration; import java.time.Instant; @@ -62,7 +62,7 @@ * * @author Vedran Pavic * @author Stephane Nicoll - * @since 2.5.0 + * @since 4.0.0 */ @Endpoint(id = "quartz") public class QuartzEndpoint { @@ -218,7 +218,6 @@ public QuartzJobDetailsDescriptor quartzJob(String groupName, String jobName, bo * @return a description of the triggered job or {@code null} if the job does not * exist * @throws SchedulerException if there is an error triggering the job - * @since 3.5.0 */ public QuartzJobTriggerDescriptor triggerQuartzJob(String groupName, String jobName) throws SchedulerException { return triggerQuartzJob(JobKey.jobKey(jobName, groupName)); @@ -410,8 +409,6 @@ public String getClassName() { /** * Description of a triggered on-demand {@link Job Quartz Job}. - * - * @since 3.5.0 */ public static final class QuartzJobTriggerDescriptor { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtension.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebExtension.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtension.java rename to spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebExtension.java index b29b8fe70f70..bfade76f277e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebExtension.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.quartz; +package org.springframework.boot.quartz.endpoint; import java.util.Set; @@ -30,18 +30,18 @@ import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzGroupsDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobDetailsDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobGroupSummaryDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzTriggerGroupSummaryDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpointWebExtension.QuartzEndpointWebExtensionRuntimeHints; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzGroupsDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzJobDetailsDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzJobGroupSummaryDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzTriggerGroupSummaryDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpointWebExtension.QuartzEndpointWebExtensionRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; /** * {@link EndpointWebExtension @EndpointWebExtension} for the {@link QuartzEndpoint}. * * @author Stephane Nicoll - * @since 2.5.0 + * @since 4.0.0 */ @EndpointWebExtension(endpoint = QuartzEndpoint.class) @ImportRuntimeHints(QuartzEndpointWebExtensionRuntimeHints.class) @@ -88,7 +88,6 @@ public WebEndpointResponse quartzJobOrTrigger(SecurityContext securityCo * @param state desired state * @return web endpoint response * @throws SchedulerException if there is an error triggering the job - * @since 3.5.0 */ @WriteOperation public WebEndpointResponse triggerQuartzJob(@Selector String jobs, @Selector String group, diff --git a/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/package-info.java b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/package-info.java new file mode 100644 index 000000000000..c75356aba903 --- /dev/null +++ b/spring-boot-project/spring-boot-quartz/src/main/java/org/springframework/boot/quartz/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator endpoint for Quartz Scheduler. + */ +package org.springframework.boot.quartz.endpoint; diff --git a/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..ace8964b50e6 --- /dev/null +++ b/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,16 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.quartz.jdbc.comment-prefix", + "defaultValue": [ + "#", + "--" + ] + }, + { + "name": "spring.quartz.scheduler-name", + "defaultValue": "quartzScheduler" + } + ] +} diff --git a/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..f70b277621fd --- /dev/null +++ b/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Depends on Database Initialization Detectors +org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ +org.springframework.boot.quartz.autoconfigure.SchedulerDependsOnDatabaseInitializationDetector diff --git a/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..e438fb1b8417 --- /dev/null +++ b/spring-boot-project/spring-boot-quartz/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.quartz.autoconfigure.QuartzAutoConfiguration +org.springframework.boot.quartz.autoconfigure.endpoint.QuartzEndpointAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/QuartzAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java rename to spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/QuartzAutoConfigurationTests.java index aa0dbc7d8d93..a22315ad8b7f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/QuartzAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import java.io.InputStream; import java.nio.file.Files; @@ -45,12 +45,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.boot.sql.init.DatabaseInitializationSettings; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSourceScriptDatabaseInitializerTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializerTests.java rename to spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSourceScriptDatabaseInitializerTests.java index d4526666e1b8..69b06819f223 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzDataSourceScriptDatabaseInitializerTests.java +++ b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/QuartzDataSourceScriptDatabaseInitializerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure; import java.util.Arrays; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointAutoConfigurationTests.java rename to spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointAutoConfigurationTests.java index 492a29413632..3aecea8714f9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/quartz/QuartzEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/autoconfigure/endpoint/QuartzEndpointAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.quartz; +package org.springframework.boot.quartz.autoconfigure.endpoint; import java.util.Collections; import java.util.Set; @@ -23,9 +23,9 @@ import org.quartz.Scheduler; import org.springframework.boot.actuate.endpoint.Show; -import org.springframework.boot.actuate.quartz.QuartzEndpoint; -import org.springframework.boot.actuate.quartz.QuartzEndpointWebExtension; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint; +import org.springframework.boot.quartz.endpoint.QuartzEndpointWebExtension; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointTests.java b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointTests.java rename to spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointTests.java index 110547591b16..f0ad60c6e832 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointTests.java +++ b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.quartz; +package org.springframework.boot.quartz.endpoint; import java.time.Duration; import java.time.Instant; @@ -62,12 +62,12 @@ import org.quartz.impl.matchers.GroupMatcher; import org.quartz.spi.OperableTrigger; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobDetailsDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobGroupSummaryDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobSummaryDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobTriggerDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzTriggerGroupSummaryDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzJobDetailsDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzJobGroupSummaryDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzJobSummaryDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzJobTriggerDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzTriggerGroupSummaryDescriptor; import org.springframework.scheduling.quartz.DelegatingJob; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebExtensionTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionTests.java rename to spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebExtensionTests.java index c827010ff783..d070ec3a1786 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionTests.java +++ b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebExtensionTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.quartz; +package org.springframework.boot.quartz.endpoint; import java.security.Principal; import java.util.Collections; @@ -28,11 +28,11 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.Show; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzGroupsDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobDetailsDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobGroupSummaryDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzTriggerGroupSummaryDescriptor; -import org.springframework.boot.actuate.quartz.QuartzEndpointWebExtension.QuartzEndpointWebExtensionRuntimeHints; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzGroupsDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzJobDetailsDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzJobGroupSummaryDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpoint.QuartzTriggerGroupSummaryDescriptor; +import org.springframework.boot.quartz.endpoint.QuartzEndpointWebExtension.QuartzEndpointWebExtensionRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebIntegrationTests.java similarity index 99% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebIntegrationTests.java index f9d3db2fc607..c7b2adb044e8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-quartz/src/test/java/org/springframework/boot/quartz/endpoint/QuartzEndpointWebIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.quartz; +package org.springframework.boot.quartz.endpoint; import java.util.ArrayList; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/quartz/tables_#_comments.sql b/spring-boot-project/spring-boot-quartz/src/test/resources/org/springframework/boot/quartz/autoconfigure/tables_#_comments.sql similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/quartz/tables_#_comments.sql rename to spring-boot-project/spring-boot-quartz/src/test/resources/org/springframework/boot/quartz/autoconfigure/tables_#_comments.sql diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/quartz/tables_--_comments.sql b/spring-boot-project/spring-boot-quartz/src/test/resources/org/springframework/boot/quartz/autoconfigure/tables_--_comments.sql similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/quartz/tables_--_comments.sql rename to spring-boot-project/spring-boot-quartz/src/test/resources/org/springframework/boot/quartz/autoconfigure/tables_--_comments.sql diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/quartz/tables_custom_comment_prefix.sql b/spring-boot-project/spring-boot-quartz/src/test/resources/org/springframework/boot/quartz/autoconfigure/tables_custom_comment_prefix.sql similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/quartz/tables_custom_comment_prefix.sql rename to spring-boot-project/spring-boot-quartz/src/test/resources/org/springframework/boot/quartz/autoconfigure/tables_custom_comment_prefix.sql diff --git a/spring-boot-project/spring-boot-r2dbc/build.gradle b/spring-boot-project/spring-boot-r2dbc/build.gradle new file mode 100644 index 000000000000..e86ba797431a --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/build.gradle @@ -0,0 +1,82 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "java-test-fixtures" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot R2DBC" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-sql")) + api(project(":spring-boot-project:spring-boot-tx")) + api("org.springframework:spring-r2dbc") + api("org.springframework:spring-r2dbc") + + compileOnly("com.fasterxml.jackson.core:jackson-annotations") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-jdbc")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-observation")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("io.micrometer:micrometer-core") + optional("io.r2dbc:r2dbc-pool") + optional("io.r2dbc:r2dbc-proxy") + optional("io.r2dbc:r2dbc-spi") + optional("org.testcontainers:clickhouse") + optional("org.testcontainers:jdbc") + optional("org.testcontainers:mariadb") + optional("org.testcontainers:mssqlserver") + optional("org.testcontainers:mysql") + optional("org.testcontainers:oracle-xe") + optional("org.testcontainers:oracle-free") + optional("org.testcontainers:postgresql") + optional("org.testcontainers:r2dbc") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-jdbc")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestRuntimeOnly("com.clickhouse:clickhouse-r2dbc") + dockerTestRuntimeOnly("com.oracle.database.r2dbc:oracle-r2dbc") + dockerTestRuntimeOnly("io.r2dbc:r2dbc-mssql") + dockerTestRuntimeOnly("org.postgresql:r2dbc-postgresql") + + testCompileOnly("com.fasterxml.jackson.core:jackson-annotations") + + testImplementation(project(":spring-boot-project:spring-boot-jdbc")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-sql"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-testcontainers"))) + testImplementation("io.projectreactor:reactor-test") + testImplementation("io.r2dbc:r2dbc-h2") + testImplementation("org.postgresql:r2dbc-postgresql") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 710548c34b98..c33dd889d5c2 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.clickhouse; +package org.springframework.boot.r2dbc.docker.compose; import java.time.Duration; @@ -23,9 +23,9 @@ import io.r2dbc.spi.ConnectionFactoryOptions; import reactor.core.publisher.Mono; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 00c468eb3712..145c016e0fc1 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mariadb; +package org.springframework.boot.r2dbc.docker.compose; import io.r2dbc.spi.ConnectionFactoryOptions; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 0a448044da0b..ce1d0a8ec01b 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mysql; +package org.springframework.boot.r2dbc.docker.compose; import io.r2dbc.spi.ConnectionFactoryOptions; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 143fd9698a61..050358b9902d 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.r2dbc.docker.compose; import java.time.Duration; @@ -22,9 +22,9 @@ import io.r2dbc.spi.ConnectionFactoryOptions; import org.awaitility.Awaitility; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.r2dbc.core.DatabaseClient; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 859edff06869..f87a421d0920 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.r2dbc.docker.compose; import java.time.Duration; @@ -23,9 +23,9 @@ import org.awaitility.Awaitility; import org.junit.jupiter.api.condition.OS; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.r2dbc.core.DatabaseClient; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 96% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 94e328bc278d..53b70295face 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.postgres; +package org.springframework.boot.r2dbc.docker.compose; import java.time.Duration; @@ -22,9 +22,9 @@ import io.r2dbc.spi.ConnectionFactoryOptions; import io.r2dbc.spi.Option; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.r2dbc.core.DatabaseClient; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 9869e5ac5194..63e3a1056fac 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.sqlserver; +package org.springframework.boot.r2dbc.docker.compose; import java.time.Duration; @@ -22,9 +22,9 @@ import io.r2dbc.spi.ConnectionFactoryOptions; import org.junit.jupiter.api.condition.OS; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.r2dbc.core.DatabaseClient; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java index 27f46bdbc1d9..ce912b374791 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import java.time.Duration; @@ -26,8 +26,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java index 4587af2c098f..3b2f22758a78 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import java.time.Duration; @@ -27,8 +27,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.junit.DisabledOnOs; diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/clickhouse-bitnami-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/clickhouse-bitnami-compose.yaml new file mode 100644 index 000000000000..2d56633e7c47 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/clickhouse-bitnami-compose.yaml @@ -0,0 +1,9 @@ +services: + database: + image: '{imageName}' + ports: + - '8123' + environment: + - 'CLICKHOUSE_USER=myuser' + - 'CLICKHOUSE_PASSWORD=secret' + - 'CLICKHOUSE_DB=mydatabase' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/clickhouse-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/clickhouse-compose.yaml new file mode 100644 index 000000000000..2d56633e7c47 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/clickhouse-compose.yaml @@ -0,0 +1,9 @@ +services: + database: + image: '{imageName}' + ports: + - '8123' + environment: + - 'CLICKHOUSE_USER=myuser' + - 'CLICKHOUSE_PASSWORD=secret' + - 'CLICKHOUSE_DB=mydatabase' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-bitnami-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-bitnami-compose.yaml new file mode 100644 index 000000000000..64406055b950 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-bitnami-compose.yaml @@ -0,0 +1,10 @@ +services: + database: + image: '{imageName}' + ports: + - '3306' + environment: + - 'MARIADB_ROOT_PASSWORD=verysecret' + - 'MARIADB_USER=myuser' + - 'MARIADB_PASSWORD=secret' + - 'MARIADB_DATABASE=mydatabase' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-compose.yaml new file mode 100644 index 000000000000..c63fd81224b7 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-compose.yaml @@ -0,0 +1,11 @@ +services: + database: + image: '{imageName}' + ports: + - '3306' + environment: + - 'MARIADB_ROOT_PASSWORD=verysecret' + - 'MARIADB_USER=myuser' + - 'MARIADB_PASSWORD=secret' + - 'MARIADB_DATABASE=mydatabase' + diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mssqlserver-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mssqlserver-compose.yaml new file mode 100644 index 000000000000..672b27ad78fb --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mssqlserver-compose.yaml @@ -0,0 +1,9 @@ +services: + database: + image: '{imageName}' + ports: + - '1433' + environment: + - 'MSSQL_PID=express' + - 'MSSQL_SA_PASSWORD=verYs3cret' + - 'ACCEPT_EULA=yes' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mssqlserver-with-jdbc-parameters-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mssqlserver-with-jdbc-parameters-compose.yaml new file mode 100644 index 000000000000..76dd4998aeea --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mssqlserver-with-jdbc-parameters-compose.yaml @@ -0,0 +1,11 @@ +services: + database: + image: '{imageName}' + ports: + - '1433' + environment: + - 'MSSQL_PID=express' + - 'MSSQL_SA_PASSWORD=verYs3cret' + - 'ACCEPT_EULA=yes' + labels: + org.springframework.boot.jdbc.parameters: sendStringParametersAsUnicode=false \ No newline at end of file diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mysql-bitnami-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mysql-bitnami-compose.yaml new file mode 100644 index 000000000000..b0340ed3ed48 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mysql-bitnami-compose.yaml @@ -0,0 +1,10 @@ +services: + database: + image: '{imageName}' + ports: + - '3306' + environment: + - 'MYSQL_ROOT_PASSWORD=verysecret' + - 'MYSQL_USER=myuser' + - 'MYSQL_PASSWORD=secret' + - 'MYSQL_DATABASE=mydatabase' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mysql-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mysql-compose.yaml new file mode 100644 index 000000000000..b0340ed3ed48 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mysql-compose.yaml @@ -0,0 +1,10 @@ +services: + database: + image: '{imageName}' + ports: + - '3306' + environment: + - 'MYSQL_ROOT_PASSWORD=verysecret' + - 'MYSQL_USER=myuser' + - 'MYSQL_PASSWORD=secret' + - 'MYSQL_DATABASE=mydatabase' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/oracle-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/oracle-compose.yaml new file mode 100644 index 000000000000..1cfa3ca87a15 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/oracle-compose.yaml @@ -0,0 +1,15 @@ +services: + database: + image: '{imageName}' + ports: + - '1521' + environment: + - 'APP_USER=app_user' + - 'APP_USER_PASSWORD=app_user_secret' + - 'ORACLE_PASSWORD=secret' + healthcheck: + test: ["CMD-SHELL", "healthcheck.sh"] + interval: 10s + timeout: 5s + retries: 10 + diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/otlp-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/otlp-compose.yaml new file mode 100644 index 000000000000..86e05475417d --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/otlp-compose.yaml @@ -0,0 +1,6 @@ +services: + otlp: + image: '{imageName}' + ports: + - '4317' + - '4318' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-application-name-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-application-name-compose.yaml new file mode 100644 index 000000000000..2b7721344111 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-application-name-compose.yaml @@ -0,0 +1,12 @@ +services: + database: + image: '{imageName}' + ports: + - '5432' + environment: + - 'POSTGRES_USER=myuser' + - 'POSTGRES_DB=mydatabase' + - 'POSTGRES_PASSWORD=secret' + labels: + org.springframework.boot.jdbc.parameters: 'ApplicationName=spring+boot' + org.springframework.boot.r2dbc.parameters: 'applicationName=spring boot' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-bitnami-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-bitnami-compose.yaml new file mode 100644 index 000000000000..97eca6b3c8b0 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-bitnami-compose.yaml @@ -0,0 +1,9 @@ +services: + database: + image: '{imageName}' + ports: + - '5432' + environment: + - 'POSTGRESQL_USERNAME=myuser' + - 'POSTGRESQL_DATABASE=mydatabase' + - 'POSTGRESQL_PASSWORD=secret' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-compose.yaml new file mode 100644 index 000000000000..cb721c823b23 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-compose.yaml @@ -0,0 +1,9 @@ +services: + database: + image: '{imageName}' + ports: + - '5432' + environment: + - 'POSTGRES_USER=myuser' + - 'POSTGRES_DB=mydatabase' + - 'POSTGRES_PASSWORD=secret' diff --git a/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-with-trust-host-auth-method-compose.yaml b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-with-trust-host-auth-method-compose.yaml new file mode 100644 index 000000000000..7a9607dcdcb0 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/postgres-with-trust-host-auth-method-compose.yaml @@ -0,0 +1,9 @@ +services: + database: + image: '{imageName}' + ports: + - '5432' + environment: + - 'POSTGRES_USER=myuser' + - 'POSTGRES_DB=mydatabase' + - 'POSTGRES_HOST_AUTH_METHOD=trust' diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/ConnectionFactoryBuilder.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/ConnectionFactoryBuilder.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/ConnectionFactoryBuilder.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/ConnectionFactoryBuilder.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/ConnectionFactoryDecorator.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/ConnectionFactoryDecorator.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/ConnectionFactoryDecorator.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/ConnectionFactoryDecorator.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/EmbeddedDatabaseConnection.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/EmbeddedDatabaseConnection.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/EmbeddedDatabaseConnection.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/EmbeddedDatabaseConnection.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/OptionsCapableConnectionFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/OptionsCapableConnectionFactory.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/OptionsCapableConnectionFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/OptionsCapableConnectionFactory.java diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ApplicationR2dbcScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ApplicationR2dbcScriptDatabaseInitializer.java new file mode 100644 index 000000000000..b7c496654c21 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ApplicationR2dbcScriptDatabaseInitializer.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.autoconfigure; + +import io.r2dbc.spi.ConnectionFactory; + +import org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializer; +import org.springframework.boot.sql.autoconfigure.init.ApplicationScriptDatabaseInitializer; +import org.springframework.boot.sql.autoconfigure.init.SqlInitializationProperties; +import org.springframework.boot.sql.init.DatabaseInitializationSettings; + +/** + * {@link R2dbcScriptDatabaseInitializer} for the primary SQL database. May be registered + * as a bean to override auto-configuration. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 4.0.0 + */ +public class ApplicationR2dbcScriptDatabaseInitializer extends R2dbcScriptDatabaseInitializer + implements ApplicationScriptDatabaseInitializer { + + /** + * Create a new {@code ApplicationR2dbcScriptDatabaseInitializer} instance. + * @param connectionFactory the primary SQL connection factory + * @param properties the SQL initialization properties + */ + public ApplicationR2dbcScriptDatabaseInitializer(ConnectionFactory connectionFactory, + SqlInitializationProperties properties) { + super(connectionFactory, ApplicationScriptDatabaseInitializer.getSettings(properties)); + } + + /** + * Create a new {@code ApplicationR2dbcScriptDatabaseInitializer} instance. + * @param connectionFactory the primary SQL connection factory + * @param settings the database initialization settings + */ + public ApplicationR2dbcScriptDatabaseInitializer(ConnectionFactory connectionFactory, + DatabaseInitializationSettings settings) { + super(connectionFactory, settings); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryBeanCreationFailureAnalyzer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryBeanCreationFailureAnalyzer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryBeanCreationFailureAnalyzer.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryBeanCreationFailureAnalyzer.java index aaad5690df5a..0860c6e95e46 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryBeanCreationFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryBeanCreationFailureAnalyzer.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; -import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsInitializer.ConnectionFactoryBeanCreationException; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; import org.springframework.boot.r2dbc.EmbeddedDatabaseConnection; +import org.springframework.boot.r2dbc.autoconfigure.ConnectionFactoryOptionsInitializer.ConnectionFactoryBeanCreationException; import org.springframework.core.env.Environment; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryConfigurations.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryConfigurations.java index 86a4113d6e72..67e508926b74 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import java.util.List; @@ -28,13 +28,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcProperties.Pool; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.context.properties.bind.BindResult; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.r2dbc.ConnectionFactoryDecorator; import org.springframework.boot.r2dbc.EmbeddedDatabaseConnection; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcProperties.Pool; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryDependentConfiguration.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryDependentConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryDependentConfiguration.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryDependentConfiguration.java index a89323bbbc07..1e65ce2183a0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryDependentConfiguration.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryDependentConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import io.r2dbc.spi.ConnectionFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryOptionsBuilderCustomizer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryOptionsBuilderCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryOptionsBuilderCustomizer.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryOptionsBuilderCustomizer.java index fb1291fea7f9..e569ff190910 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryOptionsBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryOptionsBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import io.r2dbc.spi.ConnectionFactoryOptions; import io.r2dbc.spi.ConnectionFactoryOptions.Builder; @@ -25,7 +25,7 @@ * auto-configuration. * * @author Mark Paluch - * @since 2.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface ConnectionFactoryOptionsBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryOptionsInitializer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryOptionsInitializer.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryOptionsInitializer.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryOptionsInitializer.java index 793e796b3014..d0661073b0c7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryOptionsInitializer.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryOptionsInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import java.util.function.Supplier; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyException.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyException.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyException.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyException.java index 58c0efaaf120..55dbeccc9e9b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyException.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; /** * Exception thrown when R2DBC connection pooling has been configured but the diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyFailureAnalyzer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyFailureAnalyzer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyFailureAnalyzer.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyFailureAnalyzer.java index 2449923d6c6a..52e52c59c7b1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsException.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsException.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsException.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsException.java index abf4d5a702fc..3edb4e0ae4dd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsException.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; /** * Exception thrown when R2DBC connection pooling has been configured both by the URL diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsFailureAnalyzer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsFailureAnalyzer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsFailureAnalyzer.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsFailureAnalyzer.java index e90c973ad067..7ddc583e0c8c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/NoConnectionFactoryBeanFailureAnalyzer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/NoConnectionFactoryBeanFailureAnalyzer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/NoConnectionFactoryBeanFailureAnalyzer.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/NoConnectionFactoryBeanFailureAnalyzer.java index 724c962352e6..4992f4712d46 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/NoConnectionFactoryBeanFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/NoConnectionFactoryBeanFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import io.r2dbc.spi.ConnectionFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ProxyConnectionFactoryCustomizer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ProxyConnectionFactoryCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ProxyConnectionFactoryCustomizer.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ProxyConnectionFactoryCustomizer.java index fb11f2e987b4..eccdbc9b8575 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ProxyConnectionFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/ProxyConnectionFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import io.r2dbc.proxy.ProxyConnectionFactory.Builder; @@ -22,7 +22,7 @@ * Callback interface that can be used to customize a {@link Builder}. * * @author Tadaya Tsuyukubo - * @since 3.4.0 + * @since 4.0.0 */ @FunctionalInterface public interface ProxyConnectionFactoryCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfiguration.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfiguration.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfiguration.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfiguration.java index d49c69767ec6..8f7ef53b94ad 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import java.util.function.Predicate; import java.util.function.Supplier; @@ -30,8 +30,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnResource; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -42,9 +40,10 @@ * * @author Mark Paluch * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ -@AutoConfiguration(before = { DataSourceAutoConfiguration.class, SqlInitializationAutoConfiguration.class }) +@AutoConfiguration(before = { R2dbcInitializationAutoConfiguration.class }, + beforeName = "org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration") @ConditionalOnClass(ConnectionFactory.class) @ConditionalOnResource(resources = "classpath:META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider") @EnableConfigurationProperties(R2dbcProperties.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcConnectionDetails.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcConnectionDetails.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcConnectionDetails.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcConnectionDetails.java index df2920d204e3..203d73696de6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcConnectionDetails.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import io.r2dbc.spi.ConnectionFactoryOptions; @@ -26,7 +26,7 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface R2dbcConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcInitializationAutoConfiguration.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcInitializationAutoConfiguration.java new file mode 100644 index 000000000000..fe7e17de45f6 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcInitializationAutoConfiguration.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.autoconfigure; + +import io.r2dbc.spi.ConnectionFactory; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.r2dbc.ConnectionFactoryBuilder; +import org.springframework.boot.sql.autoconfigure.init.ConditionalOnSqlInitialization; +import org.springframework.boot.sql.autoconfigure.init.SqlInitializationProperties; +import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.r2dbc.connection.init.DatabasePopulator; +import org.springframework.util.StringUtils; + +/** + * Auto-configuration for initializing an SQL database accessed through an R2DBC + * {@link ConnectionFactory}. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ConnectionFactory.class, DatabasePopulator.class }) +@ConditionalOnSingleCandidate(ConnectionFactory.class) +@ConditionalOnMissingBean(value = ApplicationR2dbcScriptDatabaseInitializer.class, + type = "org.springframework.boot.jdbc.autoconfigure.ApplicationDataSourceScriptDatabaseInitializer") +@ConditionalOnSqlInitialization +@Import(DatabaseInitializationDependencyConfigurer.class) +@EnableConfigurationProperties(SqlInitializationProperties.class) +public class R2dbcInitializationAutoConfiguration { + + @Bean + ApplicationR2dbcScriptDatabaseInitializer r2dbcScriptDatabaseInitializer(ConnectionFactory connectionFactory, + SqlInitializationProperties properties) { + return new ApplicationR2dbcScriptDatabaseInitializer( + determineConnectionFactory(connectionFactory, properties.getUsername(), properties.getPassword()), + properties); + } + + private static ConnectionFactory determineConnectionFactory(ConnectionFactory connectionFactory, String username, + String password) { + if (StringUtils.hasText(username) && StringUtils.hasText(password)) { + return ConnectionFactoryBuilder.derivedFrom(connectionFactory) + .username(username) + .password(password) + .build(); + } + return connectionFactory; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProperties.java index 7b8b072fe9cd..d24e8d5d0c68 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import java.time.Duration; import java.util.LinkedHashMap; @@ -32,7 +32,7 @@ * @author Andreas Killaitis * @author Stephane Nicoll * @author Rodolpho S. Couto - * @since 2.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.r2dbc") public class R2dbcProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProxyAutoConfiguration.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProxyAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProxyAutoConfiguration.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProxyAutoConfiguration.java index a6dc59790493..b8f4fe5ba4df 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProxyAutoConfiguration.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProxyAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import io.r2dbc.proxy.ProxyConnectionFactory; import io.r2dbc.spi.ConnectionFactory; @@ -31,7 +31,7 @@ * * @author Tadaya Tsuyukubo * @author Moritz Halbritter - * @since 3.4.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ ConnectionFactory.class, ProxyConnectionFactory.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcTransactionManagerAutoConfiguration.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcTransactionManagerAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcTransactionManagerAutoConfiguration.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcTransactionManagerAutoConfiguration.java index 88d33c456c92..83067dc6dee7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcTransactionManagerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcTransactionManagerAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import io.r2dbc.spi.ConnectionFactory; @@ -24,7 +24,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.core.Ordered; import org.springframework.r2dbc.connection.R2dbcTransactionManager; @@ -34,7 +34,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link R2dbcTransactionManager}. * * @author Mark Paluch - * @since 2.3.0 + * @since 4.0.0 */ @AutoConfiguration(before = TransactionAutoConfiguration.class) @ConditionalOnClass({ R2dbcTransactionManager.class, ReactiveTransactionManager.class }) diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/health/ConnectionFactoryHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/health/ConnectionFactoryHealthContributorAutoConfiguration.java new file mode 100644 index 000000000000..613f81e58c93 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/health/ConnectionFactoryHealthContributorAutoConfiguration.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.autoconfigure.health; + +import io.r2dbc.spi.ConnectionFactory; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthContributor; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; +import org.springframework.boot.r2dbc.health.ConnectionFactoryHealthIndicator; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link ConnectionFactoryHealthIndicator}. + * + * @author Mark Paluch + * @since 4.0.0 + */ +@AutoConfiguration(after = R2dbcAutoConfiguration.class) +@ConditionalOnClass({ ConnectionFactory.class, ConditionalOnEnabledHealthIndicator.class }) +@ConditionalOnBean(ConnectionFactory.class) +@ConditionalOnEnabledHealthIndicator("r2dbc") +public class ConnectionFactoryHealthContributorAutoConfiguration + extends CompositeReactiveHealthContributorConfiguration { + + ConnectionFactoryHealthContributorAutoConfiguration() { + super(ConnectionFactoryHealthIndicator::new); + } + + @Bean + @ConditionalOnMissingBean(name = { "r2dbcHealthIndicator", "r2dbcHealthContributor" }) + ReactiveHealthContributor r2dbcHealthContributor(ConfigurableListableBeanFactory beanFactory) { + return createContributor(beanFactory, ConnectionFactory.class); + } + +} diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/health/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/health/package-info.java new file mode 100644 index 000000000000..1a709f60b870 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-Configuration for R2DBC health. + */ +package org.springframework.boot.r2dbc.autoconfigure.health; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/ConnectionPoolMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/metrics/ConnectionPoolMetricsAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/ConnectionPoolMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/metrics/ConnectionPoolMetricsAutoConfiguration.java index 3b05d9ae3c40..640523fb7f9c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/ConnectionPoolMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/metrics/ConnectionPoolMetricsAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure.metrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tags; @@ -25,14 +25,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.metrics.r2dbc.ConnectionPoolMetrics; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; +import org.springframework.boot.r2dbc.metrics.ConnectionPoolMetrics; /** * {@link EnableAutoConfiguration Auto-configuration} for metrics on all available @@ -40,10 +38,10 @@ * * @author Tadaya Tsuyukubo * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class, - R2dbcAutoConfiguration.class }) +@AutoConfiguration(after = R2dbcAutoConfiguration.class, + afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") @ConditionalOnClass({ ConnectionPool.class, MeterRegistry.class }) @ConditionalOnBean({ ConnectionFactory.class, MeterRegistry.class }) public class ConnectionPoolMetricsAutoConfiguration { diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..3e2f0d44aac8 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-Configuration for R2DBC metrics. + */ +package org.springframework.boot.r2dbc.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfiguration.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationAutoConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfiguration.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationAutoConfiguration.java index fae0db3fc266..1179ea302a12 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure.observation; import io.micrometer.observation.ObservationRegistry; import io.r2dbc.proxy.ProxyConnectionFactory; @@ -25,14 +25,13 @@ import io.r2dbc.spi.ConnectionFactoryOptions; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.r2dbc.ProxyConnectionFactoryCustomizer; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.r2dbc.OptionsCapableConnectionFactory; +import org.springframework.boot.r2dbc.autoconfigure.ProxyConnectionFactoryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; @@ -41,16 +40,16 @@ * * @author Moritz Halbritter * @author Tadaya Tsuyukubo - * @since 3.2.0 + * @since 4.0.0 */ -@AutoConfiguration(after = ObservationAutoConfiguration.class) -@ConditionalOnClass({ ConnectionFactory.class, ProxyConnectionFactory.class }) +@AutoConfiguration(afterName = "org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration") +@ConditionalOnClass({ ConnectionFactory.class, ProxyConnectionFactory.class, ObservationRegistry.class }) +@ConditionalOnBean(ObservationRegistry.class) @EnableConfigurationProperties(R2dbcObservationProperties.class) public class R2dbcObservationAutoConfiguration { /** * {@code @Order} value of the observation customizer. - * @since 3.4.0 */ public static final int R2DBC_PROXY_OBSERVATION_CUSTOMIZER_ORDER = 0; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationProperties.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationProperties.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationProperties.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationProperties.java index a7fdf65ca425..45f6bb480f90 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationProperties.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure.observation; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -22,7 +22,7 @@ * Configuration properties for R2DBC observability. * * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ @ConfigurationProperties("management.observations.r2dbc") public class R2dbcObservationProperties { diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/package-info.java new file mode 100644 index 000000000000..acca9702e2cb --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/observation/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-Configuration for R2DBC observations. + */ +package org.springframework.boot.r2dbc.autoconfigure.observation; diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/package-info.java new file mode 100644 index 000000000000..d09254acee04 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-Configuration for R2DBC. + */ +package org.springframework.boot.r2dbc.autoconfigure; diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseEnvironment.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseEnvironment.java new file mode 100644 index 000000000000..b0afa1e7bf8d --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseEnvironment.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * ClickHouse environment details. + * + * @author Stephane Nicoll + */ +class ClickHouseEnvironment { + + private final String username; + + private final String password; + + private final String database; + + ClickHouseEnvironment(Map env) { + this.username = env.getOrDefault("CLICKHOUSE_USER", "default"); + this.password = extractPassword(env); + this.database = env.getOrDefault("CLICKHOUSE_DB", "default"); + } + + private String extractPassword(Map env) { + boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD"); + String password = env.get("CLICKHOUSE_PASSWORD"); + Assert.state(StringUtils.hasLength(password) || allowEmpty, "No ClickHouse password found"); + return (password != null) ? password : ""; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseR2dbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseR2dbcDockerComposeConnectionDetailsFactory.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseR2dbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseR2dbcDockerComposeConnectionDetailsFactory.java index 27c27356618b..0797f6dd95ab 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/clickhouse/ClickHouseR2dbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseR2dbcDockerComposeConnectionDetailsFactory.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.clickhouse; +package org.springframework.boot.r2dbc.docker.compose; import io.r2dbc.spi.ConnectionFactoryOptions; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/r2dbc/ConnectionFactoryOptionsBuilder.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ConnectionFactoryOptionsBuilder.java similarity index 90% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/r2dbc/ConnectionFactoryOptionsBuilder.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ConnectionFactoryOptionsBuilder.java index 1bb6432d3da1..42f499b6e4a4 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/r2dbc/ConnectionFactoryOptionsBuilder.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ConnectionFactoryOptionsBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.r2dbc; +package org.springframework.boot.r2dbc.docker.compose; import java.util.Collections; import java.util.LinkedHashMap; @@ -34,9 +34,8 @@ * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb - * @since 3.1.0 */ -public class ConnectionFactoryOptionsBuilder { +class ConnectionFactoryOptionsBuilder { private static final String PARAMETERS_LABEL = "org.springframework.boot.r2dbc.parameters"; @@ -49,13 +48,13 @@ public class ConnectionFactoryOptionsBuilder { * @param driver the driver * @param containerPort the source container port */ - public ConnectionFactoryOptionsBuilder(String driver, int containerPort) { + ConnectionFactoryOptionsBuilder(String driver, int containerPort) { Assert.notNull(driver, "'driver' must not be null"); this.driver = driver; this.sourcePort = containerPort; } - public ConnectionFactoryOptions build(RunningService service, String database, String user, String password) { + ConnectionFactoryOptions build(RunningService service, String database, String user, String password) { Assert.notNull(service, "'service' must not be null"); Assert.notNull(database, "'database' must not be null"); ConnectionFactoryOptions.Builder builder = ConnectionFactoryOptions.builder() diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java new file mode 100644 index 000000000000..554b598429d0 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * MariaDB environment details. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + */ +class MariaDbEnvironment { + + private final String username; + + private final String password; + + private final String database; + + MariaDbEnvironment(Map env) { + this.username = extractUsername(env); + this.password = extractPassword(env); + this.database = extractDatabase(env); + } + + private String extractUsername(Map env) { + String user = env.get("MARIADB_USER"); + return (user != null) ? user : env.getOrDefault("MYSQL_USER", "root"); + } + + private String extractPassword(Map env) { + Assert.state(!env.containsKey("MARIADB_RANDOM_ROOT_PASSWORD"), "MARIADB_RANDOM_ROOT_PASSWORD is not supported"); + Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported"); + Assert.state(!env.containsKey("MARIADB_ROOT_PASSWORD_HASH"), "MARIADB_ROOT_PASSWORD_HASH is not supported"); + boolean allowEmpty = env.containsKey("MARIADB_ALLOW_EMPTY_PASSWORD") + || env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD"); + String password = env.get("MARIADB_PASSWORD"); + password = (password != null) ? password : env.get("MYSQL_PASSWORD"); + password = (password != null) ? password : env.get("MARIADB_ROOT_PASSWORD"); + password = (password != null) ? password : env.get("MYSQL_ROOT_PASSWORD"); + Assert.state(StringUtils.hasLength(password) || allowEmpty, "No MariaDB password found"); + return (password != null) ? password : ""; + } + + private String extractDatabase(Map env) { + String database = env.get("MARIADB_DATABASE"); + database = (database != null) ? database : env.get("MYSQL_DATABASE"); + Assert.state(database != null, "No MARIADB_DATABASE defined"); + return database; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbR2dbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactory.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbR2dbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactory.java index a9f5ff2cc833..90f51b460dca 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mariadb/MariaDbR2dbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactory.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mariadb; +package org.springframework.boot.r2dbc.docker.compose; import io.r2dbc.spi.ConnectionFactoryOptions; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MySqlEnvironment.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MySqlEnvironment.java new file mode 100644 index 000000000000..78bcc8f7034c --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MySqlEnvironment.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * MySQL environment details. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + */ +class MySqlEnvironment { + + private final String username; + + private final String password; + + private final String database; + + MySqlEnvironment(Map env) { + this.username = env.getOrDefault("MYSQL_USER", "root"); + this.password = extractPassword(env); + this.database = extractDatabase(env); + } + + private String extractPassword(Map env) { + Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported"); + boolean allowEmpty = env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD"); + String password = env.get("MYSQL_PASSWORD"); + password = (password != null) ? password : env.get("MYSQL_ROOT_PASSWORD"); + Assert.state(StringUtils.hasLength(password) || allowEmpty, "No MySQL password found"); + return (password != null) ? password : ""; + } + + private String extractDatabase(Map env) { + String database = env.get("MYSQL_DATABASE"); + Assert.state(database != null, "No MYSQL_DATABASE defined"); + return database; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlR2dbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MySqlR2dbcDockerComposeConnectionDetailsFactory.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlR2dbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MySqlR2dbcDockerComposeConnectionDetailsFactory.java index ff91fd4252e4..5ffb8d42a461 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/mysql/MySqlR2dbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MySqlR2dbcDockerComposeConnectionDetailsFactory.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.mysql; +package org.springframework.boot.r2dbc.docker.compose; import io.r2dbc.spi.ConnectionFactoryOptions; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleContainer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleContainer.java new file mode 100644 index 000000000000..63afbc6875b9 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleContainer.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +/** + * Enumeration of supported Oracle containers. + * + * @author Andy Wilkinson + */ +enum OracleContainer { + + FREE("gvenzl/oracle-free", "freepdb1"), + + XE("gvenzl/oracle-xe", "xepdb1"); + + private final String imageName; + + private final String defaultDatabase; + + OracleContainer(String imageName, String defaultDatabase) { + this.imageName = imageName; + this.defaultDatabase = defaultDatabase; + } + + String getImageName() { + return this.imageName; + } + + String getDefaultDatabase() { + return this.defaultDatabase; + } + +} diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleEnvironment.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleEnvironment.java new file mode 100644 index 000000000000..dc1de0fd8805 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleEnvironment.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Oracle Database environment details. + * + * @author Andy Wilkinson + */ +class OracleEnvironment { + + private final String username; + + private final String password; + + private final String database; + + OracleEnvironment(Map env, String defaultDatabase) { + this.username = env.getOrDefault("APP_USER", "system"); + this.password = extractPassword(env); + this.database = env.getOrDefault("ORACLE_DATABASE", defaultDatabase); + } + + private String extractPassword(Map env) { + if (env.containsKey("APP_USER")) { + String password = env.get("APP_USER_PASSWORD"); + Assert.state(StringUtils.hasLength(password), "No Oracle app password found"); + return password; + } + Assert.state(!env.containsKey("ORACLE_RANDOM_PASSWORD"), + "ORACLE_RANDOM_PASSWORD is not supported without APP_USER and APP_USER_PASSWORD"); + String password = env.get("ORACLE_PASSWORD"); + Assert.state(StringUtils.hasLength(password), "No Oracle password found"); + return password; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeR2dbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleFreeR2dbcDockerComposeConnectionDetailsFactory.java similarity index 89% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeR2dbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleFreeR2dbcDockerComposeConnectionDetailsFactory.java index 4727a0985720..6877a27ffc22 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleFreeR2dbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleFreeR2dbcDockerComposeConnectionDetailsFactory.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.r2dbc.docker.compose; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleR2dbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleR2dbcDockerComposeConnectionDetailsFactory.java similarity index 92% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleR2dbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleR2dbcDockerComposeConnectionDetailsFactory.java index 52231c3e844f..f5e5f027d8f9 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleR2dbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleR2dbcDockerComposeConnectionDetailsFactory.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.r2dbc.docker.compose; import io.r2dbc.spi.ConnectionFactoryOptions; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; /** * Base class for a {@link DockerComposeConnectionDetailsFactory} to create diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeR2dbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleXeR2dbcDockerComposeConnectionDetailsFactory.java similarity index 89% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeR2dbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleXeR2dbcDockerComposeConnectionDetailsFactory.java index ee15b6c9b20c..c54f725aaab0 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/oracle/OracleXeR2dbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleXeR2dbcDockerComposeConnectionDetailsFactory.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.oracle; +package org.springframework.boot.r2dbc.docker.compose; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/PostgresEnvironment.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/PostgresEnvironment.java new file mode 100644 index 000000000000..1647aaa1dab5 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/PostgresEnvironment.java @@ -0,0 +1,92 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Postgres environment details. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + * @author Sidmar Theodoro + * @author He Zean + */ +class PostgresEnvironment { + + private static final String[] USERNAME_KEYS = new String[] { "POSTGRES_USER", "POSTGRESQL_USER", + "POSTGRESQL_USERNAME" }; + + private static final String DEFAULT_USERNAME = "postgres"; + + private static final String[] DATABASE_KEYS = new String[] { "POSTGRES_DB", "POSTGRESQL_DB", + "POSTGRESQL_DATABASE" }; + + private final String username; + + private final String password; + + private final String database; + + PostgresEnvironment(Map env) { + this.username = extract(env, USERNAME_KEYS, DEFAULT_USERNAME); + this.password = extractPassword(env); + this.database = extract(env, DATABASE_KEYS, this.username); + } + + private String extract(Map env, String[] keys, String defaultValue) { + for (String key : keys) { + if (env.containsKey(key)) { + return env.get(key); + } + } + return defaultValue; + } + + private String extractPassword(Map env) { + if (isUsingTrustHostAuthMethod(env)) { + return null; + } + String password = env.getOrDefault("POSTGRES_PASSWORD", env.get("POSTGRESQL_PASSWORD")); + boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD"); + Assert.state(allowEmpty || StringUtils.hasLength(password), "No PostgreSQL password found"); + return (password != null) ? password : ""; + } + + private boolean isUsingTrustHostAuthMethod(Map env) { + String hostAuthMethod = env.get("POSTGRES_HOST_AUTH_METHOD"); + return "trust".equals(hostAuthMethod); + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + + String getDatabase() { + return this.database; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactory.java similarity index 93% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactory.java index c1da2fb9f6ca..75ff0ed6420f 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactory.java @@ -14,16 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.postgres; +package org.springframework.boot.r2dbc.docker.compose; import io.r2dbc.spi.ConnectionFactoryOptions; import io.r2dbc.spi.Option; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/SqlServerEnvironment.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/SqlServerEnvironment.java new file mode 100644 index 000000000000..0d413c655df2 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/SqlServerEnvironment.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * MS SQL Server environment details. + * + * @author Andy Wilkinson + */ +class SqlServerEnvironment { + + private final String username = "SA"; + + private final String password; + + SqlServerEnvironment(Map env) { + this.password = extractPassword(env); + } + + private String extractPassword(Map env) { + String password = env.get("MSSQL_SA_PASSWORD"); + password = (password != null) ? password : env.get("SA_PASSWORD"); + Assert.state(StringUtils.hasLength(password), "No MSSQL password found"); + return password; + } + + String getUsername() { + return this.username; + } + + String getPassword() { + return this.password; + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerR2dbcDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/SqlServerR2dbcDockerComposeConnectionDetailsFactory.java similarity index 91% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerR2dbcDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/SqlServerR2dbcDockerComposeConnectionDetailsFactory.java index 74e73883cfcc..96ded70e625e 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/sqlserver/SqlServerR2dbcDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/SqlServerR2dbcDockerComposeConnectionDetailsFactory.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.sqlserver; +package org.springframework.boot.r2dbc.docker.compose; import io.r2dbc.spi.ConnectionFactoryOptions; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails} diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/package-info.java new file mode 100644 index 000000000000..c877afed545f --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose R2DBC service connections. + */ +package org.springframework.boot.r2dbc.docker.compose; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/r2dbc/ConnectionFactoryHealthIndicator.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/health/ConnectionFactoryHealthIndicator.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/r2dbc/ConnectionFactoryHealthIndicator.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/health/ConnectionFactoryHealthIndicator.java index 313c4e63a780..dd79f908cc73 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/r2dbc/ConnectionFactoryHealthIndicator.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/health/ConnectionFactoryHealthIndicator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.r2dbc; +package org.springframework.boot.r2dbc.health; import io.r2dbc.spi.Connection; import io.r2dbc.spi.ConnectionFactory; @@ -24,11 +24,10 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.Status; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -37,7 +36,7 @@ * * @author Mark Paluch * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ public class ConnectionFactoryHealthIndicator extends AbstractReactiveHealthIndicator { @@ -69,18 +68,18 @@ public ConnectionFactoryHealthIndicator(ConnectionFactory connectionFactory, Str } @Override - protected final Mono doHealthCheck(Builder builder) { + protected final Mono doHealthCheck(Health.Builder builder) { return validate(builder).defaultIfEmpty(builder.build()) .onErrorResume(Exception.class, (ex) -> Mono.just(builder.down(ex).build())); } - private Mono validate(Builder builder) { + private Mono validate(Health.Builder builder) { builder.withDetail("database", this.connectionFactory.getMetadata().getName()); return (StringUtils.hasText(this.validationQuery)) ? validateWithQuery(builder) : validateWithConnectionValidation(builder); } - private Mono validateWithQuery(Builder builder) { + private Mono validateWithQuery(Health.Builder builder) { builder.withDetail("validationQuery", this.validationQuery); Mono connectionValidation = Mono.usingWhen(this.connectionFactory.create(), (conn) -> Flux.from(conn.createStatement(this.validationQuery).execute()) @@ -90,7 +89,7 @@ private Mono validateWithQuery(Builder builder) { return connectionValidation.map((result) -> builder.up().withDetail("result", result).build()); } - private Mono validateWithConnectionValidation(Builder builder) { + private Mono validateWithConnectionValidation(Health.Builder builder) { builder.withDetail("validationQuery", "validate(REMOTE)"); Mono connectionValidation = Mono.usingWhen(this.connectionFactory.create(), (connection) -> Mono.from(connection.validate(ValidationDepth.REMOTE)), Connection::close, diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/health/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/health/package-info.java new file mode 100644 index 000000000000..ab2aa272f2e6 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/health/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Health integration for R2DBC. + */ +package org.springframework.boot.r2dbc.health; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializer.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerDetector.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerDetector.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/init/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/init/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/init/package-info.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/init/package-info.java diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/r2dbc/ConnectionPoolMetrics.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/metrics/ConnectionPoolMetrics.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/r2dbc/ConnectionPoolMetrics.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/metrics/ConnectionPoolMetrics.java index 037885b9a16a..187603b8a7ba 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/r2dbc/ConnectionPoolMetrics.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/metrics/ConnectionPoolMetrics.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.r2dbc; +package org.springframework.boot.r2dbc.metrics; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.Gauge.Builder; @@ -30,7 +30,7 @@ * * @author Tadaya Tsuyukubo * @author Stephane Nicoll - * @since 2.3.0 + * @since 4.0.0 */ public class ConnectionPoolMetrics implements MeterBinder { diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/metrics/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/metrics/package-info.java new file mode 100644 index 000000000000..f79fe8fed2ab --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Metrics for R2DBC. + */ +package org.springframework.boot.r2dbc.metrics; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/r2dbc/package-info.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/package-info.java diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/ClickHouseR2dbcContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/ClickHouseR2dbcContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/ClickHouseR2dbcContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/ClickHouseR2dbcContainerConnectionDetailsFactory.java index 9f215ef2d076..2eff6f976a64 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/ClickHouseR2dbcContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/ClickHouseR2dbcContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.testcontainers.clickhouse.ClickHouseContainer; import org.testcontainers.clickhouse.ClickHouseR2DBCDatabaseContainer; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/MariaDbR2dbcContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/MariaDbR2dbcContainerConnectionDetailsFactory.java index efafc758e674..922d20d36c61 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/MariaDbR2dbcContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.testcontainers.containers.MariaDBContainer; import org.testcontainers.containers.MariaDBR2DBCDatabaseContainer; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/MySqlR2dbcContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/MySqlR2dbcContainerConnectionDetailsFactory.java index 4e4701df08e4..bd2b82928806 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/MySqlR2dbcContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.testcontainers.containers.MySQLContainer; import org.testcontainers.containers.MySQLR2DBCDatabaseContainer; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactory.java index de8ac3a5f030..f4b4569f0059 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.testcontainers.oracle.OracleContainer; import org.testcontainers.oracle.OracleR2DBCDatabaseContainer; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactory.java index 206a965f94be..4d402a3547fb 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.testcontainers.containers.OracleContainer; import org.testcontainers.containers.OracleR2DBCDatabaseContainer; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/PostgresR2dbcContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/PostgresR2dbcContainerConnectionDetailsFactory.java index 1c7a4238b985..dbf622510758 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/PostgresR2dbcContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.PostgreSQLR2DBCDatabaseContainer; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/SqlServerR2dbcContainerConnectionDetailsFactory.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/SqlServerR2dbcContainerConnectionDetailsFactory.java index 6ef69124ef72..507ba77f0507 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/SqlServerR2dbcContainerConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.testcontainers.containers.MSSQLR2DBCDatabaseContainer; import org.testcontainers.containers.MSSQLServerContainer; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/package-info.java b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/package-info.java new file mode 100644 index 000000000000..17b7abb2a4be --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers R2DBC service connections. + */ +package org.springframework.boot.r2dbc.testcontainers; diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-r2dbc/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..92eacd6c66f2 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/resources/META-INF/spring.factories @@ -0,0 +1,31 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.r2dbc.docker.compose.ClickHouseR2dbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.docker.compose.MariaDbR2dbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.docker.compose.MySqlR2dbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.docker.compose.OracleFreeR2dbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.docker.compose.OracleXeR2dbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.docker.compose.PostgresR2dbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.docker.compose.SqlServerR2dbcDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.testcontainers.ClickHouseR2dbcContainerConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.testcontainers.MariaDbR2dbcContainerConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.testcontainers.MySqlR2dbcContainerConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.testcontainers.OracleFreeR2dbcContainerConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.testcontainers.OracleXeR2dbcContainerConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.testcontainers.PostgresR2dbcContainerConnectionDetailsFactory,\ +org.springframework.boot.r2dbc.testcontainers.SqlServerR2dbcContainerConnectionDetailsFactory + + + + + +# Database Initializer Detectors +org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\ +org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializerDetector + +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.boot.r2dbc.autoconfigure.ConnectionFactoryBeanCreationFailureAnalyzer,\ +org.springframework.boot.r2dbc.autoconfigure.MissingR2dbcPoolDependencyFailureAnalyzer,\ +org.springframework.boot.r2dbc.autoconfigure.MultipleConnectionPoolConfigurationsFailureAnalyzer,\ +org.springframework.boot.r2dbc.autoconfigure.NoConnectionFactoryBeanFailureAnalyzer diff --git a/spring-boot-project/spring-boot-r2dbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-r2dbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..4cf042f020e1 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,7 @@ +org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.R2dbcInitializationAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.R2dbcProxyAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.R2dbcTransactionManagerAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.health.ConnectionFactoryHealthContributorAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.metrics.ConnectionPoolMetricsAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.observation.R2dbcObservationAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/ConnectionFactoryBuilderTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/ConnectionFactoryBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/ConnectionFactoryBuilderTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/ConnectionFactoryBuilderTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/EmbeddedDatabaseConnectionTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/EmbeddedDatabaseConnectionTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/EmbeddedDatabaseConnectionTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/EmbeddedDatabaseConnectionTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryBeanCreationFailureAnalyzerTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryBeanCreationFailureAnalyzerTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryBeanCreationFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryBeanCreationFailureAnalyzerTests.java index a71d30e6fd59..fd5de970f022 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryBeanCreationFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/ConnectionFactoryBeanCreationFailureAnalyzerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyFailureAnalyzerTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyFailureAnalyzerTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyFailureAnalyzerTests.java index 212d32160ee4..2ef14b8afdd5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/MissingR2dbcPoolDependencyFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/MissingR2dbcPoolDependencyFailureAnalyzerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsFailureAnalyzerTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsFailureAnalyzerTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsFailureAnalyzerTests.java index 78dc2be622e5..2ab7150cf1bb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/MultipleConnectionPoolConfigurationsFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/MultipleConnectionPoolConfigurationsFailureAnalyzerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/NoConnectionFactoryBeanFailureAnalyzerTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/NoConnectionFactoryBeanFailureAnalyzerTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/NoConnectionFactoryBeanFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/NoConnectionFactoryBeanFailureAnalyzerTests.java index 84667f383e82..e846d14ac4da 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/NoConnectionFactoryBeanFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/NoConnectionFactoryBeanFailureAnalyzerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.ConnectionFactoryProvider; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfigurationTests.java index ee5b6b7027a4..cf544651211a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import java.net.URL; import java.net.URLClassLoader; @@ -38,10 +38,10 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.r2dbc.SimpleConnectionFactoryProvider.SimpleTestConnectionFactory; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.r2dbc.EmbeddedDatabaseConnection; import org.springframework.boot.r2dbc.OptionsCapableConnectionFactory; +import org.springframework.boot.r2dbc.SimpleConnectionFactoryProvider.SimpleTestConnectionFactory; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ForkedClassPath; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationWithoutConnectionPoolTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfigurationWithoutConnectionPoolTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationWithoutConnectionPoolTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfigurationWithoutConnectionPoolTests.java index 9ed300ed3ae9..007449fe798f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationWithoutConnectionPoolTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfigurationWithoutConnectionPoolTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import java.util.UUID; diff --git a/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcInitializationAutoConfigurationTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcInitializationAutoConfigurationTests.java new file mode 100644 index 000000000000..8cd1f2c872fc --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcInitializationAutoConfigurationTests.java @@ -0,0 +1,162 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.autoconfigure; + +import io.r2dbc.spi.ConnectionFactory; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializer; +import org.springframework.boot.sql.autoconfigure.init.ApplicationScriptDatabaseInitializer; +import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer; +import org.springframework.boot.sql.init.DatabaseInitializationSettings; +import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.r2dbc.connection.init.DatabasePopulator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link R2dbcInitializationAutoConfiguration}. + * + * @author Andy Wilkinson + * @author Phillip Webb + */ +class R2dbcInitializationAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(R2dbcInitializationAutoConfiguration.class)) + .withPropertyValues("spring.r2dbc.generate-unique-name:true"); + + @Test + void whenNoConnectionFactoryIsAvailableThenAutoConfigurationBacksOff() { + this.contextRunner + .run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class)); + } + + @Test + void whenConnectionFactoryIsAvailableThenR2dbcInitializerIsAutoConfigured() { + this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) + .run((context) -> assertThat(context).hasSingleBean(R2dbcScriptDatabaseInitializer.class)); + } + + @Test + void whenConnectionFactoryIsAvailableAndModeIsNeverThenInitializerIsNotAutoConfigured() { + this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) + .withPropertyValues("spring.sql.init.mode:never") + .run((context) -> assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class)); + } + + @Test + void whenAnSqlInitializerIsDefinedThenInitializerIsNotAutoConfigured() { + this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) + .withUserConfiguration(SqlDatabaseInitializerConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(AbstractScriptDatabaseInitializer.class) + .hasBean("customInitializer")); + } + + @Test + void whenAnInitializerIsDefinedThenSqlInitializerIsStillAutoConfigured() { + this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) + .withUserConfiguration(DatabaseInitializerConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ApplicationScriptDatabaseInitializer.class) + .hasBean("customInitializer")); + } + + @Test + void whenBeanIsAnnotatedAsDependingOnDatabaseInitializationThenItDependsOnR2dbcScriptDatabaseInitializer() { + this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) + .withUserConfiguration(DependsOnInitializedDatabaseConfiguration.class) + .run((context) -> { + ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); + BeanDefinition beanDefinition = beanFactory.getBeanDefinition( + "r2dbcInitializationAutoConfigurationTests.DependsOnInitializedDatabaseConfiguration"); + assertThat(beanDefinition.getDependsOn()).containsExactlyInAnyOrder("r2dbcScriptDatabaseInitializer"); + }); + } + + @Test + void whenBeanIsAnnotatedAsDependingOnDatabaseInitializationThenItDependsOnDataSourceScriptDatabaseInitializer() { + this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) + .withUserConfiguration(DependsOnInitializedDatabaseConfiguration.class) + .run((context) -> { + ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); + BeanDefinition beanDefinition = beanFactory.getBeanDefinition( + "r2dbcInitializationAutoConfigurationTests.DependsOnInitializedDatabaseConfiguration"); + assertThat(beanDefinition.getDependsOn()).containsExactlyInAnyOrder("r2dbcScriptDatabaseInitializer"); + }); + } + + @Test + void whenAConnectionFactoryIsAvailableAndSpringR2dbcIsNotThenAutoConfigurationBacksOff() { + this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class)) + .withClassLoader(new FilteredClassLoader(DatabasePopulator.class)) + .run((context) -> { + assertThat(context).hasSingleBean(ConnectionFactory.class); + assertThat(context).doesNotHaveBean(AbstractScriptDatabaseInitializer.class); + }); + } + + @Configuration(proxyBeanMethods = false) + static class SqlDatabaseInitializerConfiguration { + + @Bean + ApplicationScriptDatabaseInitializer customInitializer() { + return mock(ApplicationScriptDatabaseInitializer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class DatabaseInitializerConfiguration { + + @Bean + R2dbcScriptDatabaseInitializer customInitializer() { + return new R2dbcScriptDatabaseInitializer(null, new DatabaseInitializationSettings()) { + + @Override + protected void runScripts(Scripts scripts) { + // No-op + } + + @Override + protected boolean isEmbeddedDatabase() { + return true; + } + + }; + } + + } + + @Configuration(proxyBeanMethods = false) + @DependsOnDatabaseInitialization + static class DependsOnInitializedDatabaseConfiguration { + + DependsOnInitializedDatabaseConfiguration() { + + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProxyAutoConfigurationTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProxyAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProxyAutoConfigurationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProxyAutoConfigurationTests.java index 646721d78d10..83c0a814b154 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProxyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcProxyAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcTransactionManagerAutoConfigurationTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcTransactionManagerAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcTransactionManagerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcTransactionManagerAutoConfigurationTests.java index 527b347bccca..c5fb7170b456 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcTransactionManagerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcTransactionManagerAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure; import java.time.Duration; @@ -26,8 +26,8 @@ import reactor.test.StepVerifier; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.ReactiveTransactionManager; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/r2dbc/ConnectionFactoryHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/health/ConnectionFactoryHealthContributorAutoConfigurationTests.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/r2dbc/ConnectionFactoryHealthContributorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/health/ConnectionFactoryHealthContributorAutoConfigurationTests.java index 3946ca9fc288..8ef67dda4b30 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/r2dbc/ConnectionFactoryHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/health/ConnectionFactoryHealthContributorAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure.health; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.r2dbc.ConnectionFactoryHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; +import org.springframework.boot.r2dbc.health.ConnectionFactoryHealthIndicator; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/ConnectionPoolMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/metrics/ConnectionPoolMetricsAutoConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/ConnectionPoolMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/metrics/ConnectionPoolMetricsAutoConfigurationTests.java index 0a2847a3a39a..4d221b58c008 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/r2dbc/ConnectionPoolMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/metrics/ConnectionPoolMetricsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure.metrics; import java.util.Collections; import java.util.UUID; @@ -34,9 +34,9 @@ import org.junit.jupiter.api.Test; import org.reactivestreams.Publisher; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -52,10 +52,10 @@ class ConnectionPoolMetricsAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("spring.r2dbc.generate-unique-name=true") - .with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(ConnectionPoolMetricsAutoConfiguration.class)) - .withUserConfiguration(BaseConfiguration.class); + .withPropertyValues("spring.r2dbc.generate-unique-name=true", "management.metrics.use-global-registry=false") + .withBean(SimpleMeterRegistry.class) + .withConfiguration( + AutoConfigurations.of(ConnectionPoolMetricsAutoConfiguration.class, MetricsAutoConfiguration.class)); @Test void autoConfiguredDataSourceIsInstrumented() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfigurationTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationAutoConfigurationTests.java index 2e5897305ea9..6da4d2eb5d5e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/r2dbc/R2dbcObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/autoconfigure/observation/R2dbcObservationAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc.autoconfigure.observation; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; @@ -28,13 +28,11 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; -import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.r2dbc.ProxyConnectionFactoryCustomizer; -import org.springframework.boot.autoconfigure.r2dbc.R2dbcProxyAutoConfiguration; -import org.springframework.boot.context.annotation.ImportCandidates; import org.springframework.boot.r2dbc.ConnectionFactoryBuilder; import org.springframework.boot.r2dbc.ConnectionFactoryDecorator; +import org.springframework.boot.r2dbc.autoconfigure.ProxyConnectionFactoryCustomizer; +import org.springframework.boot.r2dbc.autoconfigure.R2dbcProxyAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -55,12 +53,6 @@ class R2dbcObservationAutoConfigurationTests { private final ApplicationContextRunner runner = this.runnerWithoutObservationRegistry .withBean(ObservationRegistry.class, ObservationRegistry::create); - @Test - void shouldBeRegisteredInAutoConfigurationImports() { - assertThat(ImportCandidates.load(AutoConfiguration.class, null).getCandidates()) - .contains(R2dbcObservationAutoConfiguration.class.getName()); - } - @Test void shouldNotSupplyBeansIfObservationRegistryIsNotPresent() { this.runnerWithoutObservationRegistry diff --git a/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseEnvironmentTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseEnvironmentTests.java new file mode 100644 index 000000000000..5a7b98362c25 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseEnvironmentTests.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link ClickHouseEnvironment}. + * + * @author Stephane Nicoll + */ +class ClickHouseEnvironmentTests { + + @Test + void createWhenNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new ClickHouseEnvironment(Collections.emptyMap())) + .withMessage("No ClickHouse password found"); + } + + @Test + void getPasswordWhenHasPassword() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "true")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPasswordIsYes() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getUsernameWhenNoUser() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("default"); + } + + @Test + void getUsernameWhenHasUser() { + ClickHouseEnvironment environment = new ClickHouseEnvironment( + Map.of("CLICKHOUSE_USER", "me", "CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getDatabaseWhenNoDatabase() { + ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("default"); + } + + @Test + void getDatabaseWhenHasDatabase() { + ClickHouseEnvironment environment = new ClickHouseEnvironment( + Map.of("CLICKHOUSE_DB", "db", "CLICKHOUSE_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/r2dbc/ConnectionFactoryOptionsBuilderTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/ConnectionFactoryOptionsBuilderTests.java similarity index 96% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/r2dbc/ConnectionFactoryOptionsBuilderTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/ConnectionFactoryOptionsBuilderTests.java index 008f626d5106..2497b838d638 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/r2dbc/ConnectionFactoryOptionsBuilderTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/ConnectionFactoryOptionsBuilderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.r2dbc; +package org.springframework.boot.r2dbc.docker.compose; import java.util.Collections; import java.util.Map; @@ -43,7 +43,7 @@ class ConnectionFactoryOptionsBuilderTests { private ConnectionFactoryOptionsBuilder builder = new ConnectionFactoryOptionsBuilder("mydb", 1234); @Test - void createWhenDriverProtocolIsNullThrowsException() { + void createWhenDriverIsNullThrowsException() { assertThatIllegalArgumentException().isThrownBy(() -> new ConnectionFactoryOptionsBuilder(null, 123)) .withMessage("'driver' must not be null"); } diff --git a/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironmentTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironmentTests.java new file mode 100644 index 000000000000..169af621b883 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironmentTests.java @@ -0,0 +1,176 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link MariaDbEnvironment}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Jinseong Hwang + * @author Scott Frederick + */ +class MariaDbEnvironmentTests { + + @Test + void createWhenHasMariadbRandomRootPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_RANDOM_ROOT_PASSWORD", "true"))) + .withMessage("MARIADB_RANDOM_ROOT_PASSWORD is not supported"); + } + + @Test + void createWhenHasMysqlRandomRootPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new MariaDbEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"))) + .withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported"); + } + + @Test + void createWhenHasMariadbRootPasswordHashThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_ROOT_PASSWORD_HASH", "0FF"))) + .withMessage("MARIADB_ROOT_PASSWORD_HASH is not supported"); + } + + @Test + void createWhenHasNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Collections.emptyMap())) + .withMessage("No MariaDB password found"); + } + + @Test + void createWhenHasNoDatabaseThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_PASSWORD", "secret"))) + .withMessage("No MARIADB_DATABASE defined"); + } + + @Test + void getUsernameWhenHasMariadbUser() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("myself"); + } + + @Test + void getUsernameWhenHasMysqlUser() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MYSQL_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("myself"); + } + + @Test + void getUsernameWhenHasMariadbUserAndMysqlUser() { + MariaDbEnvironment environment = new MariaDbEnvironment(Map.of("MARIADB_USER", "myself", "MYSQL_USER", "me", + "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("myself"); + } + + @Test + void getUsernameWhenHasNoMariadbUserOrMysqlUser() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("root"); + } + + @Test + void getPasswordWhenHasMariadbPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMysqlPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MYSQL_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMysqlRootPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MYSQL_ROOT_PASSWORD", "secret", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMariadbPasswordAndMysqlPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_PASSWORD", "secret", "MYSQL_PASSWORD", "donttell", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMariadbPasswordAndMysqlRootPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_PASSWORD", "secret", "MYSQL_ROOT_PASSWORD", "donttell", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getDatabaseWhenHasMariadbDatabase() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + + @Test + void getDatabaseWhenHasMysqlDatabase() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + + @Test + void getDatabaseWhenHasMariadbAndMysqlDatabase() { + MariaDbEnvironment environment = new MariaDbEnvironment( + Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MySqlEnvironmentTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MySqlEnvironmentTests.java new file mode 100644 index 000000000000..508daad6c909 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MySqlEnvironmentTests.java @@ -0,0 +1,104 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link MySqlEnvironment}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Jinseong Hwang + * @author Scott Frederick + */ +class MySqlEnvironmentTests { + + @Test + void createWhenHasMysqlRandomRootPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true"))) + .withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported"); + } + + @Test + void createWhenHasNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Collections.emptyMap())) + .withMessage("No MySQL password found"); + } + + @Test + void createWhenHasNoDatabaseThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret"))) + .withMessage("No MYSQL_DATABASE defined"); + } + + @Test + void getUsernameWhenHasMysqlUser() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("MYSQL_USER", "myself", "MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("myself"); + } + + @Test + void getUsernameWhenHasNoMysqlUser() { + MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); + assertThat(environment.getUsername()).isEqualTo("root"); + } + + @Test + void getPasswordWhenHasMysqlPassword() { + MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMysqlRootPassword() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("MYSQL_ROOT_PASSWORD", "secret", "MYSQL_DATABASE", "db")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getDatabaseWhenHasMysqlDatabase() { + MySqlEnvironment environment = new MySqlEnvironment( + Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/OracleEnvironmentTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/OracleEnvironmentTests.java new file mode 100644 index 000000000000..d07fd8b8c6d1 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/OracleEnvironmentTests.java @@ -0,0 +1,115 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatNoException; + +/** + * Tests for {@link OracleEnvironment}. + * + * @author Andy Wilkinson + */ +class OracleEnvironmentTests { + + @Test + void getUsernameWhenHasAppUser() { + OracleEnvironment environment = new OracleEnvironment( + Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getUsername()).isEqualTo("alice"); + } + + @Test + void getUsernameWhenHasNoAppUser() { + OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getUsername()).isEqualTo("system"); + } + + @Test + void getPasswordWhenHasAppPassword() { + OracleEnvironment environment = new OracleEnvironment( + Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasOraclePassword() { + OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void createWhenRandomPasswordAndAppPasswordDoesNotThrow() { + assertThatNoException().isThrownBy(() -> new OracleEnvironment( + Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret", "ORACLE_RANDOM_PASSWORD", "true"), + "defaultDb")); + } + + @Test + void createWhenRandomPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new OracleEnvironment(Map.of("ORACLE_RANDOM_PASSWORD", "true"), "defaultDb")) + .withMessage("ORACLE_RANDOM_PASSWORD is not supported without APP_USER and APP_USER_PASSWORD"); + } + + @Test + void createWhenAppUserAndNoAppPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new OracleEnvironment(Map.of("APP_USER", "alice"), "defaultDb")) + .withMessage("No Oracle app password found"); + } + + @Test + void createWhenAppUserAndEmptyAppPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new OracleEnvironment(Map.of("APP_USER", "alice", "APP_USER_PASSWORD", ""), "defaultDb")) + .withMessage("No Oracle app password found"); + } + + @Test + void createWhenHasNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new OracleEnvironment(Collections.emptyMap(), "defaultDb")) + .withMessage("No Oracle password found"); + } + + @Test + void createWhenHasEmptyPasswordThrowsException() { + assertThatIllegalStateException() + .isThrownBy(() -> new OracleEnvironment(Map.of("ORACLE_PASSWORD", ""), "defaultDb")) + .withMessage("No Oracle password found"); + } + + @Test + void getDatabaseWhenHasNoOracleDatabase() { + OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb"); + assertThat(environment.getDatabase()).isEqualTo("defaultDb"); + } + + @Test + void getDatabaseWhenHasOracleDatabase() { + OracleEnvironment environment = new OracleEnvironment( + Map.of("ORACLE_PASSWORD", "secret", "ORACLE_DATABASE", "db"), "defaultDb"); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/PostgresEnvironmentTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/PostgresEnvironmentTests.java new file mode 100644 index 000000000000..3b1031c9cdcf --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/PostgresEnvironmentTests.java @@ -0,0 +1,156 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link PostgresEnvironment}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @author Scott Frederick + * @author Sidmar Theodoro + * @author He Zean + */ +class PostgresEnvironmentTests { + + @Test + void createWhenNoPostgresPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new PostgresEnvironment(Collections.emptyMap())) + .withMessage("No PostgreSQL password found"); + } + + @Test + void getUsernameWhenNoPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("postgres"); + } + + @Test + void getUsernameWhenNoPostgresqlUser() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("postgres"); + } + + @Test + void getUsernameWhenHasPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getUsernameWhenHasPostgresqlUser() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_USER", "me", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getUsernameWhenHasPostgresqlUsername() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("me"); + } + + @Test + void getPasswordWhenHasPostgresPassword() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasPostgresqlPassword() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasTrustHostAuthMethod() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_HOST_AUTH_METHOD", "trust")); + assertThat(environment.getPassword()).isNull(); + } + + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes")); + assertThat(environment.getPassword()).isEmpty(); + } + + @Test + void getDatabaseWhenNoPostgresDbOrPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("postgres"); + } + + @Test + void getDatabaseWhenNoPostgresqlDbOrPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("postgres"); + } + + @Test + void getDatabaseWhenNoPostgresDbAndPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("me"); + } + + @Test + void getDatabaseWhenNoPostgresqlDbAndPostgresUser() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_USER", "me", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("me"); + } + + @Test + void getDatabaseWhenNoPostgresqlDatabaseAndPostgresqlUsername() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("me"); + } + + @Test + void getDatabaseWhenHasPostgresDb() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRES_DB", "db", "POSTGRES_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + + @Test + void getDatabaseWhenHasPostgresqlDb() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_DB", "db", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + + @Test + void getDatabaseWhenHasPostgresqlDatabase() { + PostgresEnvironment environment = new PostgresEnvironment( + Map.of("POSTGRESQL_DATABASE", "db", "POSTGRESQL_PASSWORD", "secret")); + assertThat(environment.getDatabase()).isEqualTo("db"); + } + +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java similarity index 98% rename from spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java index b6861c443e11..e12b31f47fe6 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/PostgresR2dbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.postgres; +package org.springframework.boot.r2dbc.docker.compose; import java.util.LinkedHashMap; import java.util.Map; diff --git a/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/SqlServerEnvironmentTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/SqlServerEnvironmentTests.java new file mode 100644 index 000000000000..49044672d7ef --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/SqlServerEnvironmentTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.r2dbc.docker.compose; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link SqlServerEnvironment}. + * + * @author Andy Wilkinson + */ +class SqlServerEnvironmentTests { + + @Test + void createWhenHasNoPasswordThrowsException() { + assertThatIllegalStateException().isThrownBy(() -> new SqlServerEnvironment(Collections.emptyMap())) + .withMessage("No MSSQL password found"); + } + + @Test + void getUsernameWhenHasNoMsSqlUser() { + SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("MSSQL_SA_PASSWORD", "secret")); + assertThat(environment.getUsername()).isEqualTo("SA"); + } + + @Test + void getPasswordWhenHasMsSqlSaPassword() { + SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("MSSQL_SA_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasSaPassword() { + SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("SA_PASSWORD", "secret")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + + @Test + void getPasswordWhenHasMsSqlSaPasswordAndSaPasswordPrefersMsSqlSaPassword() { + SqlServerEnvironment environment = new SqlServerEnvironment( + Map.of("MSSQL_SA_PASSWORD", "secret", "SA_PASSWORD", "not used")); + assertThat(environment.getPassword()).isEqualTo("secret"); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/r2dbc/ConnectionFactoryHealthIndicatorTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/health/ConnectionFactoryHealthIndicatorTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/r2dbc/ConnectionFactoryHealthIndicatorTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/health/ConnectionFactoryHealthIndicatorTests.java index 3c25c38086c1..e345acffc820 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/r2dbc/ConnectionFactoryHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/health/ConnectionFactoryHealthIndicatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.r2dbc; +package org.springframework.boot.r2dbc.health; import java.time.Duration; import java.util.Collections; @@ -32,8 +32,8 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; +import org.springframework.boot.health.contributor.Status; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/init/R2dbcScriptDatabaseInitializerTests.java diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/r2dbc/ConnectionPoolMetricsTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/metrics/ConnectionPoolMetricsTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/r2dbc/ConnectionPoolMetricsTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/metrics/ConnectionPoolMetricsTests.java index fb8d5bbed209..f69afc2a4b15 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/r2dbc/ConnectionPoolMetricsTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/metrics/ConnectionPoolMetricsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.r2dbc; +package org.springframework.boot.r2dbc.metrics; import java.time.Duration; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/ClickHouseR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/ClickHouseR2dbcContainerConnectionDetailsFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/ClickHouseR2dbcContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/ClickHouseR2dbcContainerConnectionDetailsFactoryTests.java index 8cb0308903e4..d06a0a19843f 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/ClickHouseR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/ClickHouseR2dbcContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java index 6e8878e5a4aa..12c19df6e441 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/MySqlR2dbcContainerConnectionDetailsFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/MySqlR2dbcContainerConnectionDetailsFactoryTests.java index 019939d389a9..0c6135bb413a 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/MySqlR2dbcContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactoryTests.java index 005350446fc0..326c871ee104 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleFreeR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/OracleFreeR2dbcContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactoryTests.java index b76159439d29..d4dd1ddb7e5f 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleXeR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/OracleXeR2dbcContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/PostgresR2dbcContainerConnectionDetailsFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/PostgresR2dbcContainerConnectionDetailsFactoryTests.java index 02be81a0ff1d..b65dec424df1 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/PostgresR2dbcContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java index 1deddc07cdf2..04f577b85437 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/testcontainers/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; +package org.springframework.boot.r2dbc.testcontainers; import io.r2dbc.spi.ConnectionFactoryOptions; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/SimpleBindMarkerFactoryProvider.java b/spring-boot-project/spring-boot-r2dbc/src/testFixtures/java/org/springframework/boot/r2dbc/SimpleBindMarkerFactoryProvider.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/SimpleBindMarkerFactoryProvider.java rename to spring-boot-project/spring-boot-r2dbc/src/testFixtures/java/org/springframework/boot/r2dbc/SimpleBindMarkerFactoryProvider.java index 276c2d713660..e877b245e315 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/SimpleBindMarkerFactoryProvider.java +++ b/spring-boot-project/spring-boot-r2dbc/src/testFixtures/java/org/springframework/boot/r2dbc/SimpleBindMarkerFactoryProvider.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc; import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.Wrapped; -import org.springframework.boot.autoconfigure.r2dbc.SimpleConnectionFactoryProvider.SimpleTestConnectionFactory; +import org.springframework.boot.r2dbc.SimpleConnectionFactoryProvider.SimpleTestConnectionFactory; import org.springframework.r2dbc.core.binding.BindMarkersFactory; import org.springframework.r2dbc.core.binding.BindMarkersFactoryResolver.BindMarkerFactoryProvider; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/SimpleConnectionFactoryProvider.java b/spring-boot-project/spring-boot-r2dbc/src/testFixtures/java/org/springframework/boot/r2dbc/SimpleConnectionFactoryProvider.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/SimpleConnectionFactoryProvider.java rename to spring-boot-project/spring-boot-r2dbc/src/testFixtures/java/org/springframework/boot/r2dbc/SimpleConnectionFactoryProvider.java index 0ce3e31b2afd..88e9c7a3eb9d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/SimpleConnectionFactoryProvider.java +++ b/spring-boot-project/spring-boot-r2dbc/src/testFixtures/java/org/springframework/boot/r2dbc/SimpleConnectionFactoryProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.r2dbc; +package org.springframework.boot.r2dbc; import io.r2dbc.spi.Connection; import io.r2dbc.spi.ConnectionFactory; diff --git a/spring-boot-project/spring-boot-r2dbc/src/testFixtures/resources/META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider b/spring-boot-project/spring-boot-r2dbc/src/testFixtures/resources/META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider new file mode 100644 index 000000000000..0d673d039f02 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/testFixtures/resources/META-INF/services/io.r2dbc.spi.ConnectionFactoryProvider @@ -0,0 +1 @@ +org.springframework.boot.r2dbc.SimpleConnectionFactoryProvider diff --git a/spring-boot-project/spring-boot-r2dbc/src/testFixtures/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-r2dbc/src/testFixtures/resources/META-INF/spring.factories new file mode 100644 index 000000000000..b13d6edf43c1 --- /dev/null +++ b/spring-boot-project/spring-boot-r2dbc/src/testFixtures/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.r2dbc.core.binding.BindMarkersFactoryResolver$BindMarkerFactoryProvider=org.springframework.boot.r2dbc.SimpleBindMarkerFactoryProvider diff --git a/spring-boot-project/spring-boot-reactor-netty/build.gradle b/spring-boot-project/spring-boot-reactor-netty/build.gradle new file mode 100644 index 000000000000..9b485d1c5e40 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/build.gradle @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Reactor Netty" + +dependencies { + api(project(":spring-boot-project:spring-boot-web-server")) + api("io.projectreactor.netty:reactor-netty-http") + api("org.springframework:spring-web") + + implementation(project(":spring-boot-project:spring-boot-netty")) + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("io.projectreactor:reactor-test") + testImplementation("org.springframework:spring-webflux") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("org.eclipse.jetty:jetty-client") + testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client") + testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client-transport") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/CompressionCustomizer.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/CompressionCustomizer.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/CompressionCustomizer.java rename to spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/CompressionCustomizer.java index 6f75d9120f4e..3cb03a4590b4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/CompressionCustomizer.java +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/CompressionCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.netty; +package org.springframework.boot.reactor.netty; import java.util.Arrays; import java.util.List; diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/GracefulShutdown.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/GracefulShutdown.java new file mode 100644 index 000000000000..1462d551fed9 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/GracefulShutdown.java @@ -0,0 +1,94 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty; + +import java.time.Duration; +import java.util.function.Supplier; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import reactor.netty.DisposableServer; + +import org.springframework.boot.web.server.GracefulShutdownCallback; +import org.springframework.boot.web.server.GracefulShutdownResult; + +/** + * Handles Netty graceful shutdown. + * + * @author Andy Wilkinson + */ +final class GracefulShutdown { + + private static final Log logger = LogFactory.getLog(GracefulShutdown.class); + + private final Supplier disposableServer; + + private volatile Thread shutdownThread; + + private volatile boolean shuttingDown; + + GracefulShutdown(Supplier disposableServer) { + this.disposableServer = disposableServer; + } + + void shutDownGracefully(GracefulShutdownCallback callback) { + DisposableServer server = this.disposableServer.get(); + if (server == null) { + return; + } + logger.info("Commencing graceful shutdown. Waiting for active requests to complete"); + this.shutdownThread = new Thread(() -> doShutdown(callback, server), "netty-shutdown"); + this.shutdownThread.start(); + } + + private void doShutdown(GracefulShutdownCallback callback, DisposableServer server) { + this.shuttingDown = true; + try { + server.disposeNow(Duration.ofNanos(Long.MAX_VALUE)); + logger.info("Graceful shutdown complete"); + callback.shutdownComplete(GracefulShutdownResult.IDLE); + } + catch (Exception ex) { + logger.info("Graceful shutdown aborted with one or more requests still active"); + callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE); + } + finally { + this.shutdownThread = null; + this.shuttingDown = false; + } + } + + void abort() { + Thread shutdownThread = this.shutdownThread; + if (shutdownThread != null) { + while (!this.shuttingDown) { + sleep(50); + } + shutdownThread.interrupt(); + } + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyReactiveWebServerFactory.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java rename to spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyReactiveWebServerFactory.java index b503b1447617..727f30118975 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyReactiveWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.netty; +package org.springframework.boot.reactor.netty; import java.net.InetSocketAddress; import java.time.Duration; @@ -28,11 +28,11 @@ import reactor.netty.http.HttpProtocol; import reactor.netty.http.server.HttpServer; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; import org.springframework.http.client.ReactorResourceFactory; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; @@ -45,7 +45,7 @@ * @author Brian Clozel * @author Moritz Halbritter * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ public class NettyReactiveWebServerFactory extends AbstractReactiveWebServerFactory { @@ -134,7 +134,7 @@ public void setLifecycleTimeout(Duration lifecycleTimeout) { /** * Set if x-forward-* headers should be processed. * @param useForwardHeaders if x-forward headers should be used - * @since 2.1.0 + * @since 4.0.0 */ public void setUseForwardHeaders(boolean useForwardHeaders) { this.useForwardHeaders = useForwardHeaders; @@ -143,7 +143,7 @@ public void setUseForwardHeaders(boolean useForwardHeaders) { /** * Set the {@link ReactorResourceFactory} to get the shared resources from. * @param resourceFactory the server resources - * @since 2.1.0 + * @since 4.0.0 */ public void setResourceFactory(ReactorResourceFactory resourceFactory) { this.resourceFactory = resourceFactory; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyRouteProvider.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyRouteProvider.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyRouteProvider.java rename to spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyRouteProvider.java index 9b59d651be29..70d8bad10a57 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyRouteProvider.java +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyRouteProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.netty; +package org.springframework.boot.reactor.netty; import java.util.function.Function; @@ -24,7 +24,7 @@ * Function that can add new routes to an {@link HttpServerRoutes} instance. * * @author Brian Clozel - * @since 2.2.0 + * @since 4.0.0 * @see NettyReactiveWebServerFactory */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyServerCustomizer.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyServerCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyServerCustomizer.java rename to spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyServerCustomizer.java index 5df6fb3fc036..2365b244a095 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyServerCustomizer.java +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyServerCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.netty; +package org.springframework.boot.reactor.netty; import java.util.function.Function; @@ -24,7 +24,7 @@ * Mapping function that can be used to customize a Reactor Netty server instance. * * @author Brian Clozel - * @since 2.1.0 + * @since 4.0.0 * @see NettyReactiveWebServerFactory */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyWebServer.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyWebServer.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyWebServer.java rename to spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyWebServer.java index 56158cce80ec..5461bdb09534 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyWebServer.java +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyWebServer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.netty; +package org.springframework.boot.reactor.netty; import java.time.Duration; import java.util.Collections; @@ -55,7 +55,7 @@ * @author Brian Clozel * @author Madhura Bhave * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class NettyWebServer implements WebServer { @@ -90,7 +90,7 @@ public class NettyWebServer implements WebServer { * @param shutdown the shutdown, may be {@code null} * @param resourceFactory the factory for the server's {@link LoopResources loop * resources}, may be {@code null} - * @since 3.2.0 + * @since 4.0.0 */ public NettyWebServer(HttpServer httpServer, ReactorHttpHandlerAdapter handlerAdapter, Duration lifecycleTimeout, Shutdown shutdown, ReactorResourceFactory resourceFactory) { diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/SslServerCustomizer.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/SslServerCustomizer.java new file mode 100644 index 000000000000..54a17d8007bb --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/SslServerCustomizer.java @@ -0,0 +1,125 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty; + +import java.util.HashMap; +import java.util.Map; + +import io.netty.handler.ssl.ClientAuth; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import reactor.netty.http.Http11SslContextSpec; +import reactor.netty.http.Http2SslContextSpec; +import reactor.netty.http.server.HttpServer; +import reactor.netty.tcp.AbstractProtocolSslContextSpec; +import reactor.netty.tcp.SslProvider; +import reactor.netty.tcp.SslProvider.GenericSslContextSpec; +import reactor.netty.tcp.SslProvider.SslContextSpec; + +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.ssl.SslOptions; +import org.springframework.boot.web.server.Http2; +import org.springframework.boot.web.server.Ssl; + +/** + * {@link NettyServerCustomizer} that configures SSL for the given Reactor Netty server + * instance. + * + * @author Brian Clozel + * @author Raheela Aslam + * @author Chris Bono + * @author Cyril Dangerville + * @author Scott Frederick + * @author Moritz Halbritter + * @author Phillip Webb + * @since 4.0.0 + */ +public class SslServerCustomizer implements NettyServerCustomizer { + + private static final Log logger = LogFactory.getLog(SslServerCustomizer.class); + + private final Http2 http2; + + private final ClientAuth clientAuth; + + private volatile SslProvider sslProvider; + + private final Map serverNameSslProviders; + + public SslServerCustomizer(Http2 http2, Ssl.ClientAuth clientAuth, SslBundle sslBundle, + Map serverNameSslBundles) { + this.http2 = http2; + this.clientAuth = Ssl.ClientAuth.map(clientAuth, ClientAuth.NONE, ClientAuth.OPTIONAL, ClientAuth.REQUIRE); + this.sslProvider = createSslProvider(sslBundle); + this.serverNameSslProviders = createServerNameSslProviders(serverNameSslBundles); + updateSslBundle(null, sslBundle); + } + + @Override + public HttpServer apply(HttpServer server) { + return server.secure(this::applySecurity); + } + + private void applySecurity(SslContextSpec spec) { + spec.sslContext(this.sslProvider.getSslContext()).setSniAsyncMappings((serverName, promise) -> { + SslProvider provider = (serverName != null) ? this.serverNameSslProviders.get(serverName) + : this.sslProvider; + return promise.setSuccess(provider); + }); + } + + void updateSslBundle(String serverName, SslBundle sslBundle) { + logger.debug("SSL Bundle has been updated, reloading SSL configuration"); + if (serverName == null) { + this.sslProvider = createSslProvider(sslBundle); + } + else { + this.serverNameSslProviders.put(serverName, createSslProvider(sslBundle)); + } + } + + private Map createServerNameSslProviders(Map serverNameSslBundles) { + Map serverNameSslProviders = new HashMap<>(); + serverNameSslBundles + .forEach((serverName, sslBundle) -> serverNameSslProviders.put(serverName, createSslProvider(sslBundle))); + return serverNameSslProviders; + } + + private SslProvider createSslProvider(SslBundle sslBundle) { + return SslProvider.builder().sslContext((GenericSslContextSpec) createSslContextSpec(sslBundle)).build(); + } + + /** + * Create an {@link AbstractProtocolSslContextSpec} for a given {@link SslBundle}. + * @param sslBundle the {@link SslBundle} to use + * @return an {@link AbstractProtocolSslContextSpec} instance + * @since 4.0.0 + */ + protected final AbstractProtocolSslContextSpec createSslContextSpec(SslBundle sslBundle) { + AbstractProtocolSslContextSpec sslContextSpec = (this.http2 != null && this.http2.isEnabled()) + ? Http2SslContextSpec.forServer(sslBundle.getManagers().getKeyManagerFactory()) + : Http11SslContextSpec.forServer(sslBundle.getManagers().getKeyManagerFactory()); + return sslContextSpec.configure((builder) -> { + builder.trustManager(sslBundle.getManagers().getTrustManagerFactory()); + SslOptions options = sslBundle.getOptions(); + builder.protocols(options.getEnabledProtocols()); + builder.ciphers(SslOptions.asSet(options.getCiphers())); + builder.clientAuth(this.clientAuth); + }); + } + +} diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerAutoConfiguration.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerAutoConfiguration.java new file mode 100644 index 000000000000..b552a858261f --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerAutoConfiguration.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty.autoconfigure; + +import reactor.netty.http.server.HttpServer; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.reactor.netty.NettyRouteProvider; +import org.springframework.boot.reactor.netty.NettyServerCustomizer; +import org.springframework.boot.reactor.netty.autoconfigure.ReactorNettyConfigurations.ReactorResourceFactoryConfiguration; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.reactive.ReactiveWebServerConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.core.env.Environment; +import org.springframework.http.ReactiveHttpInputMessage; +import org.springframework.http.client.ReactorResourceFactory; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for a Netty-based reactive web + * server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ReactiveHttpInputMessage.class, HttpServer.class }) +@EnableConfigurationProperties(NettyServerProperties.class) +@Import({ ReactiveWebServerConfiguration.class, ReactorResourceFactoryConfiguration.class }) +public class NettyReactiveWebServerAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(ReactiveWebServerFactory.class) + NettyReactiveWebServerFactory nettyReactiveWebServerFactory(ReactorResourceFactory resourceFactory, + ObjectProvider routes, ObjectProvider serverCustomizers) { + NettyReactiveWebServerFactory serverFactory = new NettyReactiveWebServerFactory(); + serverFactory.setResourceFactory(resourceFactory); + routes.orderedStream().forEach(serverFactory::addRouteProviders); + serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList()); + return serverFactory; + } + + @Bean + NettyReactiveWebServerFactoryCustomizer nettyWebServerFactoryCustomizer(Environment environment, + ServerProperties serverProperties, NettyServerProperties nettyProperties) { + return new NettyReactiveWebServerFactoryCustomizer(environment, serverProperties, nettyProperties); + } + +} diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..9c812f60fc68 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerFactoryCustomizer.java @@ -0,0 +1,120 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty.autoconfigure; + +import java.time.Duration; + +import io.netty.channel.ChannelOption; + +import org.springframework.boot.cloud.CloudPlatform; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.core.Ordered; +import org.springframework.core.env.Environment; + +/** + * Customization for Netty-specific features. + * + * @author Brian Clozel + * @author Chentao Qu + * @author Artsiom Yudovin + * @since 4.0.0 + */ +public class NettyReactiveWebServerFactoryCustomizer + implements WebServerFactoryCustomizer, Ordered { + + private final Environment environment; + + private final ServerProperties serverProperties; + + private final NettyServerProperties nettyProperties; + + public NettyReactiveWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties, + NettyServerProperties nettyProperties) { + this.environment = environment; + this.serverProperties = serverProperties; + this.nettyProperties = nettyProperties; + } + + @Override + public int getOrder() { + return 0; + } + + @Override + public void customize(NettyReactiveWebServerFactory factory) { + factory.setUseForwardHeaders(getOrDeduceUseForwardHeaders()); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(this.nettyProperties::getConnectionTimeout) + .to((connectionTimeout) -> customizeConnectionTimeout(factory, connectionTimeout)); + map.from(this.nettyProperties::getIdleTimeout).to((idleTimeout) -> customizeIdleTimeout(factory, idleTimeout)); + map.from(this.nettyProperties::getMaxKeepAliveRequests) + .to((maxKeepAliveRequests) -> customizeMaxKeepAliveRequests(factory, maxKeepAliveRequests)); + if (this.serverProperties.getHttp2() != null && this.serverProperties.getHttp2().isEnabled()) { + map.from(this.serverProperties.getMaxHttpRequestHeaderSize()) + .to((size) -> customizeHttp2MaxHeaderSize(factory, size.toBytes())); + } + customizeRequestDecoder(factory, map); + } + + private boolean getOrDeduceUseForwardHeaders() { + if (this.serverProperties.getForwardHeadersStrategy() == null) { + CloudPlatform platform = CloudPlatform.getActive(this.environment); + return platform != null && platform.isUsingForwardHeaders(); + } + return this.serverProperties.getForwardHeadersStrategy().equals(ServerProperties.ForwardHeadersStrategy.NATIVE); + } + + private void customizeConnectionTimeout(NettyReactiveWebServerFactory factory, Duration connectionTimeout) { + factory.addServerCustomizers((httpServer) -> httpServer.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, + (int) connectionTimeout.toMillis())); + } + + private void customizeRequestDecoder(NettyReactiveWebServerFactory factory, PropertyMapper propertyMapper) { + factory.addServerCustomizers((httpServer) -> httpServer.httpRequestDecoder((httpRequestDecoderSpec) -> { + propertyMapper.from(this.serverProperties.getMaxHttpRequestHeaderSize()) + .to((maxHttpRequestHeader) -> httpRequestDecoderSpec + .maxHeaderSize((int) maxHttpRequestHeader.toBytes())); + propertyMapper.from(this.nettyProperties.getMaxInitialLineLength()) + .to((maxInitialLineLength) -> httpRequestDecoderSpec + .maxInitialLineLength((int) maxInitialLineLength.toBytes())); + propertyMapper.from(this.nettyProperties.getH2cMaxContentLength()) + .to((h2cMaxContentLength) -> httpRequestDecoderSpec + .h2cMaxContentLength((int) h2cMaxContentLength.toBytes())); + propertyMapper.from(this.nettyProperties.getInitialBufferSize()) + .to((initialBufferSize) -> httpRequestDecoderSpec.initialBufferSize((int) initialBufferSize.toBytes())); + propertyMapper.from(this.nettyProperties.isValidateHeaders()).to(httpRequestDecoderSpec::validateHeaders); + return httpRequestDecoderSpec; + })); + } + + private void customizeIdleTimeout(NettyReactiveWebServerFactory factory, Duration idleTimeout) { + factory.addServerCustomizers((httpServer) -> httpServer.idleTimeout(idleTimeout)); + } + + private void customizeMaxKeepAliveRequests(NettyReactiveWebServerFactory factory, int maxKeepAliveRequests) { + factory.addServerCustomizers((httpServer) -> httpServer.maxKeepAliveRequests(maxKeepAliveRequests)); + } + + private void customizeHttp2MaxHeaderSize(NettyReactiveWebServerFactory factory, long size) { + factory.addServerCustomizers( + ((httpServer) -> httpServer.http2Settings((settings) -> settings.maxHeaderListSize(size)))); + } + +} diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyServerProperties.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyServerProperties.java new file mode 100644 index 000000000000..dcc548ea23dd --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/NettyServerProperties.java @@ -0,0 +1,147 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty.autoconfigure; + +import java.time.Duration; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.unit.DataSize; + +/** + * Netty server properties. + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Ivan Sopov + * @author Marcos Barbero + * @author Eddú Meléndez + * @author Quinten De Swaef + * @author Venil Noronha + * @author Aurélien Leboulanger + * @author Brian Clozel + * @author Olivier Lamy + * @author Chentao Qu + * @author Artsiom Yudovin + * @author Andrew McGhie + * @author Rafiullah Hamedy + * @author Dirk Deyne + * @author HaiTao Zhang + * @author Victor Mandujano + * @author Chris Bono + * @author Parviz Rozikov + * @author Florian Storz + * @author Michael Weidmann + * @author Lasse Wulff + * @since 4.0.0 + */ +@ConfigurationProperties("server.netty") +public class NettyServerProperties { + + /** + * Connection timeout of the Netty channel. + */ + private Duration connectionTimeout; + + /** + * Maximum content length of an H2C upgrade request. + */ + private DataSize h2cMaxContentLength = DataSize.ofBytes(0); + + /** + * Initial buffer size for HTTP request decoding. + */ + private DataSize initialBufferSize = DataSize.ofBytes(128); + + /** + * Maximum length that can be decoded for an HTTP request's initial line. + */ + private DataSize maxInitialLineLength = DataSize.ofKilobytes(4); + + /** + * Maximum number of requests that can be made per connection. By default, a + * connection serves unlimited number of requests. + */ + private Integer maxKeepAliveRequests; + + /** + * Whether to validate headers when decoding requests. + */ + private boolean validateHeaders = true; + + /** + * Idle timeout of the Netty channel. When not specified, an infinite timeout is used. + */ + private Duration idleTimeout; + + public Duration getConnectionTimeout() { + return this.connectionTimeout; + } + + public void setConnectionTimeout(Duration connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public DataSize getH2cMaxContentLength() { + return this.h2cMaxContentLength; + } + + public void setH2cMaxContentLength(DataSize h2cMaxContentLength) { + this.h2cMaxContentLength = h2cMaxContentLength; + } + + public DataSize getInitialBufferSize() { + return this.initialBufferSize; + } + + public void setInitialBufferSize(DataSize initialBufferSize) { + this.initialBufferSize = initialBufferSize; + } + + public DataSize getMaxInitialLineLength() { + return this.maxInitialLineLength; + } + + public void setMaxInitialLineLength(DataSize maxInitialLineLength) { + this.maxInitialLineLength = maxInitialLineLength; + } + + public Integer getMaxKeepAliveRequests() { + return this.maxKeepAliveRequests; + } + + public void setMaxKeepAliveRequests(Integer maxKeepAliveRequests) { + this.maxKeepAliveRequests = maxKeepAliveRequests; + } + + public boolean isValidateHeaders() { + return this.validateHeaders; + } + + public void setValidateHeaders(boolean validateHeaders) { + this.validateHeaders = validateHeaders; + } + + public Duration getIdleTimeout() { + return this.idleTimeout; + } + + public void setIdleTimeout(Duration idleTimeout) { + this.idleTimeout = idleTimeout; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/ReactorNettyConfigurations.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/ReactorNettyConfigurations.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/ReactorNettyConfigurations.java rename to spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/ReactorNettyConfigurations.java index b1e32a2da76d..705764cfca05 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/ReactorNettyConfigurations.java +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/ReactorNettyConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.reactor.netty; +package org.springframework.boot.reactor.netty.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -27,7 +27,7 @@ * auto-configuration class. * * @author Moritz Halbritter - * @since 2.7.9 + * @since 4.0.0 */ public final class ReactorNettyConfigurations { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/ReactorNettyProperties.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/ReactorNettyProperties.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/ReactorNettyProperties.java rename to spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/ReactorNettyProperties.java index 414830995166..a58d2fe0d469 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/netty/ReactorNettyProperties.java +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/ReactorNettyProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.reactor.netty; +package org.springframework.boot.reactor.netty.autoconfigure; import java.time.Duration; @@ -24,7 +24,7 @@ * Configuration properties for Reactor Netty. * * @author Moritz Halbritter - * @since 2.7.9 + * @since 4.0.0 */ @ConfigurationProperties("spring.reactor.netty") public class ReactorNettyProperties { diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/NettyReactiveManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/NettyReactiveManagementChildContextConfiguration.java new file mode 100644 index 000000000000..c55aa9a4580d --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/NettyReactiveManagementChildContextConfiguration.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty.autoconfigure.actuate.web; + +import reactor.netty.http.server.HttpServer; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Netty-based + * reactive web endpoint infrastructure when a separate management context running on a + * different port is required. + * + * @author Andy Wilkinson + */ +@ConditionalOnClass(HttpServer.class) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@EnableConfigurationProperties(ManagementServerProperties.class) +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +class NettyReactiveManagementChildContextConfiguration { + + @Bean + static ManagementContextFactory reactiveWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, + NettyReactiveWebServerAutoConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/NettyReactiveManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/NettyReactiveManagementContextAutoConfiguration.java new file mode 100644 index 000000000000..9478f14186bf --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/NettyReactiveManagementContextAutoConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty.autoconfigure.actuate.web; + +import reactor.netty.http.server.HttpServer; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * Auto-configuration for a Netty-based reactive management context. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ HttpServer.class, ManagementContextFactory.class }) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) +public class NettyReactiveManagementContextAutoConfiguration { + + @Bean + static ManagementContextFactory reactiveWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, + NettyReactiveWebServerAutoConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/package-info.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/package-info.java new file mode 100644 index 000000000000..f512c51ced88 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/actuate/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Reactor Netty actuator web concerns. + */ +package org.springframework.boot.reactor.netty.autoconfigure.actuate.web; diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/package-info.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/package-info.java new file mode 100644 index 000000000000..4f8adb491b97 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Reactor Netty. + */ +package org.springframework.boot.reactor.netty.autoconfigure; diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/package-info.java b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/package-info.java new file mode 100644 index 000000000000..7ce764f7bc7d --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive web server implementation backed by Netty. + * + */ +package org.springframework.boot.reactor.netty; diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..210c2117205c --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,12 @@ +{ + "groups": [], + "properties": [ + { + "name": "server.netty.max-chunk-size", + "deprecation": { + "reason": "Deprecated for removal in Reactor Netty.", + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..01d61ae1c32a --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.reactor.netty.autoconfigure.actuate.web.NettyReactiveManagementChildContextConfiguration diff --git a/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..1fa161d3a365 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration +org.springframework.boot.reactor.netty.autoconfigure.actuate.web.NettyReactiveManagementContextAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/NettyReactiveWebServerFactoryTests.java similarity index 96% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactoryTests.java rename to spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/NettyReactiveWebServerFactoryTests.java index cb03e6efb0e4..ac015283af26 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/NettyReactiveWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.netty; +package org.springframework.boot.reactor.netty; import java.net.ConnectException; import java.net.SocketAddress; @@ -40,11 +40,12 @@ import org.springframework.boot.ssl.pem.PemSslStoreBundle; import org.springframework.boot.ssl.pem.PemSslStoreDetails; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests; import org.springframework.boot.web.server.PortInUseException; import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactoryTests; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; import org.springframework.http.MediaType; import org.springframework.http.client.ReactorResourceFactory; import org.springframework.http.client.reactive.ReactorClientHttpConnector; @@ -228,7 +229,7 @@ protected String startedLogMessage() { } @Override - protected void addConnector(int port, AbstractReactiveWebServerFactory factory) { + protected void addConnector(int port, ConfigurableReactiveWebServerFactory factory) { throw new UnsupportedOperationException("Reactor Netty does not support multiple ports"); } diff --git a/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..453fdfc83b14 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerAutoConfigurationTests.java @@ -0,0 +1,101 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty.autoconfigure; + +import org.junit.jupiter.api.Test; +import reactor.netty.http.server.HttpServer; + +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.reactor.netty.NettyServerCustomizer; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.reactive.AbstractReactiveWebServerAutoConfigurationTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link NettyReactiveWebServerAutoConfiguration}. + * + * @author Brian Clozel + * @author Raheela Aslam + * @author Madhura Bhave + * @author Scott Frederick + */ +// @DirtiesUrlFactories +class NettyReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests { + + NettyReactiveWebServerAutoConfigurationTests() { + super(NettyReactiveWebServerAutoConfiguration.class); + } + + @Test + void nettyServerCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(NettyServerCustomizerConfiguration.class).run((context) -> { + NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class); + assertThat(factory.getServerCustomizers()) + .contains(context.getBean("serverCustomizer", NettyServerCustomizer.class)); + }); + } + + @Test + void nettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationNettyServerCustomizerConfiguration.class) + .run((context) -> { + NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class); + NettyServerCustomizer customizer = context.getBean("serverCustomizer", NettyServerCustomizer.class); + assertThat(factory.getServerCustomizers()).contains(customizer); + then(customizer).should().apply(any(HttpServer.class)); + }); + } + + @Configuration(proxyBeanMethods = false) + static class NettyServerCustomizerConfiguration { + + @Bean + NettyServerCustomizer serverCustomizer() { + return (server) -> server; + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationNettyServerCustomizerConfiguration { + + private final NettyServerCustomizer customizer = mock(NettyServerCustomizer.class); + + DoubleRegistrationNettyServerCustomizerConfiguration() { + given(this.customizer.apply(any(HttpServer.class))).willAnswer((invocation) -> invocation.getArgument(0)); + } + + @Bean + NettyServerCustomizer serverCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer nettyCustomizer() { + return (netty) -> netty.addServerCustomizers(this.customizer); + } + + } + +} diff --git a/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerFactoryCustomizerTests.java new file mode 100644 index 000000000000..f8e210bf165c --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyReactiveWebServerFactoryCustomizerTests.java @@ -0,0 +1,202 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty.autoconfigure; + +import java.time.Duration; +import java.util.Map; + +import io.netty.channel.ChannelOption; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.junit.jupiter.MockitoExtension; +import reactor.netty.http.Http2SettingsSpec; +import reactor.netty.http.server.HttpRequestDecoderSpec; +import reactor.netty.http.server.HttpServer; + +import org.springframework.boot.context.properties.source.ConfigurationPropertySources; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.reactor.netty.NettyServerCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.mock.env.MockEnvironment; +import org.springframework.util.unit.DataSize; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; + +/** + * Tests for {@link NettyReactiveWebServerFactoryCustomizer}. + * + * @author Brian Clozel + * @author Artsiom Yudovin + * @author Leo Li + */ +@ExtendWith(MockitoExtension.class) +class NettyReactiveWebServerFactoryCustomizerTests { + + private final MockEnvironment environment = new MockEnvironment(); + + private final ServerProperties serverProperties = new ServerProperties(); + + private final NettyServerProperties nettyProperties = new NettyServerProperties(); + + private NettyReactiveWebServerFactoryCustomizer customizer; + + @Captor + private ArgumentCaptor customizerCaptor; + + @BeforeEach + void setup() { + ConfigurationPropertySources.attach(this.environment); + this.customizer = new NettyReactiveWebServerFactoryCustomizer(this.environment, this.serverProperties, + this.nettyProperties); + } + + @Test + void deduceUseForwardHeaders() { + this.environment.setProperty("DYNO", "-"); + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + then(factory).should().setUseForwardHeaders(true); + } + + @Test + void defaultUseForwardHeaders() { + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + then(factory).should().setUseForwardHeaders(false); + } + + @Test + void forwardHeadersWhenStrategyIsNativeShouldConfigureValve() { + this.serverProperties.setForwardHeadersStrategy(ServerProperties.ForwardHeadersStrategy.NATIVE); + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + then(factory).should().setUseForwardHeaders(true); + } + + @Test + void forwardHeadersWhenStrategyIsNoneShouldNotConfigureValve() { + this.environment.setProperty("DYNO", "-"); + this.serverProperties.setForwardHeadersStrategy(ServerProperties.ForwardHeadersStrategy.NONE); + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + then(factory).should().setUseForwardHeaders(false); + } + + @Test + void setConnectionTimeout() { + this.nettyProperties.setConnectionTimeout(Duration.ofSeconds(1)); + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + verifyConnectionTimeout(factory, 1000); + } + + @Test + void setIdleTimeout() { + this.nettyProperties.setIdleTimeout(Duration.ofSeconds(1)); + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + verifyIdleTimeout(factory, Duration.ofSeconds(1)); + } + + @Test + void setMaxKeepAliveRequests() { + this.nettyProperties.setMaxKeepAliveRequests(100); + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + verifyMaxKeepAliveRequests(factory, 100); + } + + @Test + void setHttp2MaxRequestHeaderSize() { + DataSize headerSize = DataSize.ofKilobytes(24); + this.serverProperties.getHttp2().setEnabled(true); + this.serverProperties.setMaxHttpRequestHeaderSize(headerSize); + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + verifyHttp2MaxHeaderSize(factory, headerSize.toBytes()); + } + + @Test + void configureHttpRequestDecoder() { + NettyServerProperties nettyProperties = this.nettyProperties; + this.serverProperties.setMaxHttpRequestHeaderSize(DataSize.ofKilobytes(24)); + nettyProperties.setValidateHeaders(false); + nettyProperties.setInitialBufferSize(DataSize.ofBytes(512)); + nettyProperties.setH2cMaxContentLength(DataSize.ofKilobytes(1)); + nettyProperties.setMaxInitialLineLength(DataSize.ofKilobytes(32)); + NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class); + this.customizer.customize(factory); + then(factory).should().addServerCustomizers(this.customizerCaptor.capture()); + NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); + HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); + HttpRequestDecoderSpec decoder = httpServer.configuration().decoder(); + assertThat(decoder.validateHeaders()).isFalse(); + assertThat(decoder.maxHeaderSize()).isEqualTo(this.serverProperties.getMaxHttpRequestHeaderSize().toBytes()); + assertThat(decoder.initialBufferSize()).isEqualTo(nettyProperties.getInitialBufferSize().toBytes()); + assertThat(decoder.h2cMaxContentLength()).isEqualTo(nettyProperties.getH2cMaxContentLength().toBytes()); + assertThat(decoder.maxInitialLineLength()).isEqualTo(nettyProperties.getMaxInitialLineLength().toBytes()); + } + + private void verifyConnectionTimeout(NettyReactiveWebServerFactory factory, Integer expected) { + if (expected == null) { + then(factory).should(never()).addServerCustomizers(any(NettyServerCustomizer.class)); + return; + } + then(factory).should(times(2)).addServerCustomizers(this.customizerCaptor.capture()); + NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); + HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); + Map, ?> options = httpServer.configuration().options(); + assertThat(options.get(ChannelOption.CONNECT_TIMEOUT_MILLIS)).isEqualTo(expected); + } + + private void verifyIdleTimeout(NettyReactiveWebServerFactory factory, Duration expected) { + if (expected == null) { + then(factory).should(never()).addServerCustomizers(any(NettyServerCustomizer.class)); + return; + } + then(factory).should(times(2)).addServerCustomizers(this.customizerCaptor.capture()); + NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); + HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); + Duration idleTimeout = httpServer.configuration().idleTimeout(); + assertThat(idleTimeout).isEqualTo(expected); + } + + private void verifyMaxKeepAliveRequests(NettyReactiveWebServerFactory factory, int expected) { + then(factory).should(times(2)).addServerCustomizers(this.customizerCaptor.capture()); + NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); + HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); + int maxKeepAliveRequests = httpServer.configuration().maxKeepAliveRequests(); + assertThat(maxKeepAliveRequests).isEqualTo(expected); + } + + private void verifyHttp2MaxHeaderSize(NettyReactiveWebServerFactory factory, long expected) { + then(factory).should(times(2)).addServerCustomizers(this.customizerCaptor.capture()); + NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0); + HttpServer httpServer = serverCustomizer.apply(HttpServer.create()); + Http2SettingsSpec decoder = httpServer.configuration().http2SettingsSpec(); + assertThat(decoder.maxHeaderListSize()).isEqualTo(expected); + } + +} diff --git a/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyServerPropertiesTests.java b/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyServerPropertiesTests.java new file mode 100644 index 000000000000..d1953291e599 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/autoconfigure/NettyServerPropertiesTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.reactor.netty.autoconfigure; + +import java.time.Duration; +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import reactor.netty.http.HttpDecoderSpec; + +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.context.properties.source.ConfigurationPropertySource; +import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link NettyServerProperties}. + * + * @author Andy Wilkinson + */ +class NettyServerPropertiesTests { + + private final NettyServerProperties properties = new NettyServerProperties(); + + @Test + void testCustomizeNettyIdleTimeout() { + bind("server.netty.idle-timeout", "10s"); + assertThat(this.properties.getIdleTimeout()).isEqualTo(Duration.ofSeconds(10)); + } + + @Test + void testCustomizeNettyMaxKeepAliveRequests() { + bind("server.netty.max-keep-alive-requests", "100"); + assertThat(this.properties.getMaxKeepAliveRequests()).isEqualTo(100); + } + + @Test + void nettyMaxInitialLineLengthMatchesHttpDecoderSpecDefault() { + assertThat(this.properties.getMaxInitialLineLength().toBytes()) + .isEqualTo(HttpDecoderSpec.DEFAULT_MAX_INITIAL_LINE_LENGTH); + } + + @Test + void nettyValidateHeadersMatchesHttpDecoderSpecDefault() { + assertThat(this.properties.isValidateHeaders()).isTrue(); + } + + @Test + void nettyH2cMaxContentLengthMatchesHttpDecoderSpecDefault() { + assertThat(this.properties.getH2cMaxContentLength().toBytes()).isZero(); + } + + @Test + void nettyInitialBufferSizeMatchesHttpDecoderSpecDefault() { + assertThat(this.properties.getInitialBufferSize().toBytes()) + .isEqualTo(HttpDecoderSpec.DEFAULT_INITIAL_BUFFER_SIZE); + } + + private void bind(String name, String value) { + bind(Collections.singletonMap(name, value)); + } + + private void bind(Map map) { + ConfigurationPropertySource source = new MapConfigurationPropertySource(map); + new Binder(source).bind("server.netty", Bindable.ofInstance(this.properties)); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/1.crt b/spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/1.crt similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/1.crt rename to spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/1.crt diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/1.key b/spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/1.key rename to spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/2.crt b/spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/2.crt similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/2.crt rename to spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/2.crt diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/2.key b/spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/2.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/2.key rename to spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/2.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/jetty/test.jks b/spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/jetty/test.jks rename to spring-boot-project/spring-boot-reactor-netty/src/test/resources/org/springframework/boot/reactor/netty/test.jks diff --git a/spring-boot-project/spring-boot-reactor/build.gradle b/spring-boot-project/spring-boot-reactor/build.gradle new file mode 100644 index 000000000000..1226ebe66ab2 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor/build.gradle @@ -0,0 +1,39 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Reactor" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("io.projectreactor:reactor-core") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("io.micrometer:context-propagation") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/reactor/ReactorEnvironmentPostProcessor.java b/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/ReactorEnvironmentPostProcessor.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/reactor/ReactorEnvironmentPostProcessor.java rename to spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/ReactorEnvironmentPostProcessor.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/ReactorAutoConfiguration.java b/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/ReactorAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/ReactorAutoConfiguration.java rename to spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/ReactorAutoConfiguration.java index 586dc3cdad4c..4180d004f7c6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/ReactorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/ReactorAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.reactor; +package org.springframework.boot.reactor.autoconfigure; import reactor.core.publisher.Hooks; @@ -27,7 +27,7 @@ * {@link EnableAutoConfiguration Auto-configuration} for Reactor. * * @author Brian Clozel - * @since 3.2.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(Hooks.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/ReactorProperties.java b/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/ReactorProperties.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/ReactorProperties.java rename to spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/ReactorProperties.java index da7f7ef0c139..5a486274c11b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/reactor/ReactorProperties.java +++ b/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/ReactorProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.reactor; +package org.springframework.boot.reactor.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -22,7 +22,7 @@ * Configuration properties for Reactor. * * @author Brian Clozel - * @since 3.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.reactor") public class ReactorProperties { diff --git a/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/package-info.java b/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/package-info.java new file mode 100644 index 000000000000..18547b63a5f5 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Reactor. + */ +package org.springframework.boot.reactor.autoconfigure; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/reactor/package-info.java b/spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/reactor/package-info.java rename to spring-boot-project/spring-boot-reactor/src/main/java/org/springframework/boot/reactor/package-info.java diff --git a/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..437f81bd6346 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,13 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.reactor.stacktrace-mode.enabled", + "description": "Whether Reactor should collect stacktrace information at runtime.", + "defaultValue": false, + "deprecation": { + "replacement": "spring.reactor.debug-agent.enabled" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..638d0dfde6a0 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Environment Post Processors +org.springframework.boot.env.EnvironmentPostProcessor=\ +org.springframework.boot.reactor.ReactorEnvironmentPostProcessor diff --git a/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..5fc9bd47c370 --- /dev/null +++ b/spring-boot-project/spring-boot-reactor/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.reactor.autoconfigure.ReactorAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/reactor/InstrumentedFluxProvider.java b/spring-boot-project/spring-boot-reactor/src/test/java/org/springframework/boot/reactor/InstrumentedFluxProvider.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/reactor/InstrumentedFluxProvider.java rename to spring-boot-project/spring-boot-reactor/src/test/java/org/springframework/boot/reactor/InstrumentedFluxProvider.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/reactor/ReactorEnvironmentPostProcessorTests.java b/spring-boot-project/spring-boot-reactor/src/test/java/org/springframework/boot/reactor/ReactorEnvironmentPostProcessorTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/reactor/ReactorEnvironmentPostProcessorTests.java rename to spring-boot-project/spring-boot-reactor/src/test/java/org/springframework/boot/reactor/ReactorEnvironmentPostProcessorTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/reactor/ReactorAutoConfigurationTests.java b/spring-boot-project/spring-boot-reactor/src/test/java/org/springframework/boot/reactor/autoconfigure/ReactorAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/reactor/ReactorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-reactor/src/test/java/org/springframework/boot/reactor/autoconfigure/ReactorAutoConfigurationTests.java index 39222efc78ab..5183090b4b7e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/reactor/ReactorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-reactor/src/test/java/org/springframework/boot/reactor/autoconfigure/ReactorAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.reactor; +package org.springframework.boot.reactor.autoconfigure; import java.util.concurrent.atomic.AtomicReference; diff --git a/spring-boot-project/spring-boot-restclient-test/build.gradle b/spring-boot-project/spring-boot-restclient-test/build.gradle new file mode 100644 index 000000000000..67cee57baf86 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient-test/build.gradle @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot RestClient Test" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-restclient")) + optional("org.springframework:spring-test") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/MockServerRestClientCustomizer.java b/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/MockServerRestClientCustomizer.java similarity index 98% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/MockServerRestClientCustomizer.java rename to spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/MockServerRestClientCustomizer.java index 3fda280c4477..74956567a7aa 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/MockServerRestClientCustomizer.java +++ b/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/MockServerRestClientCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.restclient.test; import java.util.Collections; import java.util.Map; @@ -22,7 +22,7 @@ import java.util.function.Supplier; import org.springframework.beans.BeanUtils; -import org.springframework.boot.web.client.RestClientCustomizer; +import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.http.client.BufferingClientHttpRequestFactory; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.test.web.client.MockRestServiceServer.MockRestServiceServerBuilder; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/MockServerRestTemplateCustomizer.java b/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/MockServerRestTemplateCustomizer.java similarity index 97% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/MockServerRestTemplateCustomizer.java rename to spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/MockServerRestTemplateCustomizer.java index 402906c1d37b..449a7b6a5853 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/MockServerRestTemplateCustomizer.java +++ b/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/MockServerRestTemplateCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.restclient.test; import java.util.Collections; import java.util.Map; @@ -22,8 +22,8 @@ import java.util.function.Supplier; import org.springframework.beans.BeanUtils; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.client.RestTemplateCustomizer; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateCustomizer; import org.springframework.http.client.BufferingClientHttpRequestFactory; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.test.web.client.MockRestServiceServer.MockRestServiceServerBuilder; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/RootUriRequestExpectationManager.java b/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/RootUriRequestExpectationManager.java similarity index 98% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/RootUriRequestExpectationManager.java rename to spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/RootUriRequestExpectationManager.java index 7272262daf82..bc11307b388f 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/RootUriRequestExpectationManager.java +++ b/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/RootUriRequestExpectationManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.restclient.test; import java.io.IOException; import java.io.OutputStream; @@ -22,7 +22,7 @@ import java.net.URISyntaxException; import java.time.Duration; -import org.springframework.boot.web.client.RootUriTemplateHandler; +import org.springframework.boot.restclient.RootUriTemplateHandler; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.support.HttpRequestWrapper; diff --git a/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/package-info.java b/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/package-info.java new file mode 100644 index 000000000000..517a2c65020d --- /dev/null +++ b/spring-boot-project/spring-boot-restclient-test/src/main/java/org/springframework/boot/restclient/test/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * RestClient and RestTemplate test utilities. + */ +package org.springframework.boot.restclient.test; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/MockServerRestClientCustomizerTests.java b/spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/MockServerRestClientCustomizerTests.java similarity index 99% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/MockServerRestClientCustomizerTests.java rename to spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/MockServerRestClientCustomizerTests.java index 14a4dab60c60..61c8db091fe4 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/MockServerRestClientCustomizerTests.java +++ b/spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/MockServerRestClientCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.restclient.test; import java.util.function.Supplier; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/MockServerRestTemplateCustomizerTests.java b/spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/MockServerRestTemplateCustomizerTests.java similarity index 98% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/MockServerRestTemplateCustomizerTests.java rename to spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/MockServerRestTemplateCustomizerTests.java index 4fa0dbda5eab..523fe81a4c78 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/MockServerRestTemplateCustomizerTests.java +++ b/spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/MockServerRestTemplateCustomizerTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.restclient.test; import java.util.function.Supplier; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.http.client.BufferingClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.test.web.client.RequestExpectationManager; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/RootUriRequestExpectationManagerTests.java b/spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/RootUriRequestExpectationManagerTests.java similarity index 98% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/RootUriRequestExpectationManagerTests.java rename to spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/RootUriRequestExpectationManagerTests.java index 7e5d9eb3aa4b..5539e6ee9747 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/RootUriRequestExpectationManagerTests.java +++ b/spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/RootUriRequestExpectationManagerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.restclient.test; import java.net.URI; @@ -24,7 +24,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.support.HttpRequestWrapper; import org.springframework.test.web.client.ExpectedCount; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/scan/SimpleFactoryBean.java b/spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/scan/SimpleFactoryBean.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/scan/SimpleFactoryBean.java rename to spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/scan/SimpleFactoryBean.java index b7ddaf8360f0..7ec174fa154c 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/scan/SimpleFactoryBean.java +++ b/spring-boot-project/spring-boot-restclient-test/src/test/java/org/springframework/boot/restclient/test/scan/SimpleFactoryBean.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client.scan; +package org.springframework.boot.restclient.test.scan; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot-project/spring-boot-restclient/build.gradle b/spring-boot-project/spring-boot-restclient/build.gradle new file mode 100644 index 000000000000..27c072d4c3be --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/build.gradle @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot RestClient and RestTemplate" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-http-client")) + + implementation(project(":spring-boot-project:spring-boot-http-converter")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-observation")) + optional("io.projectreactor.netty:reactor-netty-http") + optional("org.apache.httpcomponents.client5:httpclient5") + optional("org.eclipse.jetty:jetty-client") + + testImplementation(project(":spring-boot-project:spring-boot-metrics")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("io.micrometer:micrometer-observation-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("jakarta.servlet:jakarta.servlet-api") + testRuntimeOnly("org.springframework:spring-webflux") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/BasicAuthentication.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/BasicAuthentication.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/BasicAuthentication.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/BasicAuthentication.java index ca445eaf2309..0c5eebeeb540 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/BasicAuthentication.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/BasicAuthentication.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import java.nio.charset.Charset; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestClientCustomizer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestClientCustomizer.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestClientCustomizer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestClientCustomizer.java index 6dae4ba09003..e87b34485bb2 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestClientCustomizer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestClientCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import org.springframework.web.client.RestClient; @@ -23,7 +23,7 @@ * {@link org.springframework.web.client.RestClient.Builder RestClient.Builder}. * * @author Arjen Poutsma - * @since 3.2.0 + * @since 4.0.0 */ @FunctionalInterface public interface RestClientCustomizer { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateBuilder.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateBuilder.java index f975f58cd1f5..2ecbbe1c30e2 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateBuilder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import java.nio.charset.Charset; import java.time.Duration; @@ -27,7 +27,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; import java.util.function.Supplier; import java.util.function.UnaryOperator; @@ -67,7 +66,7 @@ * @author Ilya Lukyanovich * @author Scott Frederick * @author Yanming Zhou - * @since 1.4.0 + * @since 4.0.0 */ public class RestTemplateBuilder { @@ -326,27 +325,6 @@ public RestTemplateBuilder requestFactory(Supplier req return requestFactoryBuilder(ClientHttpRequestFactoryBuilder.of(requestFactorySupplier)); } - /** - * Set the request factory function that should be called to provide a - * {@link ClientHttpRequestFactory} each time we {@link #build()} a new - * {@link RestTemplate} instance. - * @param requestFactoryFunction the settings to request factory function - * @return a new builder instance - * @since 3.0.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #requestFactoryBuilder(ClientHttpRequestFactoryBuilder)} - * @see ClientHttpRequestFactoryBuilder - * @see #requestFactoryBuilder(ClientHttpRequestFactoryBuilder) - */ - @Deprecated(since = "3.4.0", forRemoval = true) - @SuppressWarnings("removal") - public RestTemplateBuilder requestFactory( - Function requestFactoryFunction) { - Assert.notNull(requestFactoryFunction, "'requestFactoryFunction' must not be null"); - return requestFactoryBuilder((settings) -> requestFactoryFunction - .apply(org.springframework.boot.web.client.ClientHttpRequestFactorySettings.of(settings))); - } - /** * Set the {@link ClientHttpRequestFactoryBuilder} that should be used each time we * {@link #build()} a new {@link RestTemplate} instance. @@ -468,19 +446,6 @@ public RestTemplateBuilder requestFactorySettings( this.defaultHeaders, this.customizers, this.requestCustomizers); } - /** - * Sets the connection timeout on the underlying {@link ClientHttpRequestFactory}. - * @param connectTimeout the connection timeout - * @return a new builder instance. - * @since 2.1.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #connectTimeout(Duration)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public RestTemplateBuilder setConnectTimeout(Duration connectTimeout) { - return connectTimeout(connectTimeout); - } - /** * Sets the connection timeout on the underlying {@link ClientHttpRequestFactory}. * @param connectTimeout the connection timeout @@ -494,19 +459,6 @@ public RestTemplateBuilder connectTimeout(Duration connectTimeout) { this.defaultHeaders, this.customizers, this.requestCustomizers); } - /** - * Sets the read timeout on the underlying {@link ClientHttpRequestFactory}. - * @param readTimeout the read timeout - * @return a new builder instance. - * @since 2.1.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #readTimeout(Duration)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public RestTemplateBuilder setReadTimeout(Duration readTimeout) { - return readTimeout(readTimeout); - } - /** * Sets the read timeout on the underlying {@link ClientHttpRequestFactory}. * @param readTimeout the read timeout @@ -533,19 +485,6 @@ public RestTemplateBuilder redirects(HttpRedirects redirects) { this.customizers, this.requestCustomizers); } - /** - * Sets the SSL bundle on the underlying {@link ClientHttpRequestFactory}. - * @param sslBundle the SSL bundle - * @return a new builder instance - * @since 3.1.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #sslBundle(SslBundle)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public RestTemplateBuilder setSslBundle(SslBundle sslBundle) { - return sslBundle(sslBundle); - } - /** * Sets the SSL bundle on the underlying {@link ClientHttpRequestFactory}. * @param sslBundle the SSL bundle diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilderClientHttpRequestInitializer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateBuilderClientHttpRequestInitializer.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilderClientHttpRequestInitializer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateBuilderClientHttpRequestInitializer.java index 149326bb4c9e..5803238fcb83 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilderClientHttpRequestInitializer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateBuilderClientHttpRequestInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import java.util.List; import java.util.Map; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateCustomizer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateCustomizer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateCustomizer.java index 76c48f00839d..e0d0c81f0563 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateCustomizer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import org.springframework.web.client.RestTemplate; @@ -22,7 +22,7 @@ * Callback interface that can be used to customize a {@link RestTemplate}. * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 * @see RestTemplateBuilder */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateRequestCustomizer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateRequestCustomizer.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateRequestCustomizer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateRequestCustomizer.java index dba37fcd0288..03ecdf684382 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateRequestCustomizer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RestTemplateRequestCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestInitializer; @@ -27,7 +27,7 @@ * @param the {@link ClientHttpRequest} type * @author Ilya Lukyanovich * @author Phillip Webb - * @since 2.2.0 + * @since 4.0.0 * @see RestTemplateBuilder * @see ClientHttpRequestInitializer */ diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RootUriBuilderFactory.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RootUriBuilderFactory.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RootUriBuilderFactory.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RootUriBuilderFactory.java index 67df7fa40ed9..57611cde279a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RootUriBuilderFactory.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RootUriBuilderFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import org.springframework.util.Assert; import org.springframework.web.client.RestTemplate; @@ -27,7 +27,7 @@ * {@link UriBuilderFactory} to set the root for URI that starts with {@code '/'}. * * @author Scott Frederick - * @since 3.2.3 + * @since 4.0.0 */ public class RootUriBuilderFactory extends RootUriTemplateHandler implements UriBuilderFactory { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RootUriTemplateHandler.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RootUriTemplateHandler.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RootUriTemplateHandler.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RootUriTemplateHandler.java index eda6a4e7bdab..4a7d9d958d26 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RootUriTemplateHandler.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/RootUriTemplateHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import java.net.URI; import java.util.Map; @@ -28,7 +28,7 @@ * * @author Phillip Webb * @author Scott Frederick - * @since 1.4.0 + * @since 4.0.0 */ public class RootUriTemplateHandler implements UriTemplateHandler { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/AutoConfiguredRestClientSsl.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/AutoConfiguredRestClientSsl.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/AutoConfiguredRestClientSsl.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/AutoConfiguredRestClientSsl.java index b511b82e9e6d..cba2ec09fa60 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/AutoConfiguredRestClientSsl.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/AutoConfiguredRestClientSsl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.util.function.Consumer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/HttpMessageConvertersRestClientCustomizer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/HttpMessageConvertersRestClientCustomizer.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/HttpMessageConvertersRestClientCustomizer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/HttpMessageConvertersRestClientCustomizer.java index b0224a35047f..4fd8ed6dc885 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/HttpMessageConvertersRestClientCustomizer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/HttpMessageConvertersRestClientCustomizer.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.util.Arrays; import java.util.List; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.web.client.RestClientCustomizer; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; +import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.util.Assert; import org.springframework.web.client.RestClient; @@ -30,7 +30,7 @@ * HttpMessageConverters}. * * @author Phillip Webb - * @since 3.2.0 + * @since 4.0.0 */ public class HttpMessageConvertersRestClientCustomizer implements RestClientCustomizer { diff --git a/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/NotReactiveWebApplicationCondition.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/NotReactiveWebApplicationCondition.java new file mode 100644 index 000000000000..4de24c51b6e9 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/NotReactiveWebApplicationCondition.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.restclient.autoconfigure; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; + +/** + * {@link SpringBootCondition} that applies only when running in a non-reactive web + * application. + * + * @author Phillip Webb + */ +class NotReactiveWebApplicationCondition extends NoneNestedConditions { + + NotReactiveWebApplicationCondition() { + super(ConfigurationPhase.PARSE_CONFIGURATION); + } + + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + private static final class ReactiveWebApplication { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java index dc8cbcbee2f7..e4894a4d10c9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientAutoConfiguration.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientAutoConfiguration.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientAutoConfiguration.java index 8641fe5d0643..8e8f502e0965 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -23,15 +23,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration; import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.autoconfigure.HttpClientAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; +import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.client.RestClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Scope; @@ -49,22 +48,14 @@ * * @author Arjen Poutsma * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { HttpClientAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - SslAutoConfiguration.class, TaskExecutionAutoConfiguration.class }) +@AutoConfiguration( + after = { HttpClientAutoConfiguration.class, TaskExecutionAutoConfiguration.class, SslAutoConfiguration.class }) @ConditionalOnClass(RestClient.class) @Conditional(NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.class) public class RestClientAutoConfiguration { - @Bean - @ConditionalOnMissingBean - @Order(Ordered.LOWEST_PRECEDENCE) - HttpMessageConvertersRestClientCustomizer httpMessageConvertersRestClientCustomizer( - ObjectProvider messageConverters) { - return new HttpMessageConvertersRestClientCustomizer(messageConverters.getIfUnique()); - } - @Bean @ConditionalOnMissingBean(RestClientSsl.class) @ConditionalOnBean(SslBundles.class) @@ -96,4 +87,17 @@ RestClient.Builder restClientBuilder(RestClientBuilderConfigurer restClientBuild return restClientBuilderConfigurer.configure(RestClient.builder()); } + @ConditionalOnClass(HttpMessageConverters.class) + static class HttpMessageConvertersConfiguration { + + @Bean + @ConditionalOnMissingBean + @Order(Ordered.LOWEST_PRECEDENCE) + HttpMessageConvertersRestClientCustomizer httpMessageConvertersRestClientCustomizer( + ObjectProvider messageConverters) { + return new HttpMessageConvertersRestClientCustomizer(messageConverters.getIfUnique()); + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientBuilderConfigurer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientBuilderConfigurer.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientBuilderConfigurer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientBuilderConfigurer.java index a184e7cda92d..231abe2cfdeb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientBuilderConfigurer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientBuilderConfigurer.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.util.Collections; import java.util.List; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; -import org.springframework.boot.web.client.RestClientCustomizer; +import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.web.client.RestClient; import org.springframework.web.client.RestClient.Builder; @@ -33,7 +33,7 @@ * auto-configuration. * * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ public class RestClientBuilderConfigurer { diff --git a/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientObservationAutoConfiguration.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientObservationAutoConfiguration.java new file mode 100644 index 000000000000..b9e1fb5bf01a --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientObservationAutoConfiguration.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.restclient.autoconfigure; + +import io.micrometer.observation.ObservationRegistry; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.observation.autoconfigure.ObservationProperties; +import org.springframework.boot.restclient.RestClientCustomizer; +import org.springframework.boot.restclient.observation.ObservationRestClientCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.http.client.observation.ClientRequestObservationConvention; +import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; +import org.springframework.web.client.RestClient; + +/** + * Configure the instrumentation of {@link RestClient}. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ RestClient.class, ObservationRestClientCustomizer.class, ObservationRegistry.class, + ObservationProperties.class }) +@ConditionalOnBean({ RestClient.Builder.class, ObservationRegistry.class }) +@EnableConfigurationProperties(ObservationProperties.class) +public class RestClientObservationAutoConfiguration { + + @Bean + RestClientCustomizer observationRestClientCustomizer(ObservationRegistry observationRegistry, + ObjectProvider customConvention, + ObservationProperties observationProperties) { + String name = observationProperties.getHttp().getClient().getRequests().getName(); + ClientRequestObservationConvention observationConvention = customConvention + .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name)); + return new ObservationRestClientCustomizer(observationRegistry, observationConvention); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientSsl.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientSsl.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientSsl.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientSsl.java index 2dc69212386b..54a4e9f33bb2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestClientSsl.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestClientSsl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.util.function.Consumer; @@ -44,7 +44,7 @@ * consider using a {@link ClientHttpRequestFactoryBuilder}. * * @author Phillip Webb - * @since 3.2.0 + * @since 4.0.0 */ public interface RestClientSsl { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateAutoConfiguration.java index 6011f330ee72..2dcf0397e42e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateAutoConfiguration.java @@ -14,21 +14,20 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.client.RestTemplateCustomizer; -import org.springframework.boot.web.client.RestTemplateRequestCustomizer; +import org.springframework.boot.http.client.autoconfigure.HttpClientAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateCustomizer; +import org.springframework.boot.restclient.RestTemplateRequestCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Lazy; @@ -40,10 +39,10 @@ * * @author Stephane Nicoll * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { HttpClientAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) -@ConditionalOnClass(RestTemplate.class) +@AutoConfiguration(after = HttpClientAutoConfiguration.class) +@ConditionalOnClass({ RestTemplate.class, HttpMessageConverters.class }) @Conditional(NotReactiveWebApplicationCondition.class) public class RestTemplateAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestTemplateBuilderConfigurer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateBuilderConfigurer.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestTemplateBuilderConfigurer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateBuilderConfigurer.java index 484d91b66373..70b1126f0aa0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/client/RestTemplateBuilderConfigurer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateBuilderConfigurer.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.util.Collection; import java.util.List; import java.util.function.BiFunction; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.client.RestTemplateCustomizer; -import org.springframework.boot.web.client.RestTemplateRequestCustomizer; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateCustomizer; +import org.springframework.boot.restclient.RestTemplateRequestCustomizer; import org.springframework.util.ObjectUtils; /** @@ -36,7 +36,7 @@ * auto-configuration. * * @author Stephane Nicoll - * @since 2.4.0 + * @since 4.0.0 */ public final class RestTemplateBuilderConfigurer { diff --git a/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateObservationAutoConfiguration.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateObservationAutoConfiguration.java new file mode 100644 index 000000000000..0dc13bf2ad3f --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/RestTemplateObservationAutoConfiguration.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.restclient.autoconfigure; + +import io.micrometer.observation.ObservationRegistry; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.observation.autoconfigure.ObservationProperties; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.observation.ObservationRestTemplateCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.http.client.observation.ClientRequestObservationConvention; +import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; +import org.springframework.web.client.RestTemplate; + +/** + * Configure the instrumentation of {@link RestTemplate}. + * + * @author Brian Clozel + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ RestTemplate.class, ObservationRestTemplateCustomizer.class, ObservationRegistry.class, + ObservationProperties.class }) +@ConditionalOnBean({ ObservationRegistry.class, RestTemplateBuilder.class }) +@EnableConfigurationProperties(ObservationProperties.class) +public class RestTemplateObservationAutoConfiguration { + + @Bean + ObservationRestTemplateCustomizer observationRestTemplateCustomizer(ObservationRegistry observationRegistry, + ObjectProvider customConvention, + ObservationProperties observationProperties) { + String name = observationProperties.getHttp().getClient().getRequests().getName(); + ClientRequestObservationConvention observationConvention = customConvention + .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name)); + return new ObservationRestTemplateCustomizer(observationRegistry, observationConvention); + } + +} diff --git a/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/package-info.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/package-info.java new file mode 100644 index 000000000000..0a7984ff8c18 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for RestClient and RestTemplate. + */ +package org.springframework.boot.restclient.autoconfigure; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/AbstractHttpClientServiceProperties.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/AbstractHttpClientServiceProperties.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/AbstractHttpClientServiceProperties.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/AbstractHttpClientServiceProperties.java index cbcbec1fae2d..3f22869a65ce 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/AbstractHttpClientServiceProperties.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/AbstractHttpClientServiceProperties.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.service; +package org.springframework.boot.restclient.autoconfigure.service; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.springframework.boot.autoconfigure.http.client.AbstractHttpRequestFactoryProperties; +import org.springframework.boot.http.client.autoconfigure.AbstractHttpRequestFactoryProperties; /** * {@link AbstractHttpRequestFactoryProperties} for HTTP Service clients. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/HttpClientServiceProperties.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpClientServiceProperties.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/HttpClientServiceProperties.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpClientServiceProperties.java index 17993f6db384..ef1873da0502 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/HttpClientServiceProperties.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpClientServiceProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.service; +package org.springframework.boot.restclient.autoconfigure.service; import java.util.LinkedHashMap; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/HttpServiceClientAutoConfiguration.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/HttpServiceClientAutoConfiguration.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java index 7701370c1fca..caa4a412ef7a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/HttpServiceClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.service; +package org.springframework.boot.restclient.autoconfigure.service; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration; -import org.springframework.boot.autoconfigure.http.client.HttpClientProperties; -import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.autoconfigure.HttpClientAutoConfiguration; +import org.springframework.boot.http.client.autoconfigure.HttpClientProperties; +import org.springframework.boot.restclient.RestClientCustomizer; +import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration; import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.client.RestClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.web.client.support.RestClientAdapter; diff --git a/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java new file mode 100644 index 000000000000..96153da15873 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.restclient.autoconfigure.service; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; + +/** + * {@link SpringBootCondition} that applies only when running in a non-reactive web + * application. + * + * @author Phillip Webb + */ +class NotReactiveWebApplicationCondition extends NoneNestedConditions { + + NotReactiveWebApplicationCondition() { + super(ConfigurationPhase.PARSE_CONFIGURATION); + } + + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + private static final class ReactiveWebApplication { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/RestClientCustomizerHttpServiceGroupConfigurer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/RestClientCustomizerHttpServiceGroupConfigurer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/RestClientCustomizerHttpServiceGroupConfigurer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/RestClientCustomizerHttpServiceGroupConfigurer.java index 9e0cb3985e1b..78bd156e3f3b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/RestClientCustomizerHttpServiceGroupConfigurer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/RestClientCustomizerHttpServiceGroupConfigurer.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.service; +package org.springframework.boot.restclient.autoconfigure.service; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.web.client.RestClientCustomizer; +import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.web.client.RestClient; import org.springframework.web.client.support.RestClientHttpServiceGroupConfigurer; import org.springframework.web.service.registry.HttpServiceGroup; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/RestClientPropertiesHttpServiceGroupConfigurer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/RestClientPropertiesHttpServiceGroupConfigurer.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/RestClientPropertiesHttpServiceGroupConfigurer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/RestClientPropertiesHttpServiceGroupConfigurer.java index 472939bd6051..ec7790ddd1a3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/service/RestClientPropertiesHttpServiceGroupConfigurer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/RestClientPropertiesHttpServiceGroupConfigurer.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.service; +package org.springframework.boot.restclient.autoconfigure.service; import java.util.List; import java.util.Map; import java.util.function.Consumer; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.http.client.ClientHttpRequestFactories; -import org.springframework.boot.autoconfigure.http.client.HttpClientProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.autoconfigure.ClientHttpRequestFactories; +import org.springframework.boot.http.client.autoconfigure.HttpClientProperties; import org.springframework.boot.ssl.SslBundles; import org.springframework.core.Ordered; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/package-info.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/package-info.java new file mode 100644 index 000000000000..d47a4d159d07 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-Configuration for Spring's Blocking HTTP Service Interface Clients. + */ +package org.springframework.boot.restclient.autoconfigure.service; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestClientCustomizer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/ObservationRestClientCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestClientCustomizer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/ObservationRestClientCustomizer.java index b1c9800c92b5..1ec474aa5c7d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestClientCustomizer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/ObservationRestClientCustomizer.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.client; +package org.springframework.boot.restclient.observation; import io.micrometer.observation.ObservationRegistry; -import org.springframework.boot.web.client.RestClientCustomizer; +import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.http.client.observation.ClientRequestObservationConvention; import org.springframework.util.Assert; import org.springframework.web.client.RestClient.Builder; @@ -28,7 +28,7 @@ * record request observations. * * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ public class ObservationRestClientCustomizer implements RestClientCustomizer { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestTemplateCustomizer.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/ObservationRestTemplateCustomizer.java similarity index 92% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestTemplateCustomizer.java rename to spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/ObservationRestTemplateCustomizer.java index 1ac35af887ec..a7338539da6b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestTemplateCustomizer.java +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/ObservationRestTemplateCustomizer.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.client; +package org.springframework.boot.restclient.observation; import io.micrometer.observation.ObservationRegistry; -import org.springframework.boot.web.client.RestTemplateCustomizer; +import org.springframework.boot.restclient.RestTemplateCustomizer; import org.springframework.http.client.observation.ClientRequestObservationConvention; import org.springframework.web.client.RestTemplate; @@ -27,7 +27,7 @@ * request observations. * * @author Brian Clozel - * @since 3.0.0 + * @since 4.0.0 */ public class ObservationRestTemplateCustomizer implements RestTemplateCustomizer { diff --git a/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/package-info.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/package-info.java new file mode 100644 index 000000000000..b05362039549 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/observation/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Observation integration for RestClient and RestTemplate. + */ +package org.springframework.boot.restclient.observation; diff --git a/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/package-info.java b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/package-info.java new file mode 100644 index 000000000000..feecadcbc27c --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Web client utilities. + */ +package org.springframework.boot.restclient; diff --git a/spring-boot-project/spring-boot-restclient/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-restclient/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..4e3ab1095125 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,5 @@ +org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration +org.springframework.boot.restclient.autoconfigure.RestClientObservationAutoConfiguration +org.springframework.boot.restclient.autoconfigure.RestTemplateAutoConfiguration +org.springframework.boot.restclient.autoconfigure.RestTemplateObservationAutoConfiguration +org.springframework.boot.restclient.autoconfigure.service.HttpServiceClientAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderClientHttpRequestInitializerTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RestTemplateBuilderClientHttpRequestInitializerTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderClientHttpRequestInitializerTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RestTemplateBuilderClientHttpRequestInitializerTests.java index 8038a2c20f75..8a829be0f2a0 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderClientHttpRequestInitializerTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RestTemplateBuilderClientHttpRequestInitializerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import java.util.Arrays; import java.util.Collections; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RestTemplateBuilderTests.java similarity index 97% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RestTemplateBuilderTests.java index 135897077c6a..a014b35ca65e 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RestTemplateBuilderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import java.net.URI; import java.nio.charset.StandardCharsets; @@ -22,7 +22,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.Set; -import java.util.function.Function; import java.util.function.Supplier; import org.junit.jupiter.api.Test; @@ -274,14 +273,6 @@ void requestFactoryWhenSupplierIsNullShouldThrowException() { .withMessageContaining("requestFactorySupplier' must not be null"); } - @Test - @SuppressWarnings("removal") - void requestFactoryWhenFunctionIsNullShouldThrowException() { - assertThatIllegalArgumentException().isThrownBy(() -> this.builder.requestFactory( - (Function) null)) - .withMessageContaining("'requestFactoryFunction' must not be null"); - } - @Test void requestFactoryShouldApply() { ClientHttpRequestFactory requestFactory = mock(ClientHttpRequestFactory.class); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RootUriBuilderFactoryTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RootUriBuilderFactoryTests.java similarity index 96% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RootUriBuilderFactoryTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RootUriBuilderFactoryTests.java index 79dd317b1bda..7251decdd0b2 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RootUriBuilderFactoryTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RootUriBuilderFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import java.net.URI; import java.net.URISyntaxException; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RootUriTemplateHandlerTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RootUriTemplateHandlerTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RootUriTemplateHandlerTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RootUriTemplateHandlerTests.java index 4f2c20d3f4a9..ffc7b99c80d5 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RootUriTemplateHandlerTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/RootUriTemplateHandlerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.client; +package org.springframework.boot.restclient; import java.net.URI; import java.net.URISyntaxException; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/AutoConfiguredRestClientSslTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/AutoConfiguredRestClientSslTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/AutoConfiguredRestClientSslTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/AutoConfiguredRestClientSslTests.java index 275545c24527..207051e4ce82 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/AutoConfiguredRestClientSslTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/AutoConfiguredRestClientSslTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.time.Duration; import java.util.function.Consumer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/HttpMessageConvertersRestClientCustomizerTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/HttpMessageConvertersRestClientCustomizerTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/HttpMessageConvertersRestClientCustomizerTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/HttpMessageConvertersRestClientCustomizerTests.java index b6c63ad25a07..33daa4b69e06 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/HttpMessageConvertersRestClientCustomizerTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/HttpMessageConvertersRestClientCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.util.ArrayList; import java.util.Arrays; @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.client.RestClient; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestClientAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestClientAutoConfigurationTests.java index 3e27b4dcbdb5..e72064cce444 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestClientAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.time.Duration; import java.util.List; @@ -24,19 +24,19 @@ import org.junit.jupiter.api.condition.JRE; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.autoconfigure.HttpClientAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.client.RestClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.SimpleClientHttpRequestFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestClientBuilderConfigurerTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestClientBuilderConfigurerTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestClientBuilderConfigurerTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestClientBuilderConfigurerTests.java index 47701acd482d..e76ae0385102 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestClientBuilderConfigurerTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestClientBuilderConfigurerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.util.List; @@ -25,8 +25,8 @@ import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.web.client.RestClientCustomizer; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.web.client.RestClient; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfigurationTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestTemplateAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfigurationTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestTemplateAutoConfigurationTests.java index 07ef19e4f377..78b229d9a8e5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/RestTemplateAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.client; +package org.springframework.boot.restclient.autoconfigure; import java.util.Collections; import java.util.List; @@ -23,15 +23,15 @@ import org.springframework.beans.factory.support.BeanDefinitionOverrideException; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration; +import org.springframework.boot.http.client.autoconfigure.HttpClientAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateCustomizer; +import org.springframework.boot.restclient.RestTemplateRequestCustomizer; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.client.RestTemplateCustomizer; -import org.springframework.boot.web.client.RestTemplateRequestCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; diff --git a/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestClientObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestClientObservationAutoConfigurationTests.java new file mode 100644 index 000000000000..a182483d1e0a --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestClientObservationAutoConfigurationTests.java @@ -0,0 +1,158 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.restclient.autoconfigure.observation; + +import io.micrometer.common.KeyValues; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.Observation.Context; +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.tck.TestObservationRegistry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestClientObservationAutoConfiguration; +import org.springframework.boot.restclient.observation.ObservationRestClientCustomizer; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.client.observation.ClientRequestObservationContext; +import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestClient; +import org.springframework.web.client.RestClient.Builder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; + +/** + * Tests for {@link RestClientObservationAutoConfiguration}. + * + * @author Brian Clozel + * @author Moritz Halbritter + */ +@ExtendWith(OutputCaptureExtension.class) +class RestClientObservationAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(ObservationRegistry.class, TestObservationRegistry::create) + .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, RestClientAutoConfiguration.class, + RestClientObservationAutoConfiguration.class)); + + @Test + void contributesCustomizerBean() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ObservationRestClientCustomizer.class)); + } + + @Test + void restClientCreatedWithBuilderIsInstrumented() { + this.contextRunner.run((context) -> { + RestClient restClient = buildRestClient(context); + restClient.get().uri("/projects/{project}", "spring-boot").retrieve().toBodilessEntity(); + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + assertThat(registry).hasObservationWithNameEqualToIgnoringCase("http.client.requests"); + }); + } + + @Test + void restClientCreatedWithBuilderUsesCustomConventionName() { + final String observationName = "test.metric.name"; + this.contextRunner.withPropertyValues("management.observations.http.client.requests.name=" + observationName) + .run((context) -> { + RestClient restClient = buildRestClient(context); + restClient.get().uri("/projects/{project}", "spring-boot").retrieve().toBodilessEntity(); + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + assertThat(registry).hasObservationWithNameEqualToIgnoringCase(observationName); + }); + } + + @Test + void restClientCreatedWithBuilderUsesCustomConvention() { + this.contextRunner.withUserConfiguration(CustomConvention.class).run((context) -> { + RestClient restClient = buildRestClient(context); + restClient.get().uri("/projects/{project}", "spring-boot").retrieve().toBodilessEntity(); + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + assertThat(registry).hasObservationWithNameEqualTo("http.client.requests") + .that() + .hasLowCardinalityKeyValue("project", "spring-boot"); + }); + } + + @Test + void backsOffWhenRestClientBuilderIsMissing() { + new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, + RestClientObservationAutoConfiguration.class)) + .run((context) -> assertThat(context).doesNotHaveBean(ObservationRestClientCustomizer.class)); + } + + private RestClient buildRestClient(AssertableApplicationContext context) { + RestClientWithMockServer restClientWithMockServer = buildRestClientAndMockServer(context); + restClientWithMockServer.mockServer() + .expect(requestTo("/projects/spring-boot")) + .andRespond(withStatus(HttpStatus.OK)); + return restClientWithMockServer.restClient(); + } + + private RestClientWithMockServer buildRestClientAndMockServer(AssertableApplicationContext context) { + Builder builder = context.getBean(Builder.class); + MockRestServiceServer server = MockRestServiceServer.bindTo(builder).build(); + server.expect(requestTo("/projects/spring-boot")).andRespond(withStatus(HttpStatus.OK)); + return new RestClientWithMockServer(builder.build(), server); + } + + private record RestClientWithMockServer(RestClient restClient, MockRestServiceServer mockServer) { + } + + @Configuration(proxyBeanMethods = false) + static class CustomConventionConfiguration { + + @Bean + CustomConvention customConvention() { + return new CustomConvention(); + } + + } + + static class CustomConvention extends DefaultClientRequestObservationConvention { + + @Override + public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) { + return super.getLowCardinalityKeyValues(context).and("project", "spring-boot"); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MetricsConfiguration { + + @Bean + MeterObservationHandler meterObservationHandler(MeterRegistry registry) { + return new DefaultMeterObservationHandler(registry); + } + + } + +} diff --git a/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestClientObservationAutoConfigurationWithoutMetricsTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestClientObservationAutoConfigurationWithoutMetricsTests.java new file mode 100644 index 000000000000..aeac6b227b8e --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestClientObservationAutoConfigurationWithoutMetricsTests.java @@ -0,0 +1,74 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.restclient.autoconfigure.observation; + +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.tck.TestObservationRegistry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestClientObservationAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.testsupport.classpath.ClassPathExclusions; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestClient; +import org.springframework.web.client.RestClient.Builder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; + +/** + * Tests for {@link RestClientObservationAutoConfiguration} without Micrometer Metrics. + * + * @author Brian Clozel + * @author Andy Wilkinson + * @author Moritz Halbritter + */ +@ExtendWith(OutputCaptureExtension.class) +@ClassPathExclusions("micrometer-core-*.jar") +class RestClientObservationAutoConfigurationWithoutMetricsTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(ObservationRegistry.class, TestObservationRegistry::create) + .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, RestClientAutoConfiguration.class, + RestClientObservationAutoConfiguration.class)); + + @Test + void restClientCreatedWithBuilderIsInstrumented() { + this.contextRunner.run((context) -> { + RestClient restClient = buildRestClient(context); + restClient.get().uri("/projects/{project}", "spring-boot").retrieve().toBodilessEntity(); + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + assertThat(registry).hasObservationWithNameEqualToIgnoringCase("http.client.requests"); + }); + } + + private RestClient buildRestClient(AssertableApplicationContext context) { + Builder builder = context.getBean(Builder.class); + MockRestServiceServer server = MockRestServiceServer.bindTo(builder).build(); + server.expect(requestTo("/projects/spring-boot")).andRespond(withStatus(HttpStatus.OK)); + return builder.build(); + } + +} diff --git a/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestTemplateObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestTemplateObservationAutoConfigurationTests.java new file mode 100644 index 000000000000..d13927f802f1 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestTemplateObservationAutoConfigurationTests.java @@ -0,0 +1,146 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.restclient.autoconfigure.observation; + +import io.micrometer.common.KeyValues; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.Observation.Context; +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.tck.TestObservationRegistry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.autoconfigure.RestTemplateAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestTemplateObservationAutoConfiguration; +import org.springframework.boot.restclient.observation.ObservationRestTemplateCustomizer; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.client.observation.ClientRequestObservationContext; +import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; + +/** + * Tests for {@link RestTemplateObservationAutoConfiguration}. + * + * @author Brian Clozel + */ +@ExtendWith(OutputCaptureExtension.class) +class RestTemplateObservationAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(ObservationRegistry.class, TestObservationRegistry::create) + .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, + RestTemplateAutoConfiguration.class, RestTemplateObservationAutoConfiguration.class)); + + @Test + void contributesCustomizerBean() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ObservationRestTemplateCustomizer.class)); + } + + @Test + void restTemplateCreatedWithBuilderIsInstrumented() { + this.contextRunner.run((context) -> { + RestTemplate restTemplate = buildRestTemplate(context); + restTemplate.getForEntity("/projects/{project}", Void.class, "spring-boot"); + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + assertThat(registry).hasObservationWithNameEqualToIgnoringCase("http.client.requests"); + }); + } + + @Test + void restTemplateCreatedWithBuilderUsesCustomConventionName() { + final String observationName = "test.metric.name"; + this.contextRunner.withPropertyValues("management.observations.http.client.requests.name=" + observationName) + .run((context) -> { + RestTemplate restTemplate = buildRestTemplate(context); + restTemplate.getForEntity("/projects/{project}", Void.class, "spring-boot"); + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + assertThat(registry).hasObservationWithNameEqualToIgnoringCase(observationName); + }); + } + + @Test + void restTemplateCreatedWithBuilderUsesCustomConvention() { + this.contextRunner.withUserConfiguration(CustomConvention.class).run((context) -> { + RestTemplate restTemplate = buildRestTemplate(context); + restTemplate.getForEntity("/projects/{project}", Void.class, "spring-boot"); + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + assertThat(registry).hasObservationWithNameEqualTo("http.client.requests") + .that() + .hasLowCardinalityKeyValue("project", "spring-boot"); + }); + } + + @Test + void backsOffWhenRestTemplateBuilderIsMissing() { + new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, + RestTemplateObservationAutoConfiguration.class)) + .run((context) -> assertThat(context).doesNotHaveBean(ObservationRestTemplateCustomizer.class)); + } + + private RestTemplate buildRestTemplate(AssertableApplicationContext context) { + RestTemplate restTemplate = context.getBean(RestTemplateBuilder.class).build(); + MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate); + server.expect(requestTo("/projects/spring-boot")).andRespond(withStatus(HttpStatus.OK)); + return restTemplate; + } + + @Configuration(proxyBeanMethods = false) + static class CustomConventionConfiguration { + + @Bean + CustomConvention customConvention() { + return new CustomConvention(); + } + + } + + static class CustomConvention extends DefaultClientRequestObservationConvention { + + @Override + public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) { + return super.getLowCardinalityKeyValues(context).and("project", "spring-boot"); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MetricsConfiguration { + + @Bean + MeterObservationHandler meterObservationHandler(MeterRegistry registry) { + return new DefaultMeterObservationHandler(registry); + } + + } + +} diff --git a/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestTemplateObservationAutoConfigurationWithoutMetricsTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestTemplateObservationAutoConfigurationWithoutMetricsTests.java new file mode 100644 index 000000000000..9bf6f3f0a383 --- /dev/null +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/observation/RestTemplateObservationAutoConfigurationWithoutMetricsTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.restclient.autoconfigure.observation; + +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.tck.TestObservationRegistry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.autoconfigure.RestTemplateAutoConfiguration; +import org.springframework.boot.restclient.autoconfigure.RestTemplateObservationAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.testsupport.classpath.ClassPathExclusions; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; + +/** + * Tests for {@link RestTemplateObservationAutoConfiguration} without Micrometer Metrics. + * + * @author Brian Clozel + * @author Andy Wilkinson + */ +@ExtendWith(OutputCaptureExtension.class) +@ClassPathExclusions("micrometer-core-*.jar") +class RestTemplateObservationAutoConfigurationWithoutMetricsTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(ObservationRegistry.class, TestObservationRegistry::create) + .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, + RestTemplateAutoConfiguration.class, RestTemplateObservationAutoConfiguration.class)); + + @Test + void restTemplateCreatedWithBuilderIsInstrumented() { + this.contextRunner.run((context) -> { + RestTemplate restTemplate = buildRestTemplate(context); + restTemplate.getForEntity("/projects/{project}", Void.class, "spring-boot"); + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + assertThat(registry).hasObservationWithNameEqualToIgnoringCase("http.client.requests"); + }); + } + + private RestTemplate buildRestTemplate(AssertableApplicationContext context) { + RestTemplate restTemplate = context.getBean(RestTemplateBuilder.class).build(); + MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate); + server.expect(requestTo("/projects/spring-boot")).andRespond(withStatus(HttpStatus.OK)); + return restTemplate; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/service/HttpClientServicePropertiesTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpClientServicePropertiesTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/service/HttpClientServicePropertiesTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpClientServicePropertiesTests.java index 7c713ea32232..ed72dd44a80f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/service/HttpClientServicePropertiesTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpClientServicePropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.service; +package org.springframework.boot.restclient.autoconfigure.service; import java.time.Duration; import java.util.List; @@ -22,10 +22,10 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.http.client.AbstractHttpRequestFactoryProperties.Factory; -import org.springframework.boot.autoconfigure.http.client.service.HttpClientServiceProperties.Group; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.autoconfigure.AbstractHttpRequestFactoryProperties.Factory; +import org.springframework.boot.restclient.autoconfigure.service.HttpClientServiceProperties.Group; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.mock.env.MockEnvironment; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/service/HttpServiceClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/service/HttpServiceClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java index 87b6b0fe7005..92a1fc47a673 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/service/HttpServiceClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.service; +package org.springframework.boot.restclient.autoconfigure.service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; @@ -28,13 +28,13 @@ import org.springframework.aop.Advisor; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration; -import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.autoconfigure.HttpClientAutoConfiguration; +import org.springframework.boot.restclient.RestClientCustomizer; +import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.web.client.RestClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.web.client.MockRestServiceServer; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestClientCustomizerTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/observation/ObservationRestClientCustomizerTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestClientCustomizerTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/observation/ObservationRestClientCustomizerTests.java index 650a13cdd7df..e282b2b80424 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestClientCustomizerTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/observation/ObservationRestClientCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.client; +package org.springframework.boot.restclient.observation; import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.tck.TestObservationRegistry; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestTemplateCustomizerTests.java b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/observation/ObservationRestTemplateCustomizerTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestTemplateCustomizerTests.java rename to spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/observation/ObservationRestTemplateCustomizerTests.java index ed533cbd6546..6cfe5bc834c3 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/ObservationRestTemplateCustomizerTests.java +++ b/spring-boot-project/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/observation/ObservationRestTemplateCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.client; +package org.springframework.boot.restclient.observation; import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.tck.TestObservationRegistry; diff --git a/spring-boot-project/spring-boot-rsocket/build.gradle b/spring-boot-project/spring-boot-rsocket/build.gradle new file mode 100644 index 000000000000..f40ebb1ba90a --- /dev/null +++ b/spring-boot-project/spring-boot-rsocket/build.gradle @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot RSocket" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("io.rsocket:rsocket-core") + api("org.springframework:spring-messaging") + + implementation("org.springframework:spring-web") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-jackson")) + optional(project(":spring-boot-project:spring-boot-reactor-netty")) + optional("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor") + optional("io.rsocket:rsocket-transport-netty") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("io.projectreactor:reactor-test") + testImplementation("org.springframework:spring-webflux") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessageHandlerCustomizer.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessageHandlerCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessageHandlerCustomizer.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessageHandlerCustomizer.java index 440db97b1bfa..b8aadb3fd258 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessageHandlerCustomizer.java +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessageHandlerCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler; @@ -23,7 +23,7 @@ * * @author Aarti Gupta * @author Madhura Bhave - * @since 2.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface RSocketMessageHandlerCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessagingAutoConfiguration.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessagingAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessagingAutoConfiguration.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessagingAutoConfiguration.java index 34cc1586a757..b798b65afa91 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessagingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessagingAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import io.rsocket.transport.netty.server.TcpServerTransport; @@ -33,7 +33,7 @@ * Messaging. * * @author Brian Clozel - * @since 2.2.0 + * @since 4.0.0 */ @AutoConfiguration(after = RSocketStrategiesAutoConfiguration.class) @ConditionalOnClass({ RSocketRequester.class, io.rsocket.RSocket.class, TcpServerTransport.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketProperties.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketProperties.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketProperties.java index f38707843b31..14afad7af28d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketProperties.java +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import java.net.InetAddress; @@ -29,7 +29,7 @@ * * @author Brian Clozel * @author Chris Bono - * @since 2.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.rsocket") public class RSocketProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketRequesterAutoConfiguration.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketRequesterAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketRequesterAutoConfiguration.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketRequesterAutoConfiguration.java index e9c6b24acddc..bbb3a441f6e4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketRequesterAutoConfiguration.java +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketRequesterAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import io.rsocket.transport.netty.server.TcpServerTransport; import reactor.netty.http.server.HttpServer; @@ -40,7 +40,7 @@ * requester instances with different configurations. * * @author Brian Clozel - * @since 2.2.0 + * @since 4.0.0 */ @AutoConfiguration(after = RSocketStrategiesAutoConfiguration.class) @ConditionalOnClass({ RSocketRequester.class, io.rsocket.RSocket.class, HttpServer.class, TcpServerTransport.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfiguration.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketServerAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfiguration.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketServerAutoConfiguration.java index 18ec1381a909..1b17c17adfcf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketServerAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import java.util.function.Consumer; @@ -33,10 +33,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigurations; -import org.springframework.boot.autoconfigure.rsocket.RSocketProperties.Server.Spec; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.reactor.netty.autoconfigure.ReactorNettyConfigurations; +import org.springframework.boot.rsocket.autoconfigure.RSocketProperties.Server.Spec; import org.springframework.boot.rsocket.context.RSocketServerBootstrap; import org.springframework.boot.rsocket.netty.NettyRSocketServerFactory; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; @@ -56,12 +56,12 @@ * {@link EnableAutoConfiguration Auto-configuration} for RSocket servers. In the case of * {@link org.springframework.boot.WebApplicationType#REACTIVE}, the RSocket server is * added as a WebSocket endpoint on the existing - * {@link org.springframework.boot.web.embedded.netty.NettyWebServer}. If a specific - * server port is configured, a new standalone RSocket server is created. + * {@link org.springframework.boot.reactor.netty.NettyWebServer}. If a specific server + * port is configured, a new standalone RSocket server is created. * * @author Brian Clozel * @author Scott Frederick - * @since 2.2.0 + * @since 4.0.0 */ @AutoConfiguration(after = RSocketStrategiesAutoConfiguration.class) @ConditionalOnClass({ RSocketServer.class, RSocketStrategies.class, HttpServer.class, TcpServerTransport.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketStrategiesAutoConfiguration.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketStrategiesAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketStrategiesAutoConfiguration.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketStrategiesAutoConfiguration.java index ba32dd8788f5..731c515f6767 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketStrategiesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketStrategiesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.cbor.CBORFactory; @@ -26,7 +26,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.rsocket.messaging.RSocketStrategiesCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -40,9 +39,9 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link RSocketStrategies}. * * @author Brian Clozel - * @since 2.2.0 + * @since 4.0.0 */ -@AutoConfiguration(after = JacksonAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration") @ConditionalOnClass({ io.rsocket.RSocket.class, RSocketStrategies.class, PooledByteBufAllocator.class }) public class RSocketStrategiesAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProvider.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketWebSocketNettyRouteProvider.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProvider.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketWebSocketNettyRouteProvider.java index 2c3aaf2b909a..3732437f4693 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProvider.java +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/RSocketWebSocketNettyRouteProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import java.util.List; import java.util.function.Consumer; @@ -28,8 +28,8 @@ import reactor.netty.http.server.WebsocketServerSpec; import reactor.netty.http.server.WebsocketServerSpec.Builder; +import org.springframework.boot.reactor.netty.NettyRouteProvider; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; -import org.springframework.boot.web.embedded.netty.NettyRouteProvider; /** * {@link NettyRouteProvider} that configures an RSocket Websocket endpoint. diff --git a/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/package-info.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/package-info.java new file mode 100644 index 000000000000..0a88c05f02ed --- /dev/null +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for RSocket. + */ +package org.springframework.boot.rsocket.autoconfigure; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializer.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializer.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/RSocketServerBootstrap.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/context/RSocketServerBootstrap.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/RSocketServerBootstrap.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/context/RSocketServerBootstrap.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/RSocketServerInitializedEvent.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/context/RSocketServerInitializedEvent.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/RSocketServerInitializedEvent.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/context/RSocketServerInitializedEvent.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/package-info.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/context/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/package-info.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/context/package-info.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/messaging/RSocketStrategiesCustomizer.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/messaging/RSocketStrategiesCustomizer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/messaging/RSocketStrategiesCustomizer.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/messaging/RSocketStrategiesCustomizer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/messaging/package-info.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/messaging/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/messaging/package-info.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/messaging/package-info.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServer.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServer.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServer.java diff --git a/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java new file mode 100644 index 000000000000..02fb798570d2 --- /dev/null +++ b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java @@ -0,0 +1,307 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.rsocket.netty; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import io.netty.handler.ssl.ClientAuth; +import io.rsocket.SocketAcceptor; +import io.rsocket.transport.ServerTransport; +import io.rsocket.transport.netty.server.CloseableChannel; +import io.rsocket.transport.netty.server.TcpServerTransport; +import io.rsocket.transport.netty.server.WebsocketServerTransport; +import reactor.core.publisher.Mono; +import reactor.netty.http.Http11SslContextSpec; +import reactor.netty.http.server.HttpServer; +import reactor.netty.tcp.AbstractProtocolSslContextSpec; +import reactor.netty.tcp.SslProvider; +import reactor.netty.tcp.SslProvider.GenericSslContextSpec; +import reactor.netty.tcp.SslProvider.SslContextSpec; +import reactor.netty.tcp.TcpServer; + +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.rsocket.server.ConfigurableRSocketServerFactory; +import org.springframework.boot.rsocket.server.RSocketServer; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; +import org.springframework.boot.rsocket.server.RSocketServerFactory; +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.boot.ssl.SslOptions; +import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.Ssl.ServerNameSslBundle; +import org.springframework.boot.web.server.WebServerSslBundle; +import org.springframework.http.client.ReactorResourceFactory; +import org.springframework.util.Assert; +import org.springframework.util.unit.DataSize; + +/** + * {@link RSocketServerFactory} that can be used to create {@link RSocketServer}s backed + * by Netty. + * + * @author Brian Clozel + * @author Chris Bono + * @author Scott Frederick + * @since 2.2.0 + */ +public class NettyRSocketServerFactory implements RSocketServerFactory, ConfigurableRSocketServerFactory { + + private int port = 9898; + + private DataSize fragmentSize; + + private InetAddress address; + + private RSocketServer.Transport transport = RSocketServer.Transport.TCP; + + private ReactorResourceFactory resourceFactory; + + private Duration lifecycleTimeout; + + private List rSocketServerCustomizers = new ArrayList<>(); + + private Ssl ssl; + + private SslBundles sslBundles; + + @Override + public void setPort(int port) { + this.port = port; + } + + @Override + public void setFragmentSize(DataSize fragmentSize) { + this.fragmentSize = fragmentSize; + } + + @Override + public void setAddress(InetAddress address) { + this.address = address; + } + + @Override + public void setTransport(RSocketServer.Transport transport) { + this.transport = transport; + } + + @Override + public void setSsl(Ssl ssl) { + this.ssl = ssl; + } + + @Override + public void setSslBundles(SslBundles sslBundles) { + this.sslBundles = sslBundles; + } + + /** + * Set the {@link ReactorResourceFactory} to get the shared resources from. + * @param resourceFactory the server resources + */ + public void setResourceFactory(ReactorResourceFactory resourceFactory) { + this.resourceFactory = resourceFactory; + } + + /** + * Set {@link RSocketServerCustomizer}s that should be called to configure the + * {@link io.rsocket.core.RSocketServer} while building the server. Calling this + * method will replace any existing customizers. + * @param rSocketServerCustomizers customizers to apply before the server starts + * @since 2.2.7 + */ + public void setRSocketServerCustomizers(Collection rSocketServerCustomizers) { + Assert.notNull(rSocketServerCustomizers, "'rSocketServerCustomizers' must not be null"); + this.rSocketServerCustomizers = new ArrayList<>(rSocketServerCustomizers); + } + + /** + * Add {@link RSocketServerCustomizer}s that should be called to configure the + * {@link io.rsocket.core.RSocketServer}. + * @param rSocketServerCustomizers customizers to apply before the server starts + * @since 2.2.7 + */ + public void addRSocketServerCustomizers(RSocketServerCustomizer... rSocketServerCustomizers) { + Assert.notNull(rSocketServerCustomizers, "'rSocketServerCustomizers' must not be null"); + this.rSocketServerCustomizers.addAll(Arrays.asList(rSocketServerCustomizers)); + } + + /** + * Set the maximum amount of time that should be waited when starting or stopping the + * server. + * @param lifecycleTimeout the lifecycle timeout + */ + public void setLifecycleTimeout(Duration lifecycleTimeout) { + this.lifecycleTimeout = lifecycleTimeout; + } + + @Override + public NettyRSocketServer create(SocketAcceptor socketAcceptor) { + ServerTransport transport = createTransport(); + io.rsocket.core.RSocketServer server = io.rsocket.core.RSocketServer.create(socketAcceptor); + configureServer(server); + Mono starter = server.bind(transport); + return new NettyRSocketServer(starter, this.lifecycleTimeout); + } + + private void configureServer(io.rsocket.core.RSocketServer server) { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(this.fragmentSize).asInt(DataSize::toBytes).to(server::fragment); + this.rSocketServerCustomizers.forEach((customizer) -> customizer.customize(server)); + } + + private ServerTransport createTransport() { + if (this.transport == RSocketServer.Transport.WEBSOCKET) { + return createWebSocketTransport(); + } + return createTcpTransport(); + } + + private ServerTransport createWebSocketTransport() { + HttpServer httpServer = HttpServer.create(); + if (this.resourceFactory != null) { + httpServer = httpServer.runOn(this.resourceFactory.getLoopResources()); + } + if (Ssl.isEnabled(this.ssl)) { + httpServer = customizeSslConfiguration(httpServer); + } + return WebsocketServerTransport.create(httpServer.bindAddress(this::getListenAddress)); + } + + private HttpServer customizeSslConfiguration(HttpServer httpServer) { + return new HttpServerSslCustomizer(this.ssl.getClientAuth(), getSslBundle(), getServerNameSslBundles()) + .apply(httpServer); + } + + private ServerTransport createTcpTransport() { + TcpServer tcpServer = TcpServer.create(); + if (this.resourceFactory != null) { + tcpServer = tcpServer.runOn(this.resourceFactory.getLoopResources()); + } + if (Ssl.isEnabled(this.ssl)) { + tcpServer = new TcpServerSslCustomizer(this.ssl.getClientAuth(), getSslBundle(), getServerNameSslBundles()) + .apply(tcpServer); + } + return TcpServerTransport.create(tcpServer.bindAddress(this::getListenAddress)); + } + + private SslBundle getSslBundle() { + return WebServerSslBundle.get(this.ssl, this.sslBundles); + } + + protected final Map getServerNameSslBundles() { + return this.ssl.getServerNameBundles() + .stream() + .collect(Collectors.toMap(Ssl.ServerNameSslBundle::serverName, this::getBundle)); + } + + private SslBundle getBundle(ServerNameSslBundle serverNameSslBundle) { + return this.sslBundles.getBundle(serverNameSslBundle.bundle()); + } + + private InetSocketAddress getListenAddress() { + if (this.address != null) { + return new InetSocketAddress(this.address.getHostAddress(), this.port); + } + return new InetSocketAddress(this.port); + } + + private abstract static class SslCustomizer { + + private final ClientAuth clientAuth; + + protected SslCustomizer(ClientAuth clientAuth) { + this.clientAuth = clientAuth; + } + + protected final AbstractProtocolSslContextSpec createSslContextSpec(SslBundle sslBundle) { + AbstractProtocolSslContextSpec sslContextSpec = Http11SslContextSpec + .forServer(sslBundle.getManagers().getKeyManagerFactory()); + return sslContextSpec.configure((builder) -> { + builder.trustManager(sslBundle.getManagers().getTrustManagerFactory()); + SslOptions options = sslBundle.getOptions(); + builder.protocols(options.getEnabledProtocols()); + builder.ciphers(SslOptions.asSet(options.getCiphers())); + builder.clientAuth(this.clientAuth); + }); + } + + } + + private static final class TcpServerSslCustomizer extends SslCustomizer { + + private final SslBundle sslBundle; + + private TcpServerSslCustomizer(Ssl.ClientAuth clientAuth, SslBundle sslBundle, + Map serverNameSslBundles) { + super(Ssl.ClientAuth.map(clientAuth, ClientAuth.NONE, ClientAuth.OPTIONAL, ClientAuth.REQUIRE)); + this.sslBundle = sslBundle; + } + + private TcpServer apply(TcpServer server) { + GenericSslContextSpec sslContextSpec = createSslContextSpec(this.sslBundle); + return server.secure((spec) -> spec.sslContext(sslContextSpec)); + } + + } + + private static final class HttpServerSslCustomizer extends SslCustomizer { + + private final SslProvider sslProvider; + + private final Map serverNameSslProviders; + + private HttpServerSslCustomizer(Ssl.ClientAuth clientAuth, SslBundle sslBundle, + Map serverNameSslBundles) { + super(Ssl.ClientAuth.map(clientAuth, ClientAuth.NONE, ClientAuth.OPTIONAL, ClientAuth.REQUIRE)); + this.sslProvider = createSslProvider(sslBundle); + this.serverNameSslProviders = createServerNameSslProviders(serverNameSslBundles); + } + + private HttpServer apply(HttpServer server) { + return server.secure(this::applySecurity); + } + + private void applySecurity(SslContextSpec spec) { + spec.sslContext(this.sslProvider.getSslContext()).setSniAsyncMappings((serverName, promise) -> { + SslProvider provider = (serverName != null) ? this.serverNameSslProviders.get(serverName) + : this.sslProvider; + return promise.setSuccess(provider); + }); + } + + private Map createServerNameSslProviders(Map serverNameSslBundles) { + Map serverNameSslProviders = new HashMap<>(); + serverNameSslBundles.forEach( + (serverName, sslBundle) -> serverNameSslProviders.put(serverName, createSslProvider(sslBundle))); + return serverNameSslProviders; + } + + private SslProvider createSslProvider(SslBundle sslBundle) { + return SslProvider.builder().sslContext((GenericSslContextSpec) createSslContextSpec(sslBundle)).build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/package-info.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/netty/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/package-info.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/netty/package-info.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/ConfigurableRSocketServerFactory.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/ConfigurableRSocketServerFactory.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/ConfigurableRSocketServerFactory.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/ConfigurableRSocketServerFactory.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServer.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/RSocketServer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServer.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/RSocketServer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerCustomizer.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/RSocketServerCustomizer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerCustomizer.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/RSocketServerCustomizer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerException.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/RSocketServerException.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerException.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/RSocketServerException.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerFactory.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/RSocketServerFactory.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/RSocketServerFactory.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/RSocketServerFactory.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/package-info.java b/spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/server/package-info.java rename to spring-boot-project/spring-boot-rsocket/src/main/java/org/springframework/boot/rsocket/server/package-info.java diff --git a/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..649131484873 --- /dev/null +++ b/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "properties": [ + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..9776e16d1856 --- /dev/null +++ b/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Application Context Initializers +org.springframework.context.ApplicationContextInitializer=\ +org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer diff --git a/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..10cbb3760300 --- /dev/null +++ b/spring-boot-project/spring-boot-rsocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.rsocket.autoconfigure.RSocketMessagingAutoConfiguration +org.springframework.boot.rsocket.autoconfigure.RSocketRequesterAutoConfiguration +org.springframework.boot.rsocket.autoconfigure.RSocketServerAutoConfiguration +org.springframework.boot.rsocket.autoconfigure.RSocketStrategiesAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessagingAutoConfigurationTests.java b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessagingAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessagingAutoConfigurationTests.java rename to spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessagingAutoConfigurationTests.java index 35a311542f42..5a04bc07c7f6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketMessagingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketMessagingAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketPropertiesTests.java b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketPropertiesTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketPropertiesTests.java rename to spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketPropertiesTests.java index 414253f70b3f..5444fc1d8097 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketPropertiesTests.java +++ b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketPropertiesTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import org.junit.jupiter.api.Test; import reactor.netty.http.server.WebsocketServerSpec; -import org.springframework.boot.autoconfigure.rsocket.RSocketProperties.Server.Spec; +import org.springframework.boot.rsocket.autoconfigure.RSocketProperties.Server.Spec; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketRequesterAutoConfigurationTests.java b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketRequesterAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketRequesterAutoConfigurationTests.java rename to spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketRequesterAutoConfigurationTests.java index 1b30df0849b3..cb73313452a7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketRequesterAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketRequesterAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketServerAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketServerAutoConfigurationTests.java index 8af00918d227..246ac319e238 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketServerAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketStrategiesAutoConfigurationTests.java b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketStrategiesAutoConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketStrategiesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketStrategiesAutoConfigurationTests.java index 778bc10f6ac4..8fce7072dd0d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketStrategiesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketStrategiesAutoConfigurationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.rsocket.messaging.RSocketStrategiesCustomizer; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -41,8 +41,11 @@ */ class RSocketStrategiesAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(JacksonAutoConfiguration.class, RSocketStrategiesAutoConfiguration.class)); + @SuppressWarnings("removal") + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(RSocketStrategiesAutoConfiguration.class)) + .withBean(org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.class) + .withBean(ObjectMapper.class); @Test @SuppressWarnings("removal") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProviderTests.java b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketWebSocketNettyRouteProviderTests.java similarity index 76% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProviderTests.java rename to spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketWebSocketNettyRouteProviderTests.java index 1b9683a38908..ece69aaac03f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/rsocket/RSocketWebSocketNettyRouteProviderTests.java +++ b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/autoconfigure/RSocketWebSocketNettyRouteProviderTests.java @@ -14,35 +14,36 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.rsocket; +package org.springframework.boot.rsocket.autoconfigure; import java.net.URI; import java.time.Duration; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; +import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener; +import org.springframework.boot.logging.LogLevel; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.reactive.context.ReactiveWebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.HttpHandler; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.rsocket.RSocketRequester; import org.springframework.stereotype.Controller; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import static org.assertj.core.api.Assertions.assertThat; @@ -56,14 +57,13 @@ class RSocketWebSocketNettyRouteProviderTests { @Test void webEndpointsShouldWork() { new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class, - ErrorWebFluxAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - JacksonAutoConfiguration.class, CodecsAutoConfiguration.class, + .withConfiguration(AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class, RSocketStrategiesAutoConfiguration.class, RSocketServerAutoConfiguration.class, RSocketMessagingAutoConfiguration.class, RSocketRequesterAutoConfiguration.class)) .withUserConfiguration(WebConfiguration.class) .withPropertyValues("spring.rsocket.server.transport=websocket", "spring.rsocket.server.mapping-path=/rsocket") + .withInitializer(ConditionEvaluationReportLoggingListener.forLogLevel(LogLevel.INFO)) .run((context) -> { ReactiveWebServerApplicationContext serverContext = (ReactiveWebServerApplicationContext) context .getSourceApplicationContext(); @@ -99,9 +99,15 @@ private RSocketRequester createRSocketRequester(ApplicationContext context, WebS .websocket(URI.create("ws://localhost:" + port + "/rsocket")); } + @EnableWebFlux @Configuration(proxyBeanMethods = false) static class WebConfiguration { + @Bean + HttpHandler httpHandler(ApplicationContext context) { + return WebHttpHandlerBuilder.applicationContext(context).build(); + } + @Bean WebController webController() { return new WebController(); @@ -114,6 +120,17 @@ NettyReactiveWebServerFactory customServerFactory(RSocketWebSocketNettyRouteProv return serverFactory; } + @Bean + ObjectMapper objectMapper() { + return new ObjectMapper(); + } + + @Bean + @SuppressWarnings({ "removal", "deprecation" }) + org.springframework.http.converter.json.Jackson2ObjectMapperBuilder objectMapperBuilder() { + return new org.springframework.http.converter.json.Jackson2ObjectMapperBuilder(); + } + } @Controller diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializerTests.java b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializerTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializerTests.java rename to spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/context/RSocketPortInfoApplicationContextInitializerTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java b/spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java rename to spring-boot-project/spring-boot-rsocket/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/rsocket/test.jks b/spring-boot-project/spring-boot-rsocket/src/test/resources/org/springframework/boot/rsocket/autoconfigure/test.jks similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/rsocket/test.jks rename to spring-boot-project/spring-boot-rsocket/src/test/resources/org/springframework/boot/rsocket/autoconfigure/test.jks diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/rsocket/netty/test-cert.pem b/spring-boot-project/spring-boot-rsocket/src/test/resources/org/springframework/boot/rsocket/netty/test-cert.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/rsocket/netty/test-cert.pem rename to spring-boot-project/spring-boot-rsocket/src/test/resources/org/springframework/boot/rsocket/netty/test-cert.pem diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/rsocket/netty/test-key.pem b/spring-boot-project/spring-boot-rsocket/src/test/resources/org/springframework/boot/rsocket/netty/test-key.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/rsocket/netty/test-key.pem rename to spring-boot-project/spring-boot-rsocket/src/test/resources/org/springframework/boot/rsocket/netty/test-key.pem diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/test.jks b/spring-boot-project/spring-boot-rsocket/src/test/resources/org/springframework/boot/rsocket/netty/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/netty/test.jks rename to spring-boot-project/spring-boot-rsocket/src/test/resources/org/springframework/boot/rsocket/netty/test.jks diff --git a/spring-boot-project/spring-boot-security-oauth2-authorization-server/build.gradle b/spring-boot-project/spring-boot-security-oauth2-authorization-server/build.gradle new file mode 100644 index 000000000000..f1442ecd0b48 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/build.gradle @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Security OAuth2 Authorization Server" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.security:spring-security-oauth2-authorization-server") + + implementation(project(":spring-boot-project:spring-boot-security")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-security-oauth2-resource-server")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("jakarta.servlet:jakarta.servlet-api") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerAutoConfiguration.java similarity index 80% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerAutoConfiguration.java index 83749c0f58ba..691325122432 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerAutoConfiguration.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration; import org.springframework.context.annotation.Import; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; @@ -39,11 +38,11 @@ * if necessary. * * @author Steve Riesenberg - * @since 3.1.0 + * @since 4.0.0 * @see OAuth2AuthorizationServerJwtAutoConfiguration */ -@AutoConfiguration(before = { OAuth2ResourceServerAutoConfiguration.class, SecurityAutoConfiguration.class, - UserDetailsServiceAutoConfiguration.class }) +@AutoConfiguration(before = SecurityAutoConfiguration.class, + beforeName = "org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet.OAuth2ResourceServerAutoConfiguration") @ConditionalOnClass(OAuth2Authorization.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @Import({ OAuth2AuthorizationServerConfiguration.class, OAuth2AuthorizationServerWebSecurityConfiguration.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerConfiguration.java index 00af062de2f0..516053713166 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java index 765cb3017c39..968b0d88c520 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -34,7 +34,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Role; @@ -47,7 +47,7 @@ * OAuth2 authorization server that require it (e.g. User Info, Client Registration). * * @author Steve Riesenberg - * @since 3.1.0 + * @since 4.0.0 */ @AutoConfiguration(after = UserDetailsServiceAutoConfiguration.class) @ConditionalOnClass({ OAuth2Authorization.class, JWKSource.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerProperties.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerProperties.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerProperties.java index 193f113d939c..c466716341f5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerProperties.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import java.time.Duration; import java.util.HashMap; @@ -32,7 +32,7 @@ * OAuth 2.0 Authorization Server properties. * * @author Steve Riesenberg - * @since 3.1.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.security.oauth2.authorizationserver") public class OAuth2AuthorizationServerProperties implements InitializingBean { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapper.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesMapper.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapper.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesMapper.java index 0130684b59c4..6e6eecb257b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapper.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesMapper.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import org.springframework.boot.autoconfigure.security.oauth2.server.servlet.OAuth2AuthorizationServerProperties.Client; -import org.springframework.boot.autoconfigure.security.oauth2.server.servlet.OAuth2AuthorizationServerProperties.Registration; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet.OAuth2AuthorizationServerProperties.Client; +import org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet.OAuth2AuthorizationServerProperties.Registration; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.jose.jws.JwsAlgorithm; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java index 232231d6eaa8..f984573b36f0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerWebSecurityConfiguration.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import java.util.Set; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; -import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.security.autoconfigure.ConditionalOnDefaultWebSecurity; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/RegisteredClientsConfiguredCondition.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/RegisteredClientsConfiguredCondition.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/RegisteredClientsConfiguredCondition.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/RegisteredClientsConfiguredCondition.java index 1299f9018de9..2e21d514a2ca 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/RegisteredClientsConfiguredCondition.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/RegisteredClientsConfiguredCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..249f5a886081 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Security's OAuth2 authorization server. + */ +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..72f3dc8dc0bc --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet.OAuth2AuthorizationServerAutoConfiguration +org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet.OAuth2AuthorizationServerJwtAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java index a36ddfbb95ef..4dfbe7749e90 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerAutoConfigurationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java index d1717e26516f..d871ba119266 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import com.nimbusds.jose.jwk.source.ImmutableJWKSet; import com.nimbusds.jose.jwk.source.JWKSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java index 100627def60b..5a0e56a6af8c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import java.time.Duration; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesTests.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesTests.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesTests.java index ace2e45f2756..01028308df89 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java index 862545c5a355..e18a97cbc609 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-authorization-server/src/test/java/org/springframework/boot/security/oauth2/server/authorization/autoconfigure/servlet/OAuth2AuthorizationServerWebSecurityConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.server.servlet; +package org.springframework.boot.security.oauth2.server.authorization.autoconfigure.servlet; import java.util.List; diff --git a/spring-boot-project/spring-boot-security-oauth2-client/build.gradle b/spring-boot-project/spring-boot-security-oauth2-client/build.gradle new file mode 100644 index 000000000000..0d82d30cad91 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-client/build.gradle @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Security OAuth2 Client" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.security:spring-security-oauth2-client") + + implementation(project(":spring-boot-project:spring-boot-security")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-reactor")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-webmvc")) + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("com.squareup.okhttp3:mockwebserver") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("org.springframework:spring-webflux") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ClientsConfiguredCondition.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/ClientsConfiguredCondition.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ClientsConfiguredCondition.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/ClientsConfiguredCondition.java index 354b8b111a57..6b1fad00ddb4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ClientsConfiguredCondition.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/ClientsConfiguredCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client; +package org.springframework.boot.security.oauth2.client.autoconfigure; import java.util.Collections; import java.util.Map; @@ -34,12 +34,8 @@ * properties are defined. * * @author Madhura Bhave - * @since 2.1.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link ConditionalOnOAuth2ClientRegistrationProperties @ConditionalOnOAuth2ClientRegistrationProperties} */ -@Deprecated(since = "3.5.0", forRemoval = true) -public class ClientsConfiguredCondition extends SpringBootCondition { +class ClientsConfiguredCondition extends SpringBootCondition { private static final Bindable> STRING_REGISTRATION_MAP = Bindable .mapOf(String.class, OAuth2ClientProperties.Registration.class); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ConditionalOnOAuth2ClientRegistrationProperties.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/ConditionalOnOAuth2ClientRegistrationProperties.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ConditionalOnOAuth2ClientRegistrationProperties.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/ConditionalOnOAuth2ClientRegistrationProperties.java index 45b62fa7e533..cf63ecc405a8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ConditionalOnOAuth2ClientRegistrationProperties.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/ConditionalOnOAuth2ClientRegistrationProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client; +package org.springframework.boot.security.oauth2.client.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -29,7 +29,7 @@ * properties are defined. * * @author Andy Wilkinson - * @since 3.5.0 + * @since 4.0.0 */ @SuppressWarnings("removal") @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientAutoConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientAutoConfiguration.java new file mode 100644 index 000000000000..33807405e1de --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientAutoConfiguration.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.oauth2.client.autoconfigure; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientAutoConfiguration.NonReactiveWebApplicationCondition; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Import; +import org.springframework.security.oauth2.client.registration.ClientRegistration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for OAuth client support. + * + * @author Madhura Bhave + * @author Phillip Webb + * @since 4.0.0 + */ +@AutoConfiguration +@Conditional(NonReactiveWebApplicationCondition.class) +@ConditionalOnClass(ClientRegistration.class) +@Import({ OAuth2ClientConfigurations.ClientRegistrationRepositoryConfiguration.class, + OAuth2ClientConfigurations.OAuth2AuthorizedClientServiceConfiguration.class }) +public class OAuth2ClientAutoConfiguration { + + static class NonReactiveWebApplicationCondition extends NoneNestedConditions { + + NonReactiveWebApplicationCondition() { + super(ConfigurationPhase.PARSE_CONFIGURATION); + } + + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + static class ReactiveWebApplicationCondition { + + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientConfigurations.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientConfigurations.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientConfigurations.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientConfigurations.java index 5f57c834c1d1..fc8572d30353 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientConfigurations.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client; +package org.springframework.boot.security.oauth2.client.autoconfigure; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientProperties.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientProperties.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientProperties.java index 1c5d9d30fff4..86d0918d9214 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientProperties.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client; +package org.springframework.boot.security.oauth2.client.autoconfigure; import java.util.HashMap; import java.util.Map; @@ -32,7 +32,7 @@ * @author Artsiom Yudovin * @author MyeongHyeon Lee * @author Moritz Halbritter - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.security.oauth2.client") public class OAuth2ClientProperties implements InitializingBean { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesMapper.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesMapper.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesMapper.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesMapper.java index 505b7f485b8c..b56b894217b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesMapper.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesMapper.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client; +package org.springframework.boot.security.oauth2.client.autoconfigure; import java.util.HashMap; import java.util.Map; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.Provider; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.convert.ApplicationConversionService; +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientProperties.Provider; import org.springframework.core.convert.ConversionException; import org.springframework.security.config.oauth2.client.CommonOAuth2Provider; import org.springframework.security.oauth2.client.registration.ClientRegistration; @@ -40,7 +40,7 @@ * @author Madhura Bhave * @author MyeongHyeon Lee * @author Andy Wilkinson - * @since 3.1.0 + * @since 4.0.0 */ public final class OAuth2ClientPropertiesMapper { diff --git a/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/package-info.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/package-info.java new file mode 100644 index 000000000000..38da11d9c667 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Spring Security's OAuth 2 client. + */ +package org.springframework.boot.security.oauth2.client.autoconfigure; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientAutoConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientAutoConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientAutoConfiguration.java index 8004b8962afd..a946841cacae 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client.reactive; +package org.springframework.boot.security.oauth2.client.autoconfigure.reactive; import reactor.core.publisher.Flux; @@ -32,7 +32,7 @@ * OAuth2 client. * * @author Madhura Bhave - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration @Conditional(ReactiveOAuth2ClientAutoConfiguration.NonServletApplicationCondition.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientConfigurations.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientConfigurations.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientConfigurations.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientConfigurations.java index 380fb504ea30..6a95d94efca8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientConfigurations.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientConfigurations.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client.reactive; +package org.springframework.boot.security.oauth2.client.autoconfigure.reactive; import java.util.ArrayList; import java.util.List; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.security.oauth2.client.ConditionalOnOAuth2ClientRegistrationProperties; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.oauth2.client.autoconfigure.ConditionalOnOAuth2ClientRegistrationProperties; +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientProperties; +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientPropertiesMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientWebSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientWebSecurityAutoConfiguration.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientWebSecurityAutoConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientWebSecurityAutoConfiguration.java index e2e3d5b4acc1..46a0454ff930 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientWebSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientWebSecurityAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client.reactive; +package org.springframework.boot.security.oauth2.client.autoconfigure.reactive; import reactor.core.publisher.Flux; @@ -23,7 +23,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.actuate.reactive.ReactiveManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; @@ -40,9 +41,10 @@ * @author Madhura Bhave * @author Phillip Webb * @author Andy Wilkinson - * @since 3.5.0 + * @since 4.0.0 */ -@AutoConfiguration(before = ReactiveSecurityAutoConfiguration.class, +@AutoConfiguration( + before = { ReactiveManagementWebSecurityAutoConfiguration.class, ReactiveSecurityAutoConfiguration.class }, after = ReactiveOAuth2ClientAutoConfiguration.class) @ConditionalOnClass({ Flux.class, EnableWebFluxSecurity.class, ServerOAuth2AuthorizedClientRepository.class }) @ConditionalOnBean(ReactiveOAuth2AuthorizedClientService.class) diff --git a/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..02461bd6d33e --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Security's Reactive OAuth 2 client. + */ +package org.springframework.boot.security.oauth2.client.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientWebSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/OAuth2ClientWebSecurityAutoConfiguration.java similarity index 82% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientWebSecurityAutoConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/OAuth2ClientWebSecurityAutoConfiguration.java index f78a11f0883e..20fe3c82ff5c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientWebSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/OAuth2ClientWebSecurityAutoConfiguration.java @@ -14,16 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client.servlet; +package org.springframework.boot.security.oauth2.client.autoconfigure.servlet; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.ConditionalOnDefaultWebSecurity; +import org.springframework.boot.security.autoconfigure.actuate.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -41,9 +42,10 @@ * @author Madhura Bhave * @author Phillip Webb * @author Andy Wilkinson - * @since 3.5.0 + * @since 4.0.0 */ -@AutoConfiguration(before = SecurityAutoConfiguration.class, after = OAuth2ClientAutoConfiguration.class) +@AutoConfiguration(before = { ManagementWebSecurityAutoConfiguration.class, SecurityAutoConfiguration.class }, + after = OAuth2ClientAutoConfiguration.class) @ConditionalOnClass({ EnableWebSecurity.class, OAuth2AuthorizedClientRepository.class }) @ConditionalOnBean(OAuth2AuthorizedClientService.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) diff --git a/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..0d5f37d340e8 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Security's OAuth 2 client. + */ +package org.springframework.boot.security.oauth2.client.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot-security-oauth2-client/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-security-oauth2-client/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-security-oauth2-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-security-oauth2-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..f841e95bd9ef --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientAutoConfiguration +org.springframework.boot.security.oauth2.client.autoconfigure.reactive.ReactiveOAuth2ClientAutoConfiguration +org.springframework.boot.security.oauth2.client.autoconfigure.reactive.ReactiveOAuth2ClientWebSecurityAutoConfiguration +org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientAutoConfigurationTests.java index 9afcca06d20d..a93abc4b3b68 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientAutoConfigurationTests.java @@ -14,12 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client.servlet; +package org.springframework.boot.security.oauth2.client.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.registration.ClientRegistration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesMapperTests.java b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesMapperTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesMapperTests.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesMapperTests.java index 60d325aeb5cb..6f0edc9f80a9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesMapperTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesMapperTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client; +package org.springframework.boot.security.oauth2.client.autoconfigure; import java.util.Collections; import java.util.HashMap; @@ -27,8 +27,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.Provider; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties.Registration; +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientProperties.Provider; +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientProperties.Registration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesTests.java b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesTests.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesTests.java index 3fee91dbd7f5..5081de7ba1fa 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2ClientPropertiesTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/OAuth2ClientPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client; +package org.springframework.boot.security.oauth2.client.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientAutoConfigurationTests.java index 6e9a99fb20b6..886f20077668 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client.reactive; +package org.springframework.boot.security.oauth2.client.autoconfigure.reactive; import java.time.Duration; @@ -22,7 +22,7 @@ import reactor.core.publisher.Flux; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientWebSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientWebSecurityAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientWebSecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientWebSecurityAutoConfigurationTests.java index 4fcc0c31a418..9ce21f9fb9da 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientWebSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/reactive/ReactiveOAuth2ClientWebSecurityAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client.reactive; +package org.springframework.boot.security.oauth2.client.autoconfigure.reactive; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientWebSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/OAuth2ClientWebSecurityAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientWebSecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/OAuth2ClientWebSecurityAutoConfigurationTests.java index 76eb89e53252..43a860d06768 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientWebSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-client/src/test/java/org/springframework/boot/security/oauth2/client/autoconfigure/servlet/OAuth2ClientWebSecurityAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.client.servlet; +package org.springframework.boot.security.oauth2.client.autoconfigure.servlet; import java.util.ArrayList; import java.util.List; @@ -23,11 +23,11 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-security-oauth2-resource-server/build.gradle b/spring-boot-project/spring-boot-security-oauth2-resource-server/build.gradle new file mode 100644 index 000000000000..362f4fe1eb3b --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/build.gradle @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Security OAuth2 Resource Server" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.security:spring-security-oauth2-jose") + api("org.springframework.security:spring-security-oauth2-resource-server") + + implementation(project(":spring-boot-project:spring-boot-security")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-reactor")) + optional("jakarta.servlet:jakarta.servlet-api") + + testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-webmvc")) + testImplementation(project(":spring-boot-project:spring-boot-webflux")) + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("com.squareup.okhttp3:mockwebserver") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("org.springframework:spring-webflux") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ConditionalOnIssuerLocationJwtDecoder.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/ConditionalOnIssuerLocationJwtDecoder.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ConditionalOnIssuerLocationJwtDecoder.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/ConditionalOnIssuerLocationJwtDecoder.java index 30b9d4b26282..568d486dc316 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ConditionalOnIssuerLocationJwtDecoder.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/ConditionalOnIssuerLocationJwtDecoder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -30,9 +30,8 @@ * issuer-location-based JWT decoder} should be used. * * @author Andy Wilkinson - * @since 3.5.0 + * @since 4.0.0 */ -@SuppressWarnings("removal") @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) @Documented diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ConditionalOnPublicKeyJwtDecoder.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/ConditionalOnPublicKeyJwtDecoder.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ConditionalOnPublicKeyJwtDecoder.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/ConditionalOnPublicKeyJwtDecoder.java index 01c72b5d1e8b..1c4eb5c7fd75 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/ConditionalOnPublicKeyJwtDecoder.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/ConditionalOnPublicKeyJwtDecoder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -30,9 +30,8 @@ * JWT decoder} should be used. * * @author Andy Wilkinson - * @since 3.5.0 + * @since 4.0.0 */ -@SuppressWarnings("removal") @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) @Documented diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/IssuerUriCondition.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/IssuerUriCondition.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/IssuerUriCondition.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/IssuerUriCondition.java index 65dd625f4f23..89718f59cd6f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/IssuerUriCondition.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/IssuerUriCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; @@ -29,12 +29,8 @@ * Condition for creating {@link JwtDecoder} by oidc issuer location. * * @author Artsiom Yudovin - * @since 2.1.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link ConditionalOnIssuerLocationJwtDecoder @ConditionalOnIssuerLocationJwtDecoder} */ -@Deprecated(since = "3.5.0", forRemoval = true) -public class IssuerUriCondition extends SpringBootCondition { +class IssuerUriCondition extends SpringBootCondition { @Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/KeyValueCondition.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/KeyValueCondition.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/KeyValueCondition.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/KeyValueCondition.java index 0904693574fd..f0ee4b97e32e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/KeyValueCondition.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/KeyValueCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; @@ -28,12 +28,8 @@ * Condition for creating a jwt decoder using a public key value. * * @author Madhura Bhave - * @since 2.2.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link ConditionalOnPublicKeyJwtDecoder @ConditionalOnPublicKeyJwtDecoder} */ -@Deprecated(since = "3.5.0", forRemoval = true) -public class KeyValueCondition extends SpringBootCondition { +class KeyValueCondition extends SpringBootCondition { @Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/OAuth2ResourceServerProperties.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/OAuth2ResourceServerProperties.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/OAuth2ResourceServerProperties.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/OAuth2ResourceServerProperties.java index 26e53dd08aa4..531a8d448b64 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/OAuth2ResourceServerProperties.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/OAuth2ResourceServerProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure; import java.io.IOException; import java.io.InputStream; @@ -35,7 +35,7 @@ * @author Artsiom Yudovin * @author Mushtaq Ahmed * @author Yan Kardziyaka - * @since 2.1.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.security.oauth2.resourceserver") public class OAuth2ResourceServerProperties { diff --git a/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/package-info.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/package-info.java new file mode 100644 index 000000000000..437795bbe2b8 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Spring Security's OAuth2 resource server. + */ +package org.springframework.boot.security.oauth2.server.resource.autoconfigure; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/JwkSetUriReactiveJwtDecoderBuilderCustomizer.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/JwkSetUriReactiveJwtDecoderBuilderCustomizer.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/JwkSetUriReactiveJwtDecoderBuilderCustomizer.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/JwkSetUriReactiveJwtDecoderBuilderCustomizer.java index a2ff0db74523..ae890f4fad33 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/JwkSetUriReactiveJwtDecoderBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/JwkSetUriReactiveJwtDecoderBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive; import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder.JwkSetUriReactiveJwtDecoderBuilder; import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; @@ -26,7 +26,7 @@ * obtained through an issuer URI. * * @author Andy Wilkinson - * @since 3.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface JwkSetUriReactiveJwtDecoderBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerAutoConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerAutoConfiguration.java new file mode 100644 index 000000000000..5773b42e0244 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerAutoConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.autoconfigure.actuate.reactive.ReactiveManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveUserDetailsServiceAutoConfiguration; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties; +import org.springframework.context.annotation.Import; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Reactive OAuth2 resource server + * support. + * + * @author Madhura Bhave + * @since 4.0.0 + */ +@AutoConfiguration(before = { ReactiveManagementWebSecurityAutoConfiguration.class, + ReactiveSecurityAutoConfiguration.class, ReactiveUserDetailsServiceAutoConfiguration.class }) +@EnableConfigurationProperties(OAuth2ResourceServerProperties.class) +@ConditionalOnClass({ EnableWebFluxSecurity.class }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +@Import({ ReactiveOAuth2ResourceServerConfiguration.JwtConfiguration.class, + ReactiveOAuth2ResourceServerConfiguration.OpaqueTokenConfiguration.class }) +public class ReactiveOAuth2ResourceServerAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerConfiguration.java index 6337b2c7ef46..cdff4d704609 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java index 46be276d0abb..8f47c2be5a18 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive; import java.security.KeyFactory; import java.security.interfaces.RSAPublicKey; @@ -30,10 +30,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.security.oauth2.resource.ConditionalOnIssuerLocationJwtDecoder; -import org.springframework.boot.autoconfigure.security.oauth2.resource.ConditionalOnPublicKeyJwtDecoder; -import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.ConditionalOnIssuerLocationJwtDecoder; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.ConditionalOnPublicKeyJwtDecoder; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.java index 0f0f733ca9c0..01a74164c6ea 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerOpaqueTokenConfiguration.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.web.server.ServerHttpSecurity; diff --git a/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..f5a566f5e56b --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Security's Reactive OAuth2 resource server. + */ +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/JwkSetUriJwtDecoderBuilderCustomizer.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/JwkSetUriJwtDecoderBuilderCustomizer.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/JwkSetUriJwtDecoderBuilderCustomizer.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/JwkSetUriJwtDecoderBuilderCustomizer.java index 94ed1cfa22b6..a7e85e3e2727 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/JwkSetUriJwtDecoderBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/JwkSetUriJwtDecoderBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder.JwkSetUriJwtDecoderBuilder; @@ -25,7 +25,7 @@ * configured directly or obtained through an issuer URI. * * @author Andy Wilkinson - * @since 3.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface JwkSetUriJwtDecoderBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerAutoConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerAutoConfiguration.java new file mode 100644 index 000000000000..585afb089b02 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerAutoConfiguration.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.autoconfigure.actuate.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties; +import org.springframework.context.annotation.Import; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for OAuth2 resource server support. + * + * @author Madhura Bhave + * @since 4.0.0 + */ +@AutoConfiguration(before = { ManagementWebSecurityAutoConfiguration.class, SecurityAutoConfiguration.class, + UserDetailsServiceAutoConfiguration.class }) +@EnableConfigurationProperties(OAuth2ResourceServerProperties.class) +@ConditionalOnClass(BearerTokenAuthenticationToken.class) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +@Import({ Oauth2ResourceServerConfiguration.JwtConfiguration.class, + Oauth2ResourceServerConfiguration.OpaqueTokenConfiguration.class }) +public class OAuth2ResourceServerAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerJwtConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerJwtConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerJwtConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerJwtConfiguration.java index 1540c2417819..81a8a8eaf90f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerJwtConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerJwtConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet; import java.security.KeyFactory; import java.security.interfaces.RSAPublicKey; @@ -30,11 +30,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; -import org.springframework.boot.autoconfigure.security.oauth2.resource.ConditionalOnIssuerLocationJwtDecoder; -import org.springframework.boot.autoconfigure.security.oauth2.resource.ConditionalOnPublicKeyJwtDecoder; -import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.security.autoconfigure.ConditionalOnDefaultWebSecurity; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.ConditionalOnIssuerLocationJwtDecoder; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.ConditionalOnPublicKeyJwtDecoder; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerOpaqueTokenConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerOpaqueTokenConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerOpaqueTokenConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerOpaqueTokenConfiguration.java index 0296e1287cdb..c26a2370b008 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerOpaqueTokenConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerOpaqueTokenConfiguration.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; -import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties; +import org.springframework.boot.security.autoconfigure.ConditionalOnDefaultWebSecurity; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/Oauth2ResourceServerConfiguration.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/Oauth2ResourceServerConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/Oauth2ResourceServerConfiguration.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/Oauth2ResourceServerConfiguration.java index fd6fdcbd3b8b..d3f563bb7016 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/Oauth2ResourceServerConfiguration.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/Oauth2ResourceServerConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..bf718ed4eea0 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Security's OAuth2 resource server. + */ +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..ccbb1dd449ca --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,13 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.security.oauth2.resourceserver.jwt.jws-algorithm", + "type": "java.lang.String", + "deprecation": { + "replacement": "spring.security.oauth2.resourceserver.jwt.jws-algorithms", + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..36abf455cc47 --- /dev/null +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive.ReactiveOAuth2ResourceServerAutoConfiguration +org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet.OAuth2ResourceServerAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/JwtConverterCustomizationsArgumentsProvider.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/JwtConverterCustomizationsArgumentsProvider.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/JwtConverterCustomizationsArgumentsProvider.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/JwtConverterCustomizationsArgumentsProvider.java index 6566a10242b7..4b0742fe1fa0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/JwtConverterCustomizationsArgumentsProvider.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/JwtConverterCustomizationsArgumentsProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure; import java.time.Instant; import java.util.UUID; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java index 62e11246f5a5..37297a267b41 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive; import java.io.IOException; import java.lang.annotation.ElementType; @@ -49,11 +49,14 @@ import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.oauth2.resource.JwtConverterCustomizationsArgumentsProvider; +import org.springframework.boot.security.autoconfigure.actuate.reactive.ReactiveManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.JwtConverterCustomizationsArgumentsProvider; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; @@ -705,6 +708,19 @@ void jwtAuthenticationConverterByJwtConfigIsConditionalOnMissingBean() { }); } + @Test + void causesReactiveManagementWebSecurityAutoConfigurationToBackOff() { + ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ReactiveManagementWebSecurityAutoConfiguration.class, + ReactiveOAuth2ResourceServerAutoConfiguration.class, ReactiveSecurityAutoConfiguration.class, + WebFluxAutoConfiguration.class)); + contextRunner + .run((context) -> assertThat(context).hasSingleBean(ReactiveManagementWebSecurityAutoConfiguration.class)); + contextRunner.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://authserver") + .run((context) -> assertThat(context) + .doesNotHaveBean(ReactiveManagementWebSecurityAutoConfiguration.class)); + } + private void assertFilterConfiguredWithJwtAuthenticationManager(AssertableReactiveWebApplicationContext context) { MatcherSecurityWebFilterChain filterChain = (MatcherSecurityWebFilterChain) context .getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerAutoConfigurationTests.java index d9bef45fb79b..089544745c8a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.oauth2.resource.servlet; +package org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -47,12 +47,14 @@ import org.mockito.InOrder; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.oauth2.resource.JwtConverterCustomizationsArgumentsProvider; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.security.autoconfigure.actuate.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.JwtConverterCustomizationsArgumentsProvider; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; @@ -98,6 +100,8 @@ */ class OAuth2ResourceServerAutoConfigurationTests { + private static final String MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN = "managementSecurityFilterChain"; + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(OAuth2ResourceServerAutoConfiguration.class)) .withUserConfiguration(TestConfig.class); @@ -718,6 +722,18 @@ void jwtAuthenticationConverterByJwtConfigIsConditionalOnMissingBean() { }); } + @Test + void causesManagementWebSecurityAutoConfigurationToBackOff() { + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ManagementWebSecurityAutoConfiguration.class, + OAuth2ResourceServerAutoConfiguration.class, SecurityAutoConfiguration.class, + WebMvcAutoConfiguration.class)); + contextRunner.run((context) -> assertThat(context).hasSingleBean(ManagementWebSecurityAutoConfiguration.class)); + contextRunner.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://authserver") + .run((context) -> assertThat(context).doesNotHaveBean(ManagementWebSecurityAutoConfiguration.class) + .doesNotHaveBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN)); + } + private Filter getBearerTokenFilter(AssertableWebApplicationContext context) { FilterChainProxy filterChain = (FilterChainProxy) context.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN); List filterChains = filterChain.getFilterChains(); diff --git a/spring-boot-project/spring-boot-security-saml2/build.gradle b/spring-boot-project/spring-boot-security-saml2/build.gradle new file mode 100644 index 000000000000..bd6508233b85 --- /dev/null +++ b/spring-boot-project/spring-boot-security-saml2/build.gradle @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Security SAML2" + +configurations.all { + resolutionStrategy.eachDependency { + if (it.requested.group == 'org.opensaml') { + it.useVersion '4.0.1' + } + } +} + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.security:spring-security-saml2-service-provider") + + implementation(project(":spring-boot-project:spring-boot-security")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-webmvc")) + testImplementation("com.fasterxml.jackson.core:jackson-databind") + testImplementation("com.squareup.okhttp3:mockwebserver") + testImplementation("jakarta.servlet:jakarta.servlet-api") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/RegistrationConfiguredCondition.java b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/RegistrationConfiguredCondition.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/RegistrationConfiguredCondition.java rename to spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/RegistrationConfiguredCondition.java index fde7dfade701..b201b3a9604d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/RegistrationConfiguredCondition.java +++ b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/RegistrationConfiguredCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.saml2; +package org.springframework.boot.security.saml2.autoconfigure; import java.util.Collections; import java.util.Map; @@ -22,9 +22,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.security.saml2.autoconfigure.Saml2RelyingPartyProperties.Registration; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2LoginConfiguration.java b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2LoginConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2LoginConfiguration.java rename to spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2LoginConfiguration.java index 018c09296b51..2147b9c15be4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2LoginConfiguration.java +++ b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2LoginConfiguration.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.saml2; +package org.springframework.boot.security.saml2.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; +import org.springframework.boot.security.autoconfigure.ConditionalOnDefaultWebSecurity; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfiguration.java b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyAutoConfiguration.java similarity index 82% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfiguration.java rename to spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyAutoConfiguration.java index 04bc7ba92818..5ea99d96efb7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyAutoConfiguration.java @@ -14,14 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.saml2; +package org.springframework.boot.security.saml2.autoconfigure; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.autoconfigure.actuate.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.context.annotation.Import; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; @@ -30,9 +31,9 @@ * authentication support. * * @author Madhura Bhave - * @since 2.2.0 + * @since 4.0.0 */ -@AutoConfiguration(before = SecurityAutoConfiguration.class) +@AutoConfiguration(before = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class }) @ConditionalOnClass(RelyingPartyRegistrationRepository.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @Import({ Saml2RelyingPartyRegistrationConfiguration.class, Saml2LoginConfiguration.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java rename to spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyProperties.java index f0aa778afc37..137c35d3b260 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java +++ b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.saml2; +package org.springframework.boot.security.saml2.autoconfigure; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -32,7 +32,7 @@ * @author Phillip Webb * @author Moritz Halbritter * @author Lasse Wulff - * @since 2.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.security.saml2.relyingparty") public class Saml2RelyingPartyProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyRegistrationConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java rename to spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyRegistrationConfiguration.java index 68f1f26a03b6..5849331591f9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java +++ b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyRegistrationConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.saml2; +package org.springframework.boot.security.saml2.autoconfigure; import java.io.InputStream; import java.security.PrivateKey; @@ -26,12 +26,12 @@ import java.util.function.Consumer; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.AssertingParty; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.AssertingParty.Verification; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Decryption; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration.Signing; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.security.saml2.autoconfigure.Saml2RelyingPartyProperties.AssertingParty; +import org.springframework.boot.security.saml2.autoconfigure.Saml2RelyingPartyProperties.AssertingParty.Verification; +import org.springframework.boot.security.saml2.autoconfigure.Saml2RelyingPartyProperties.Decryption; +import org.springframework.boot.security.saml2.autoconfigure.Saml2RelyingPartyProperties.Registration; +import org.springframework.boot.security.saml2.autoconfigure.Saml2RelyingPartyProperties.Registration.Signing; import org.springframework.boot.ssl.pem.PemContent; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; diff --git a/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/package-info.java b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/package-info.java new file mode 100644 index 000000000000..ce52a339ef58 --- /dev/null +++ b/spring-boot-project/spring-boot-security-saml2/src/main/java/org/springframework/boot/security/saml2/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Security's SAML 2.0. + */ +package org.springframework.boot.security.saml2.autoconfigure; diff --git a/spring-boot-project/spring-boot-security-saml2/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-security-saml2/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-security-saml2/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-security-saml2/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-security-saml2/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..06e8706aa933 --- /dev/null +++ b/spring-boot-project/spring-boot-security-saml2/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.security.saml2.autoconfigure.Saml2RelyingPartyAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java b/spring-boot-project/spring-boot-security-saml2/src/test/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyAutoConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security-saml2/src/test/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyAutoConfigurationTests.java index 6ea5c66a6661..bbf26ef4e1d3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security-saml2/src/test/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.saml2; +package org.springframework.boot.security.saml2.autoconfigure; import java.io.InputStream; import java.util.List; @@ -26,13 +26,14 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.security.autoconfigure.actuate.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @@ -65,6 +66,8 @@ class Saml2RelyingPartyAutoConfigurationTests { private static final String PREFIX = "spring.security.saml2.relyingparty.registration"; + private static final String MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN = "managementSecurityFilterChain"; + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner().withConfiguration( AutoConfigurations.of(Saml2RelyingPartyAutoConfiguration.class, SecurityAutoConfiguration.class)); @@ -280,8 +283,8 @@ void signRequestShouldApplyIfMetadataUriIsSet() throws Exception { setupMockResponse(server, new ClassPathResource("idp-metadata")); this.contextRunner.withPropertyValues(PREFIX + ".foo.assertingparty.metadata-uri=" + metadataUrl, PREFIX + ".foo.assertingparty.singlesignon.sign-request=true", - PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:org/springframework/boot/autoconfigure/security/saml2/rsa.key", - PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:org/springframework/boot/autoconfigure/security/saml2/rsa.crt") + PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:org/springframework/boot/security/saml2/autoconfigure/rsa.key", + PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:org/springframework/boot/security/saml2/autoconfigure/rsa.crt") .run((context) -> { RelyingPartyRegistrationRepository repository = context .getBean(RelyingPartyRegistrationRepository.class); @@ -325,6 +328,22 @@ void autoconfigurationWithInvalidCertificateShouldFail() { .hasMessageContaining("Missing certificates or unrecognized format")); } + @Test + @WithPackageResources("certificate-location") + void causesManagementWebSecurityAutoConfigurationToBackOff() { + WebApplicationContextRunner contextRunner = this.contextRunner.withConfiguration( + AutoConfigurations.of(ManagementWebSecurityAutoConfiguration.class, WebMvcAutoConfiguration.class)); + assertThat(contextRunner + .run((context) -> assertThat(context).hasSingleBean(ManagementWebSecurityAutoConfiguration.class))); + contextRunner.withPropertyValues(PREFIX + + ".simplesamlphp.assertingparty.single-sign-on.url=https://simplesaml-for-spring-saml/SSOService.php", + PREFIX + ".simplesamlphp.assertingparty.single-sign-on.sign-request=false", + PREFIX + ".simplesamlphp.assertingparty.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + PREFIX + ".simplesamlphp.assertingparty.verification.credentials[0].certificate-location=classpath:certificate-location") + .run((context) -> assertThat(context).doesNotHaveBean(ManagementWebSecurityAutoConfiguration.class) + .doesNotHaveBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN)); + } + private void testMultipleProviders(String specifiedEntityId, String expected) throws Exception { try (MockWebServer server = new MockWebServer()) { server.start(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java b/spring-boot-project/spring-boot-security-saml2/src/test/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyPropertiesTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java rename to spring-boot-project/spring-boot-security-saml2/src/test/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyPropertiesTests.java index 3e14631de64a..8c5d184a33c4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java +++ b/spring-boot-project/spring-boot-security-saml2/src/test/java/org/springframework/boot/security/saml2/autoconfigure/Saml2RelyingPartyPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.saml2; +package org.springframework.boot.security.saml2.autoconfigure; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/certificate-location b/spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/certificate-location similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/certificate-location rename to spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/certificate-location diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/idp-metadata b/spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/idp-metadata similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/idp-metadata rename to spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/idp-metadata diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/idp-metadata-with-multiple-providers b/spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/idp-metadata-with-multiple-providers similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/idp-metadata-with-multiple-providers rename to spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/idp-metadata-with-multiple-providers diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/private-key-location b/spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/private-key-location similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/private-key-location rename to spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/private-key-location diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/rsa.crt b/spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/rsa.crt similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/rsa.crt rename to spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/rsa.crt diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/rsa.key b/spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/rsa.key similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/security/saml2/rsa.key rename to spring-boot-project/spring-boot-security-saml2/src/test/resources/org/springframework/boot/security/saml2/autoconfigure/rsa.key diff --git a/spring-boot-project/spring-boot-security/build.gradle b/spring-boot-project/spring-boot-security/build.gradle new file mode 100644 index 000000000000..8bfe469eeb13 --- /dev/null +++ b/spring-boot-project/spring-boot-security/build.gradle @@ -0,0 +1,81 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Security" + +configurations.all { + resolutionStrategy.eachDependency { + if (it.requested.group == 'org.opensaml') { + it.useVersion '4.0.1' + } + } +} + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.security:spring-security-config") + api("org.springframework.security:spring-security-web") + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-h2console")) + optional(project(":spring-boot-project:spring-boot-jersey")) + optional(project(":spring-boot-project:spring-boot-reactor")) + optional(project(":spring-boot-project:spring-boot-rsocket")) + optional(project(":spring-boot-project:spring-boot-webmvc")) + optional(project(":spring-boot-project:spring-boot-webflux")) + optional(project(":spring-boot-project:spring-boot-web-server")) + optional("jakarta.servlet:jakarta.servlet-api") + optional("org.springframework:spring-messaging") + optional("org.springframework:spring-webflux") + optional("org.springframework.security:spring-security-data") + optional("org.springframework.security:spring-security-messaging") + optional("org.springframework.security:spring-security-rsocket") + + testImplementation(project(":spring-boot-project:spring-boot-health")) + testImplementation(project(":spring-boot-project:spring-boot-hibernate")) + testImplementation(project(":spring-boot-project:spring-boot-http-converter")) + testImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-restclient")) + testImplementation(project(":spring-boot-project:spring-boot-rsocket")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-web-server-test")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("com.squareup.okhttp3:mockwebserver") + testImplementation("org.springframework.security:spring-security-oauth2-client") + testImplementation("org.springframework.security:spring-security-oauth2-jose") + testImplementation("org.springframework.security:spring-security-oauth2-resource-server") + testImplementation("org.springframework.security:spring-security-saml2-service-provider") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.zaxxer:HikariCP") + testRuntimeOnly("org.hsqldb:hsqldb") +} + +tasks.named("test") { + jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/ConditionalOnDefaultWebSecurity.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/ConditionalOnDefaultWebSecurity.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/ConditionalOnDefaultWebSecurity.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/ConditionalOnDefaultWebSecurity.java index 99c644e487ff..eca9f26e148f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/ConditionalOnDefaultWebSecurity.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/ConditionalOnDefaultWebSecurity.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security; +package org.springframework.boot.security.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -29,7 +29,7 @@ * the user has not defined their own configuration. * * @author Phillip Webb - * @since 2.4.0 + * @since 4.0.0 */ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/DefaultWebSecurityCondition.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/DefaultWebSecurityCondition.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/DefaultWebSecurityCondition.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/DefaultWebSecurityCondition.java index 67d0fc4f7542..1e37161bbc05 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/DefaultWebSecurityCondition.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/DefaultWebSecurityCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security; +package org.springframework.boot.security.autoconfigure; import org.springframework.boot.autoconfigure.condition.AllNestedConditions; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityDataConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/SecurityDataConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityDataConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/SecurityDataConfiguration.java index 1d42327eeb7a..2b949cedf299 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityDataConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/SecurityDataConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security; +package org.springframework.boot.security.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -26,7 +26,7 @@ * Automatically adds Spring Security's integration with Spring Data. * * @author Rob Winch - * @since 1.3.0 + * @since 4.0.0 */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass(SecurityEvaluationContextExtension.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/SecurityProperties.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/SecurityProperties.java index 6c3095be91c5..a1798878b35e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityProperties.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/SecurityProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security; +package org.springframework.boot.security.autoconfigure; import java.util.ArrayList; import java.util.EnumSet; @@ -23,8 +23,8 @@ import java.util.UUID; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.servlet.filter.OrderedFilter; import org.springframework.boot.web.servlet.DispatcherType; -import org.springframework.boot.web.servlet.filter.OrderedFilter; import org.springframework.core.Ordered; import org.springframework.util.StringUtils; @@ -34,7 +34,7 @@ * @author Dave Syer * @author Andy Wilkinson * @author Madhura Bhave - * @since 1.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.security") public class SecurityProperties { @@ -47,15 +47,6 @@ public class SecurityProperties { */ public static final int BASIC_AUTH_ORDER = Ordered.LOWEST_PRECEDENCE - 5; - /** - * Order applied to the {@code WebSecurityCustomizer} that ignores standard static - * resource paths. - * @deprecated since 3.5.0 for removal in 4.0.0 since Spring Security no longer - * recommends using the {@code .ignoring()} method - */ - @Deprecated(since = "3.5.0", forRemoval = true) - public static final int IGNORED_ORDER = Ordered.HIGHEST_PRECEDENCE; - /** * Default order of Spring Security's Filter in the servlet container (i.e. amongst * other filters registered with the container). There is no connection between this diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/StaticResourceLocation.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/StaticResourceLocation.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/StaticResourceLocation.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/StaticResourceLocation.java index e840b02e15a6..89ae4f2c898c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/StaticResourceLocation.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/StaticResourceLocation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security; +package org.springframework.boot.security.autoconfigure; import java.util.Arrays; import java.util.stream.Stream; @@ -23,7 +23,7 @@ * Common locations for static resources. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ public enum StaticResourceLocation { diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequest.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequest.java new file mode 100644 index 000000000000..36b4a6555a8b --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequest.java @@ -0,0 +1,451 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.actuate.reactive; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; +import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.security.reactive.ApplicationContextServerWebExchangeMatcher; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; +import org.springframework.http.HttpMethod; +import org.springframework.security.web.server.util.matcher.OrServerWebExchangeMatcher; +import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher.MatchResult; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.server.ServerWebExchange; + +/** + * Factory that can be used to create a {@link ServerWebExchangeMatcher} for actuator + * endpoint locations. + * + * @author Madhura Bhave + * @author Phillip Webb + * @author Chris Bono + * @since 4.0.0 + */ +public final class EndpointRequest { + + private static final ServerWebExchangeMatcher EMPTY_MATCHER = (request) -> MatchResult.notMatch(); + + private EndpointRequest() { + } + + /** + * Returns a matcher that includes all {@link Endpoint actuator endpoints}. It also + * includes the links endpoint which is present at the base path of the actuator + * endpoints. The {@link EndpointServerWebExchangeMatcher#excluding(Class...) + * excluding} method can be used to further remove specific endpoints if required. For + * example:
+	 * EndpointRequest.toAnyEndpoint().excluding(ShutdownEndpoint.class)
+	 * 
+ * @return the configured {@link ServerWebExchangeMatcher} + */ + public static EndpointServerWebExchangeMatcher toAnyEndpoint() { + return new EndpointServerWebExchangeMatcher(true); + } + + /** + * Returns a matcher that includes the specified {@link Endpoint actuator endpoints}. + * For example:
+	 * EndpointRequest.to(ShutdownEndpoint.class, HealthEndpoint.class)
+	 * 
+ * @param endpoints the endpoints to include + * @return the configured {@link ServerWebExchangeMatcher} + */ + public static EndpointServerWebExchangeMatcher to(Class... endpoints) { + return new EndpointServerWebExchangeMatcher(endpoints, false); + } + + /** + * Returns a matcher that includes the specified {@link Endpoint actuator endpoints}. + * For example:
+	 * EndpointRequest.to("shutdown", "health")
+	 * 
+ * @param endpoints the endpoints to include + * @return the configured {@link ServerWebExchangeMatcher} + */ + public static EndpointServerWebExchangeMatcher to(String... endpoints) { + return new EndpointServerWebExchangeMatcher(endpoints, false); + } + + /** + * Returns a matcher that matches only on the links endpoint. It can be used when + * security configuration for the links endpoint is different from the other + * {@link Endpoint actuator endpoints}. The + * {@link EndpointServerWebExchangeMatcher#excludingLinks() excludingLinks} method can + * be used in combination with this to remove the links endpoint from + * {@link EndpointRequest#toAnyEndpoint() toAnyEndpoint}. For example: + *
+	 * EndpointRequest.toLinks()
+	 * 
+ * @return the configured {@link ServerWebExchangeMatcher} + */ + public static LinksServerWebExchangeMatcher toLinks() { + return new LinksServerWebExchangeMatcher(); + } + + /** + * Returns a matcher that includes additional paths under a {@link WebServerNamespace} + * for the specified {@link Endpoint actuator endpoints}. For example: + *
+	 * EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "health")
+	 * 
+ * @param webServerNamespace the web server namespace + * @param endpoints the endpoints to include + * @return the configured {@link RequestMatcher} + */ + public static AdditionalPathsEndpointServerWebExchangeMatcher toAdditionalPaths( + WebServerNamespace webServerNamespace, Class... endpoints) { + return new AdditionalPathsEndpointServerWebExchangeMatcher(webServerNamespace, endpoints); + } + + /** + * Returns a matcher that includes additional paths under a {@link WebServerNamespace} + * for the specified {@link Endpoint actuator endpoints}. For example: + *
+	 * EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, HealthEndpoint.class)
+	 * 
+ * @param webServerNamespace the web server namespace + * @param endpoints the endpoints to include + * @return the configured {@link RequestMatcher} + */ + public static AdditionalPathsEndpointServerWebExchangeMatcher toAdditionalPaths( + WebServerNamespace webServerNamespace, String... endpoints) { + return new AdditionalPathsEndpointServerWebExchangeMatcher(webServerNamespace, endpoints); + } + + /** + * Base class for supported request matchers. + */ + private abstract static class AbstractWebExchangeMatcher extends ApplicationContextServerWebExchangeMatcher { + + private volatile ServerWebExchangeMatcher delegate; + + private volatile ManagementPortType managementPortType; + + AbstractWebExchangeMatcher(Class contextClass) { + super(contextClass); + } + + @Override + protected void initialized(Supplier supplier) { + this.delegate = createDelegate(supplier); + } + + private ServerWebExchangeMatcher createDelegate(Supplier context) { + try { + return createDelegate(context.get()); + } + catch (NoSuchBeanDefinitionException ex) { + return EMPTY_MATCHER; + } + } + + protected abstract ServerWebExchangeMatcher createDelegate(C context); + + protected final List getDelegateMatchers(Set paths, HttpMethod httpMethod) { + return paths.stream() + .map((path) -> getDelegateMatcher(path, httpMethod)) + .collect(Collectors.toCollection(ArrayList::new)); + } + + private PathPatternParserServerWebExchangeMatcher getDelegateMatcher(String path, HttpMethod httpMethod) { + Assert.notNull(path, "'path' must not be null"); + return new PathPatternParserServerWebExchangeMatcher(path + "/**", httpMethod); + } + + @Override + protected Mono matches(ServerWebExchange exchange, Supplier context) { + return this.delegate.matches(exchange); + } + + @Override + protected boolean ignoreApplicationContext(ApplicationContext applicationContext) { + ManagementPortType managementPortType = this.managementPortType; + if (managementPortType == null) { + managementPortType = ManagementPortType.get(applicationContext.getEnvironment()); + this.managementPortType = managementPortType; + } + return ignoreApplicationContext(applicationContext, managementPortType); + } + + protected boolean ignoreApplicationContext(ApplicationContext applicationContext, + ManagementPortType managementPortType) { + return managementPortType == ManagementPortType.DIFFERENT + && !hasWebServerNamespace(applicationContext, WebServerNamespace.MANAGEMENT); + } + + protected final boolean hasWebServerNamespace(ApplicationContext applicationContext, + WebServerNamespace webServerNamespace) { + return WebServerApplicationContext.hasServerNamespace(applicationContext, webServerNamespace.getValue()) + || hasImplicitServerNamespace(applicationContext, webServerNamespace); + } + + private boolean hasImplicitServerNamespace(ApplicationContext applicationContext, + WebServerNamespace webServerNamespace) { + return WebServerNamespace.SERVER.equals(webServerNamespace) + && WebServerApplicationContext.getServerNamespace(applicationContext) == null + && applicationContext.getParent() == null; + } + + protected final String toString(List endpoints, String emptyValue) { + return (!endpoints.isEmpty()) ? endpoints.stream() + .map(this::getEndpointId) + .map(Object::toString) + .collect(Collectors.joining(", ", "[", "]")) : emptyValue; + } + + protected final EndpointId getEndpointId(Object source) { + if (source instanceof EndpointId endpointId) { + return endpointId; + } + if (source instanceof String string) { + return EndpointId.of(string); + } + if (source instanceof Class) { + return getEndpointId((Class) source); + } + throw new IllegalStateException("Unsupported source " + source); + } + + private EndpointId getEndpointId(Class source) { + MergedAnnotation annotation = MergedAnnotations.from(source).get(Endpoint.class); + Assert.state(annotation.isPresent(), () -> "Class " + source + " is not annotated with @Endpoint"); + return EndpointId.of(annotation.getString("id")); + } + + } + + /** + * The {@link ServerWebExchangeMatcher} used to match against {@link Endpoint actuator + * endpoints}. + */ + public static final class EndpointServerWebExchangeMatcher extends AbstractWebExchangeMatcher { + + private final List includes; + + private final List excludes; + + private final boolean includeLinks; + + private final HttpMethod httpMethod; + + private EndpointServerWebExchangeMatcher(boolean includeLinks) { + this(Collections.emptyList(), Collections.emptyList(), includeLinks, null); + } + + private EndpointServerWebExchangeMatcher(Class[] endpoints, boolean includeLinks) { + this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks, null); + } + + private EndpointServerWebExchangeMatcher(String[] endpoints, boolean includeLinks) { + this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks, null); + } + + private EndpointServerWebExchangeMatcher(List includes, List excludes, boolean includeLinks, + HttpMethod httpMethod) { + super(PathMappedEndpoints.class); + this.includes = includes; + this.excludes = excludes; + this.includeLinks = includeLinks; + this.httpMethod = httpMethod; + } + + public EndpointServerWebExchangeMatcher excluding(Class... endpoints) { + List excludes = new ArrayList<>(this.excludes); + excludes.addAll(Arrays.asList((Object[]) endpoints)); + return new EndpointServerWebExchangeMatcher(this.includes, excludes, this.includeLinks, null); + } + + public EndpointServerWebExchangeMatcher excluding(String... endpoints) { + List excludes = new ArrayList<>(this.excludes); + excludes.addAll(Arrays.asList((Object[]) endpoints)); + return new EndpointServerWebExchangeMatcher(this.includes, excludes, this.includeLinks, null); + } + + public EndpointServerWebExchangeMatcher excludingLinks() { + return new EndpointServerWebExchangeMatcher(this.includes, this.excludes, false, null); + } + + /** + * Restricts the matcher to only consider requests with a particular http method. + * @param httpMethod the http method to include + * @return a copy of the matcher further restricted to only match requests with + * the specified http method + */ + public EndpointServerWebExchangeMatcher withHttpMethod(HttpMethod httpMethod) { + return new EndpointServerWebExchangeMatcher(this.includes, this.excludes, this.includeLinks, httpMethod); + } + + @Override + protected ServerWebExchangeMatcher createDelegate(PathMappedEndpoints endpoints) { + Set paths = new LinkedHashSet<>(); + if (this.includes.isEmpty()) { + paths.addAll(endpoints.getAllPaths()); + } + streamPaths(this.includes, endpoints).forEach(paths::add); + streamPaths(this.excludes, endpoints).forEach(paths::remove); + List delegateMatchers = getDelegateMatchers(paths, this.httpMethod); + if (this.includeLinks && StringUtils.hasText(endpoints.getBasePath())) { + delegateMatchers.add(new LinksServerWebExchangeMatcher()); + } + if (delegateMatchers.isEmpty()) { + return EMPTY_MATCHER; + } + return new OrServerWebExchangeMatcher(delegateMatchers); + } + + private Stream streamPaths(List source, PathMappedEndpoints endpoints) { + return source.stream() + .filter(Objects::nonNull) + .map(this::getEndpointId) + .map(endpoints::getPath) + .filter(Objects::nonNull); + } + + @Override + public String toString() { + return String.format("EndpointRequestMatcher includes=%s, excludes=%s, includeLinks=%s", + toString(this.includes, "[*]"), toString(this.excludes, "[]"), this.includeLinks); + } + + } + + /** + * The {@link ServerWebExchangeMatcher} used to match against the links endpoint. + */ + public static final class LinksServerWebExchangeMatcher extends AbstractWebExchangeMatcher { + + private LinksServerWebExchangeMatcher() { + super(WebEndpointProperties.class); + } + + @Override + protected ServerWebExchangeMatcher createDelegate(WebEndpointProperties properties) { + if (StringUtils.hasText(properties.getBasePath())) { + return new OrServerWebExchangeMatcher( + new PathPatternParserServerWebExchangeMatcher(properties.getBasePath()), + new PathPatternParserServerWebExchangeMatcher(properties.getBasePath() + "/")); + } + return EMPTY_MATCHER; + } + + @Override + public String toString() { + return String.format("LinksServerWebExchangeMatcher"); + } + + } + + /** + * The {@link ServerWebExchangeMatcher} used to match against additional paths for + * {@link Endpoint actuator endpoints}. + */ + public static class AdditionalPathsEndpointServerWebExchangeMatcher + extends AbstractWebExchangeMatcher { + + private final WebServerNamespace webServerNamespace; + + private final List endpoints; + + private final HttpMethod httpMethod; + + AdditionalPathsEndpointServerWebExchangeMatcher(WebServerNamespace webServerNamespace, String... endpoints) { + this(webServerNamespace, Arrays.asList((Object[]) endpoints), null); + } + + AdditionalPathsEndpointServerWebExchangeMatcher(WebServerNamespace webServerNamespace, Class... endpoints) { + this(webServerNamespace, Arrays.asList((Object[]) endpoints), null); + } + + private AdditionalPathsEndpointServerWebExchangeMatcher(WebServerNamespace webServerNamespace, + List endpoints, HttpMethod httpMethod) { + super(PathMappedEndpoints.class); + Assert.notNull(webServerNamespace, "'webServerNamespace' must not be null"); + Assert.notNull(endpoints, "'endpoints' must not be null"); + Assert.notEmpty(endpoints, "'endpoints' must not be empty"); + this.webServerNamespace = webServerNamespace; + this.endpoints = endpoints; + this.httpMethod = httpMethod; + } + + /** + * Restricts the matcher to only consider requests with a particular HTTP method. + * @param httpMethod the HTTP method to include + * @return a copy of the matcher further restricted to only match requests with + * the specified HTTP method + */ + public AdditionalPathsEndpointServerWebExchangeMatcher withHttpMethod(HttpMethod httpMethod) { + return new AdditionalPathsEndpointServerWebExchangeMatcher(this.webServerNamespace, this.endpoints, + httpMethod); + } + + @Override + protected boolean ignoreApplicationContext(ApplicationContext applicationContext, + ManagementPortType managementPortType) { + return !hasWebServerNamespace(applicationContext, this.webServerNamespace); + } + + @Override + protected ServerWebExchangeMatcher createDelegate(PathMappedEndpoints endpoints) { + Set paths = this.endpoints.stream() + .filter(Objects::nonNull) + .map(this::getEndpointId) + .flatMap((endpointId) -> streamAdditionalPaths(endpoints, endpointId)) + .collect(Collectors.toCollection(LinkedHashSet::new)); + List delegateMatchers = getDelegateMatchers(paths, this.httpMethod); + return (!CollectionUtils.isEmpty(delegateMatchers)) ? new OrServerWebExchangeMatcher(delegateMatchers) + : EMPTY_MATCHER; + } + + private Stream streamAdditionalPaths(PathMappedEndpoints pathMappedEndpoints, EndpointId endpointId) { + return pathMappedEndpoints.getAdditionalPaths(this.webServerNamespace, endpointId).stream(); + } + + @Override + public String toString() { + return String.format("AdditionalPathsEndpointServerWebExchangeMatcher endpoints=%s, webServerNamespace=%s", + toString(this.endpoints, ""), this.webServerNamespace); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/ReactiveManagementWebSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/ReactiveManagementWebSecurityAutoConfiguration.java similarity index 80% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/ReactiveManagementWebSecurityAutoConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/ReactiveManagementWebSecurityAutoConfiguration.java index ec3c535d8d40..033b973525fe 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/ReactiveManagementWebSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/ReactiveManagementWebSecurityAutoConfiguration.java @@ -14,13 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.reactive; +package org.springframework.boot.security.autoconfigure.actuate.reactive; import reactor.core.publisher.Mono; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -28,10 +26,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientWebSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveUserDetailsServiceAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; @@ -53,14 +49,14 @@ * while securing everything else. * * @author Madhura Bhave - * @since 2.1.0 + * @since 4.0.0 */ @AutoConfiguration(before = ReactiveSecurityAutoConfiguration.class, - after = { HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class, - WebEndpointAutoConfiguration.class, ReactiveOAuth2ClientWebSecurityAutoConfiguration.class, - ReactiveOAuth2ResourceServerAutoConfiguration.class, - ReactiveUserDetailsServiceAutoConfiguration.class }) -@ConditionalOnClass({ EnableWebFluxSecurity.class, WebFilterChainProxy.class }) + after = ReactiveUserDetailsServiceAutoConfiguration.class, + afterName = { "org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration", + "org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration", + "org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration" }) +@ConditionalOnClass({ EnableWebFluxSecurity.class, WebFilterChainProxy.class, WebEndpointAutoConfiguration.class }) @ConditionalOnMissingBean({ SecurityWebFilterChain.class, WebFilterChainProxy.class }) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) public class ReactiveManagementWebSecurityAutoConfiguration { diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/package-info.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/package-info.java new file mode 100644 index 000000000000..3f384d88d9fb --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for actuator security using WebFlux. + */ +package org.springframework.boot.security.autoconfigure.actuate.reactive; diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/EndpointRequest.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/EndpointRequest.java new file mode 100644 index 000000000000..573793c7bb42 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/EndpointRequest.java @@ -0,0 +1,486 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.actuate.servlet; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import jakarta.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; +import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; +import org.springframework.http.HttpMethod; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; +import org.springframework.security.web.util.matcher.OrRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.context.WebApplicationContext; + +/** + * Factory that can be used to create a {@link RequestMatcher} for actuator endpoint + * locations. + * + * @author Madhura Bhave + * @author Phillip Webb + * @author Chris Bono + * @since 2.0.0 + */ +public final class EndpointRequest { + + private static final RequestMatcher EMPTY_MATCHER = (request) -> false; + + private EndpointRequest() { + } + + /** + * Returns a matcher that includes all {@link Endpoint actuator endpoints}. It also + * includes the links endpoint which is present at the base path of the actuator + * endpoints. The {@link EndpointRequestMatcher#excluding(Class...) excluding} method + * can be used to further remove specific endpoints if required. For example: + *
+	 * EndpointRequest.toAnyEndpoint().excluding(ShutdownEndpoint.class)
+	 * 
+ * @return the configured {@link RequestMatcher} + */ + public static EndpointRequestMatcher toAnyEndpoint() { + return new EndpointRequestMatcher(true); + } + + /** + * Returns a matcher that includes the specified {@link Endpoint actuator endpoints}. + * For example:
+	 * EndpointRequest.to(ShutdownEndpoint.class, HealthEndpoint.class)
+	 * 
+ * @param endpoints the endpoints to include + * @return the configured {@link RequestMatcher} + */ + public static EndpointRequestMatcher to(Class... endpoints) { + return new EndpointRequestMatcher(endpoints, false); + } + + /** + * Returns a matcher that includes the specified {@link Endpoint actuator endpoints}. + * For example:
+	 * EndpointRequest.to("shutdown", "health")
+	 * 
+ * @param endpoints the endpoints to include + * @return the configured {@link RequestMatcher} + */ + public static EndpointRequestMatcher to(String... endpoints) { + return new EndpointRequestMatcher(endpoints, false); + } + + /** + * Returns a matcher that matches only on the links endpoint. It can be used when + * security configuration for the links endpoint is different from the other + * {@link Endpoint actuator endpoints}. The + * {@link EndpointRequestMatcher#excludingLinks() excludingLinks} method can be used + * in combination with this to remove the links endpoint from + * {@link EndpointRequest#toAnyEndpoint() toAnyEndpoint}. For example: + *
+	 * EndpointRequest.toLinks()
+	 * 
+ * @return the configured {@link RequestMatcher} + */ + public static LinksRequestMatcher toLinks() { + return new LinksRequestMatcher(); + } + + /** + * Returns a matcher that includes additional paths under a {@link WebServerNamespace} + * for the specified {@link Endpoint actuator endpoints}. For example: + *
+	 * EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "health")
+	 * 
+ * @param webServerNamespace the web server namespace + * @param endpoints the endpoints to include + * @return the configured {@link RequestMatcher} + * @since 3.4.0 + */ + public static AdditionalPathsEndpointRequestMatcher toAdditionalPaths(WebServerNamespace webServerNamespace, + Class... endpoints) { + return new AdditionalPathsEndpointRequestMatcher(webServerNamespace, endpoints); + } + + /** + * Returns a matcher that includes additional paths under a {@link WebServerNamespace} + * for the specified {@link Endpoint actuator endpoints}. For example: + *
+	 * EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, HealthEndpoint.class)
+	 * 
+ * @param webServerNamespace the web server namespace + * @param endpoints the endpoints to include + * @return the configured {@link RequestMatcher} + * @since 3.4.0 + */ + public static AdditionalPathsEndpointRequestMatcher toAdditionalPaths(WebServerNamespace webServerNamespace, + String... endpoints) { + return new AdditionalPathsEndpointRequestMatcher(webServerNamespace, endpoints); + } + + /** + * Base class for supported request matchers. + */ + private abstract static class AbstractRequestMatcher + extends ApplicationContextRequestMatcher { + + private volatile RequestMatcher delegate; + + private volatile ManagementPortType managementPortType; + + AbstractRequestMatcher() { + super(WebApplicationContext.class); + } + + @Override + protected boolean ignoreApplicationContext(WebApplicationContext applicationContext) { + ManagementPortType managementPortType = this.managementPortType; + if (managementPortType == null) { + managementPortType = ManagementPortType.get(applicationContext.getEnvironment()); + this.managementPortType = managementPortType; + } + return ignoreApplicationContext(applicationContext, managementPortType); + } + + protected boolean ignoreApplicationContext(WebApplicationContext applicationContext, + ManagementPortType managementPortType) { + return managementPortType == ManagementPortType.DIFFERENT + && !hasWebServerNamespace(applicationContext, WebServerNamespace.MANAGEMENT); + } + + protected final boolean hasWebServerNamespace(ApplicationContext applicationContext, + WebServerNamespace webServerNamespace) { + return WebServerApplicationContext.hasServerNamespace(applicationContext, webServerNamespace.getValue()) + || hasImplicitServerNamespace(applicationContext, webServerNamespace); + } + + private boolean hasImplicitServerNamespace(ApplicationContext applicationContext, + WebServerNamespace webServerNamespace) { + return WebServerNamespace.SERVER.equals(webServerNamespace) + && WebServerApplicationContext.getServerNamespace(applicationContext) == null + && applicationContext.getParent() == null; + } + + @Override + protected final void initialized(Supplier context) { + this.delegate = createDelegate(context.get()); + } + + @Override + protected final boolean matches(HttpServletRequest request, Supplier context) { + return this.delegate.matches(request); + } + + private RequestMatcher createDelegate(WebApplicationContext context) { + try { + return createDelegate(context, new RequestMatcherFactory()); + } + catch (NoSuchBeanDefinitionException ex) { + return EMPTY_MATCHER; + } + } + + protected abstract RequestMatcher createDelegate(WebApplicationContext context, + RequestMatcherFactory requestMatcherFactory); + + protected final List getDelegateMatchers(RequestMatcherFactory requestMatcherFactory, + RequestMatcherProvider matcherProvider, Set paths, HttpMethod httpMethod) { + return paths.stream() + .map((path) -> requestMatcherFactory.antPath(matcherProvider, httpMethod, path, "/**")) + .collect(Collectors.toCollection(ArrayList::new)); + } + + protected List getLinksMatchers(RequestMatcherFactory requestMatcherFactory, + RequestMatcherProvider matcherProvider, String basePath) { + List linksMatchers = new ArrayList<>(); + linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, basePath)); + linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, basePath, "/")); + return linksMatchers; + } + + protected RequestMatcherProvider getRequestMatcherProvider(WebApplicationContext context) { + try { + return context.getBean(RequestMatcherProvider.class); + } + catch (NoSuchBeanDefinitionException ex) { + return (pattern, method) -> PathPatternRequestMatcher.withDefaults().matcher(method, pattern); + } + } + + protected String toString(List endpoints, String emptyValue) { + return (!endpoints.isEmpty()) ? endpoints.stream() + .map(this::getEndpointId) + .map(Object::toString) + .collect(Collectors.joining(", ", "[", "]")) : emptyValue; + } + + protected EndpointId getEndpointId(Object source) { + if (source instanceof EndpointId endpointId) { + return endpointId; + } + if (source instanceof String string) { + return EndpointId.of(string); + } + if (source instanceof Class sourceClass) { + return getEndpointId(sourceClass); + } + throw new IllegalStateException("Unsupported source " + source); + } + + private EndpointId getEndpointId(Class source) { + MergedAnnotation annotation = MergedAnnotations.from(source).get(Endpoint.class); + Assert.state(annotation.isPresent(), () -> "Class " + source + " is not annotated with @Endpoint"); + return EndpointId.of(annotation.getString("id")); + } + + } + + /** + * The request matcher used to match against {@link Endpoint actuator endpoints}. + */ + public static final class EndpointRequestMatcher extends AbstractRequestMatcher { + + private final List includes; + + private final List excludes; + + private final boolean includeLinks; + + private final HttpMethod httpMethod; + + private EndpointRequestMatcher(boolean includeLinks) { + this(Collections.emptyList(), Collections.emptyList(), includeLinks, null); + } + + private EndpointRequestMatcher(Class[] endpoints, boolean includeLinks) { + this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks, null); + } + + private EndpointRequestMatcher(String[] endpoints, boolean includeLinks) { + this(Arrays.asList((Object[]) endpoints), Collections.emptyList(), includeLinks, null); + } + + private EndpointRequestMatcher(List includes, List excludes, boolean includeLinks, + HttpMethod httpMethod) { + this.includes = includes; + this.excludes = excludes; + this.includeLinks = includeLinks; + this.httpMethod = httpMethod; + } + + public EndpointRequestMatcher excluding(Class... endpoints) { + List excludes = new ArrayList<>(this.excludes); + excludes.addAll(Arrays.asList((Object[]) endpoints)); + return new EndpointRequestMatcher(this.includes, excludes, this.includeLinks, null); + } + + public EndpointRequestMatcher excluding(String... endpoints) { + List excludes = new ArrayList<>(this.excludes); + excludes.addAll(Arrays.asList((Object[]) endpoints)); + return new EndpointRequestMatcher(this.includes, excludes, this.includeLinks, null); + } + + public EndpointRequestMatcher excludingLinks() { + return new EndpointRequestMatcher(this.includes, this.excludes, false, null); + } + + /** + * Restricts the matcher to only consider requests with a particular HTTP method. + * @param httpMethod the HTTP method to include + * @return a copy of the matcher further restricted to only match requests with + * the specified HTTP method + * @since 3.5.0 + */ + public EndpointRequestMatcher withHttpMethod(HttpMethod httpMethod) { + return new EndpointRequestMatcher(this.includes, this.excludes, this.includeLinks, httpMethod); + } + + @Override + protected RequestMatcher createDelegate(WebApplicationContext context, + RequestMatcherFactory requestMatcherFactory) { + PathMappedEndpoints endpoints = context.getBean(PathMappedEndpoints.class); + RequestMatcherProvider matcherProvider = getRequestMatcherProvider(context); + Set paths = new LinkedHashSet<>(); + if (this.includes.isEmpty()) { + paths.addAll(endpoints.getAllPaths()); + } + streamPaths(this.includes, endpoints).forEach(paths::add); + streamPaths(this.excludes, endpoints).forEach(paths::remove); + List delegateMatchers = getDelegateMatchers(requestMatcherFactory, matcherProvider, paths, + this.httpMethod); + String basePath = endpoints.getBasePath(); + if (this.includeLinks && StringUtils.hasText(basePath)) { + delegateMatchers.addAll(getLinksMatchers(requestMatcherFactory, matcherProvider, basePath)); + } + if (delegateMatchers.isEmpty()) { + return EMPTY_MATCHER; + } + return new OrRequestMatcher(delegateMatchers); + } + + private Stream streamPaths(List source, PathMappedEndpoints endpoints) { + return source.stream() + .filter(Objects::nonNull) + .map(this::getEndpointId) + .map(endpoints::getPath) + .filter(Objects::nonNull); + } + + @Override + public String toString() { + return String.format("EndpointRequestMatcher includes=%s, excludes=%s, includeLinks=%s", + toString(this.includes, "[*]"), toString(this.excludes, "[]"), this.includeLinks); + } + + } + + /** + * The request matcher used to match against the links endpoint. + */ + public static final class LinksRequestMatcher extends AbstractRequestMatcher { + + @Override + protected RequestMatcher createDelegate(WebApplicationContext context, + RequestMatcherFactory requestMatcherFactory) { + WebEndpointProperties properties = context.getBean(WebEndpointProperties.class); + String basePath = properties.getBasePath(); + if (StringUtils.hasText(basePath)) { + return new OrRequestMatcher( + getLinksMatchers(requestMatcherFactory, getRequestMatcherProvider(context), basePath)); + } + return EMPTY_MATCHER; + } + + @Override + public String toString() { + return String.format("LinksRequestMatcher"); + } + + } + + /** + * The request matcher used to match against additional paths for {@link Endpoint + * actuator endpoints}. + */ + public static class AdditionalPathsEndpointRequestMatcher extends AbstractRequestMatcher { + + private final WebServerNamespace webServerNamespace; + + private final List endpoints; + + private final HttpMethod httpMethod; + + AdditionalPathsEndpointRequestMatcher(WebServerNamespace webServerNamespace, String... endpoints) { + this(webServerNamespace, Arrays.asList((Object[]) endpoints), null); + } + + AdditionalPathsEndpointRequestMatcher(WebServerNamespace webServerNamespace, Class... endpoints) { + this(webServerNamespace, Arrays.asList((Object[]) endpoints), null); + } + + private AdditionalPathsEndpointRequestMatcher(WebServerNamespace webServerNamespace, List endpoints, + HttpMethod httpMethod) { + Assert.notNull(webServerNamespace, "'webServerNamespace' must not be null"); + Assert.notNull(endpoints, "'endpoints' must not be null"); + Assert.notEmpty(endpoints, "'endpoints' must not be empty"); + this.webServerNamespace = webServerNamespace; + this.endpoints = endpoints; + this.httpMethod = httpMethod; + } + + /** + * Restricts the matcher to only consider requests with a particular HTTP method. + * @param httpMethod the HTTP method to include + * @return a copy of the matcher further restricted to only match requests with + * the specified HTTP method + * @since 3.5.0 + */ + public AdditionalPathsEndpointRequestMatcher withHttpMethod(HttpMethod httpMethod) { + return new AdditionalPathsEndpointRequestMatcher(this.webServerNamespace, this.endpoints, httpMethod); + } + + @Override + protected boolean ignoreApplicationContext(WebApplicationContext applicationContext, + ManagementPortType managementPortType) { + return !hasWebServerNamespace(applicationContext, this.webServerNamespace); + } + + @Override + protected RequestMatcher createDelegate(WebApplicationContext context, + RequestMatcherFactory requestMatcherFactory) { + PathMappedEndpoints endpoints = context.getBean(PathMappedEndpoints.class); + RequestMatcherProvider matcherProvider = getRequestMatcherProvider(context); + Set paths = this.endpoints.stream() + .filter(Objects::nonNull) + .map(this::getEndpointId) + .flatMap((endpointId) -> streamAdditionalPaths(endpoints, endpointId)) + .collect(Collectors.toCollection(LinkedHashSet::new)); + List delegateMatchers = getDelegateMatchers(requestMatcherFactory, matcherProvider, paths, + this.httpMethod); + return (!CollectionUtils.isEmpty(delegateMatchers)) ? new OrRequestMatcher(delegateMatchers) + : EMPTY_MATCHER; + } + + private Stream streamAdditionalPaths(PathMappedEndpoints pathMappedEndpoints, EndpointId endpointId) { + return pathMappedEndpoints.getAdditionalPaths(this.webServerNamespace, endpointId).stream(); + } + + @Override + public String toString() { + return String.format("AdditionalPathsEndpointRequestMatcher endpoints=%s, webServerNamespace=%s", + toString(this.endpoints, ""), this.webServerNamespace); + } + + } + + /** + * Factory used to create a {@link RequestMatcher}. + */ + private static final class RequestMatcherFactory { + + RequestMatcher antPath(RequestMatcherProvider matcherProvider, HttpMethod httpMethod, String... parts) { + StringBuilder pattern = new StringBuilder(); + for (String part : parts) { + Assert.notNull(part, "'part' must not be null"); + pattern.append(part); + } + return matcherProvider.getRequestMatcher(pattern.toString(), httpMethod); + } + + } + +} diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/ManagementWebSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/ManagementWebSecurityAutoConfiguration.java new file mode 100644 index 000000000000..4be15bffd7be --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/ManagementWebSecurityAutoConfiguration.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.actuate.servlet; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.security.autoconfigure.ConditionalOnDefaultWebSecurity; +import org.springframework.boot.security.autoconfigure.SecurityProperties; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.ClassUtils; + +import static org.springframework.security.config.Customizer.withDefaults; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Security when actuator is + * on the classpath. It allows unauthenticated access to the {@link HealthEndpoint}. If + * the user specifies their own {@link SecurityFilterChain} bean, this will back-off + * completely and the user should specify all the bits that they want to configure as part + * of the custom security configuration. + * + * @author Madhura Bhave + * @author Hatef Palizgar + * @since 4.0.0 + */ +@AutoConfiguration(before = SecurityAutoConfiguration.class, + afterName = { "org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration", + "org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration" }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +@ConditionalOnClass({ RequestMatcher.class, WebEndpointAutoConfiguration.class }) +@ConditionalOnDefaultWebSecurity +public class ManagementWebSecurityAutoConfiguration { + + @Bean + @Order(SecurityProperties.BASIC_AUTH_ORDER) + SecurityFilterChain managementSecurityFilterChain(Environment environment, HttpSecurity http) throws Exception { + http.authorizeHttpRequests((requests) -> { + requests.requestMatchers(healthMatcher(), additionalHealthPathsMatcher()).permitAll(); + requests.anyRequest().authenticated(); + }); + if (ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", null)) { + http.cors(withDefaults()); + } + http.formLogin(withDefaults()); + http.httpBasic(withDefaults()); + return http.build(); + } + + private RequestMatcher healthMatcher() { + return EndpointRequest.to(HealthEndpoint.class); + } + + private RequestMatcher additionalHealthPathsMatcher() { + return EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, HealthEndpoint.class); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/PathPatternRequestMatcherProvider.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/PathPatternRequestMatcherProvider.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/PathPatternRequestMatcherProvider.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/PathPatternRequestMatcherProvider.java index bc593fc495a7..43775d2ef4e3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/PathPatternRequestMatcherProvider.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/PathPatternRequestMatcherProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.actuate.servlet; import java.util.function.Function; diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/RequestMatcherProvider.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/RequestMatcherProvider.java new file mode 100644 index 000000000000..52bf6f54de05 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/RequestMatcherProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.actuate.servlet; + +import org.springframework.http.HttpMethod; +import org.springframework.security.web.util.matcher.RequestMatcher; + +/** + * Interface that can be used to provide a {@link RequestMatcher} that can be used with + * Spring Security. + * + * @author Madhura Bhave + * @author Chris Bono + * @since 4.0.0 + */ +@FunctionalInterface +public interface RequestMatcherProvider { + + /** + * Return the {@link RequestMatcher} to be used for the specified pattern and http + * method. + * @param pattern the request pattern + * @param httpMethod the http method + * @return a request matcher + */ + RequestMatcher getRequestMatcher(String pattern, HttpMethod httpMethod); + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/SecurityRequestMatchersManagementContextConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/SecurityRequestMatchersManagementContextConfiguration.java index 7d43b6de7500..adabb86de56a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/SecurityRequestMatchersManagementContextConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.actuate.servlet; import org.glassfish.jersey.server.ResourceConfig; @@ -24,8 +24,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.web.util.matcher.RequestMatcher; @@ -36,7 +36,7 @@ * {@link RequestMatcherProvider}. * * @author Madhura Bhave - * @since 2.1.8 + * @since 4.0.0 */ @ManagementContextConfiguration(proxyBeanMethods = false) @ConditionalOnClass({ RequestMatcher.class }) diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/package-info.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/package-info.java new file mode 100644 index 000000000000..d69efc2e7c37 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for actuator security using Spring MVC. + */ +package org.springframework.boot.security.autoconfigure.actuate.servlet; diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/package-info.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/package-info.java new file mode 100644 index 000000000000..eaf07258f858 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Security. + */ +package org.springframework.boot.security.autoconfigure; diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/PathRequest.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/PathRequest.java new file mode 100644 index 000000000000..b5d51b27d959 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/PathRequest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.reactive; + +import org.springframework.boot.security.autoconfigure.StaticResourceLocation; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; + +/** + * Factory that can be used to create a {@link ServerWebExchangeMatcher} for commonly used + * paths. + * + * @author Madhura Bhave + * @since 4.0.0 + */ +public final class PathRequest { + + private PathRequest() { + } + + /** + * Returns a {@link StaticResourceRequest} that can be used to create a matcher for + * {@link StaticResourceLocation locations}. + * @return a {@link StaticResourceRequest} + */ + public static StaticResourceRequest toStaticResources() { + return StaticResourceRequest.INSTANCE; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveSecurityAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveSecurityAutoConfiguration.java index ebc5b7e84046..9515aa9b29e2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveSecurityAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.reactive; +package org.springframework.boot.security.autoconfigure.reactive; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -24,8 +24,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.ReactiveAuthenticationManager; @@ -45,7 +45,7 @@ * configured in any other way. * * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration @EnableConfigurationProperties(SecurityProperties.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveUserDetailsServiceAutoConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveUserDetailsServiceAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveUserDetailsServiceAutoConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveUserDetailsServiceAutoConfiguration.java index 0e6c10831722..92159fb4fbc4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveUserDetailsServiceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveUserDetailsServiceAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.reactive; +package org.springframework.boot.security.autoconfigure.reactive; import java.util.List; import java.util.regex.Pattern; @@ -31,9 +31,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; -import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -55,9 +54,10 @@ * {@link ReactiveAuthenticationManagerResolver}. * * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(before = ReactiveSecurityAutoConfiguration.class, after = RSocketMessagingAutoConfiguration.class) +@AutoConfiguration(before = ReactiveSecurityAutoConfiguration.class, + afterName = "org.springframework.boot.rsocket.autoconfigure.RSocketMessagingAutoConfiguration") @ConditionalOnClass({ ReactiveAuthenticationManager.class }) @ConditionalOnMissingBean( value = { ReactiveAuthenticationManager.class, ReactiveUserDetailsService.class, diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/StaticResourceRequest.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/StaticResourceRequest.java new file mode 100644 index 000000000000..4f7074e58f84 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/StaticResourceRequest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.reactive; + +import java.util.EnumSet; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.stream.Stream; + +import reactor.core.publisher.Mono; + +import org.springframework.boot.security.autoconfigure.StaticResourceLocation; +import org.springframework.security.web.server.util.matcher.OrServerWebExchangeMatcher; +import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; +import org.springframework.util.Assert; +import org.springframework.web.server.ServerWebExchange; + +/** + * Used to create a {@link ServerWebExchangeMatcher} for static resources in commonly used + * locations. Returned by {@link PathRequest#toStaticResources()}. + * + * @author Madhura Bhave + * @since 4.0.0 + * @see PathRequest + */ +public final class StaticResourceRequest { + + static final StaticResourceRequest INSTANCE = new StaticResourceRequest(); + + private StaticResourceRequest() { + } + + /** + * Returns a matcher that includes all commonly used {@link StaticResourceLocation + * Locations}. The + * {@link StaticResourceServerWebExchange#excluding(StaticResourceLocation, StaticResourceLocation...) + * excluding} method can be used to remove specific locations if required. For + * example:
+	 * PathRequest.toStaticResources().atCommonLocations().excluding(StaticResourceLocation.CSS)
+	 * 
+ * @return the configured {@link ServerWebExchangeMatcher} + */ + public StaticResourceServerWebExchange atCommonLocations() { + return at(EnumSet.allOf(StaticResourceLocation.class)); + } + + /** + * Returns a matcher that includes the specified {@link StaticResourceLocation + * Locations}. For example:
+	 * PathRequest.toStaticResources().at(StaticResourceLocation.CSS, StaticResourceLocation.JAVA_SCRIPT)
+	 * 
+ * @param first the first location to include + * @param rest additional locations to include + * @return the configured {@link ServerWebExchangeMatcher} + */ + public StaticResourceServerWebExchange at(StaticResourceLocation first, StaticResourceLocation... rest) { + return at(EnumSet.of(first, rest)); + } + + /** + * Returns a matcher that includes the specified {@link StaticResourceLocation + * Locations}. For example:
+	 * PathRequest.toStaticResources().at(locations)
+	 * 
+ * @param locations the locations to include + * @return the configured {@link ServerWebExchangeMatcher} + */ + public StaticResourceServerWebExchange at(Set locations) { + Assert.notNull(locations, "'locations' must not be null"); + return new StaticResourceServerWebExchange(new LinkedHashSet<>(locations)); + } + + /** + * The server web exchange matcher used to match against resource + * {@link StaticResourceLocation locations}. + */ + public static final class StaticResourceServerWebExchange implements ServerWebExchangeMatcher { + + private final Set locations; + + private StaticResourceServerWebExchange(Set locations) { + this.locations = locations; + } + + /** + * Return a new {@link StaticResourceServerWebExchange} based on this one but + * excluding the specified locations. + * @param first the first location to exclude + * @param rest additional locations to exclude + * @return a new {@link StaticResourceServerWebExchange} + */ + public StaticResourceServerWebExchange excluding(StaticResourceLocation first, StaticResourceLocation... rest) { + return excluding(EnumSet.of(first, rest)); + } + + /** + * Return a new {@link StaticResourceServerWebExchange} based on this one but + * excluding the specified locations. + * @param locations the locations to exclude + * @return a new {@link StaticResourceServerWebExchange} + */ + public StaticResourceServerWebExchange excluding(Set locations) { + Assert.notNull(locations, "'locations' must not be null"); + Set subset = new LinkedHashSet<>(this.locations); + subset.removeAll(locations); + return new StaticResourceServerWebExchange(subset); + } + + private Stream getPatterns() { + return this.locations.stream().flatMap(StaticResourceLocation::getPatterns); + } + + @Override + public Mono matches(ServerWebExchange exchange) { + return new OrServerWebExchangeMatcher(getDelegateMatchers().toList()).matches(exchange); + } + + private Stream getDelegateMatchers() { + return getPatterns().map(PathPatternParserServerWebExchangeMatcher::new); + } + + } + +} diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..8a1d95f9f16b --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for reactive Spring Security. + */ +package org.springframework.boot.security.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/rsocket/RSocketSecurityAutoConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/rsocket/RSocketSecurityAutoConfiguration.java index 889305a2f2a0..9bdf2431137c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/rsocket/RSocketSecurityAutoConfiguration.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.rsocket; +package org.springframework.boot.security.autoconfigure.rsocket; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessageHandlerCustomizer; +import org.springframework.boot.rsocket.autoconfigure.RSocketMessageHandlerCustomizer; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,11 +34,11 @@ * @author Madhura Bhave * @author Brian Clozel * @author Guirong Hu - * @since 2.2.0 + * @since 4.0.0 */ @AutoConfiguration @EnableRSocketSecurity -@ConditionalOnClass(SecuritySocketAcceptorInterceptor.class) +@ConditionalOnClass({ RSocketServerCustomizer.class, SecuritySocketAcceptorInterceptor.class }) public class RSocketSecurityAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/rsocket/package-info.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/rsocket/package-info.java new file mode 100644 index 000000000000..0fd4f5cb0d76 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/rsocket/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for RSocket support in Spring Security. + */ +package org.springframework.boot.security.autoconfigure.rsocket; diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/PathRequest.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/PathRequest.java new file mode 100644 index 000000000000..6431d21b72a7 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/PathRequest.java @@ -0,0 +1,95 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.servlet; + +import java.util.function.Supplier; + +import jakarta.servlet.http.HttpServletRequest; + +import org.springframework.boot.h2console.autoconfigure.H2ConsoleProperties; +import org.springframework.boot.security.autoconfigure.StaticResourceLocation; +import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.context.ApplicationContext; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.Assert; +import org.springframework.web.context.WebApplicationContext; + +/** + * Factory that can be used to create a {@link RequestMatcher} for commonly used paths. + * + * @author Madhura Bhave + * @author Phillip Webb + * @since 4.0.0 + */ +public final class PathRequest { + + private PathRequest() { + } + + /** + * Returns a {@link StaticResourceRequest} that can be used to create a matcher for + * {@link StaticResourceLocation locations}. + * @return a {@link StaticResourceRequest} + */ + public static StaticResourceRequest toStaticResources() { + return StaticResourceRequest.INSTANCE; + } + + /** + * Returns a matcher that includes the H2 console location. For example: + *
+	 * PathRequest.toH2Console()
+	 * 
+ * @return the configured {@link RequestMatcher} + */ + public static H2ConsoleRequestMatcher toH2Console() { + return new H2ConsoleRequestMatcher(); + } + + /** + * The request matcher used to match against h2 console path. + */ + public static final class H2ConsoleRequestMatcher extends ApplicationContextRequestMatcher { + + private volatile RequestMatcher delegate; + + private H2ConsoleRequestMatcher() { + super(ApplicationContext.class); + } + + @Override + protected boolean ignoreApplicationContext(WebApplicationContext applicationContext) { + return WebServerApplicationContext.hasServerNamespace(applicationContext, "management"); + } + + @Override + protected void initialized(Supplier context) { + String path = context.get().getBean(H2ConsoleProperties.class).getPath(); + Assert.hasText(path, "'path' in H2ConsoleProperties must not be empty"); + this.delegate = PathPatternRequestMatcher.withDefaults().matcher(path + "/**"); + } + + @Override + protected boolean matches(HttpServletRequest request, Supplier context) { + return this.delegate.matches(request); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SecurityAutoConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SecurityAutoConfiguration.java index 45e5f0f3046f..919cf21d8bce 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SecurityAutoConfiguration.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.servlet; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.security.SecurityDataConfiguration; -import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.autoconfigure.SecurityDataConfiguration; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -35,7 +35,7 @@ * @author Dave Syer * @author Andy Wilkinson * @author Madhura Bhave - * @since 1.0.0 + * @since 4.0.0 */ @AutoConfiguration(before = UserDetailsServiceAutoConfiguration.class) @ConditionalOnClass(DefaultAuthenticationEventPublisher.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfiguration.java index 8381f035fd85..40695cb4802b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.servlet; import java.util.EnumSet; import java.util.stream.Collectors; @@ -27,8 +27,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration; @@ -44,7 +44,7 @@ * @author Rob Winch * @author Phillip Webb * @author Andy Wilkinson - * @since 1.3.0 + * @since 4.0.0 */ @AutoConfiguration(after = SecurityAutoConfiguration.class) @ConditionalOnWebApplication(type = Type.SERVLET) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SpringBootWebSecurityConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SpringBootWebSecurityConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SpringBootWebSecurityConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SpringBootWebSecurityConfiguration.java index d1e5eba15115..8781ca783596 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/SpringBootWebSecurityConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SpringBootWebSecurityConfiguration.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.servlet; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity; -import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.security.autoconfigure.ConditionalOnDefaultWebSecurity; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/StaticResourceRequest.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/StaticResourceRequest.java new file mode 100644 index 000000000000..2f0e76e4714a --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/StaticResourceRequest.java @@ -0,0 +1,160 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.servlet; + +import java.util.EnumSet; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import jakarta.servlet.http.HttpServletRequest; + +import org.springframework.boot.security.autoconfigure.StaticResourceLocation; +import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; +import org.springframework.security.web.util.matcher.OrRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.Assert; +import org.springframework.web.context.WebApplicationContext; + +/** + * Used to create a {@link RequestMatcher} for static resources in commonly used + * locations. Returned by {@link PathRequest#toStaticResources()}. + * + * @author Madhura Bhave + * @author Phillip Webb + * @since 4.0.0 + * @see PathRequest + */ +public final class StaticResourceRequest { + + static final StaticResourceRequest INSTANCE = new StaticResourceRequest(); + + private StaticResourceRequest() { + } + + /** + * Returns a matcher that includes all commonly used {@link StaticResourceLocation + * Locations}. The + * {@link StaticResourceRequestMatcher#excluding(StaticResourceLocation, StaticResourceLocation...) + * excluding} method can be used to remove specific locations if required. For + * example:
+	 * PathRequest.toStaticResources().atCommonLocations().excluding(StaticResourceLocation.CSS)
+	 * 
+ * @return the configured {@link RequestMatcher} + */ + public StaticResourceRequestMatcher atCommonLocations() { + return at(EnumSet.allOf(StaticResourceLocation.class)); + } + + /** + * Returns a matcher that includes the specified {@link StaticResourceLocation + * Locations}. For example:
+	 * PathRequest.toStaticResources().at(StaticResourceLocation.CSS, StaticResourceLocation.JAVA_SCRIPT)
+	 * 
+ * @param first the first location to include + * @param rest additional locations to include + * @return the configured {@link RequestMatcher} + */ + public StaticResourceRequestMatcher at(StaticResourceLocation first, StaticResourceLocation... rest) { + return at(EnumSet.of(first, rest)); + } + + /** + * Returns a matcher that includes the specified {@link StaticResourceLocation + * Locations}. For example:
+	 * PathRequest.toStaticResources().at(locations)
+	 * 
+ * @param locations the locations to include + * @return the configured {@link RequestMatcher} + */ + public StaticResourceRequestMatcher at(Set locations) { + Assert.notNull(locations, "'locations' must not be null"); + return new StaticResourceRequestMatcher(new LinkedHashSet<>(locations)); + } + + /** + * The request matcher used to match against resource {@link StaticResourceLocation + * Locations}. + */ + public static final class StaticResourceRequestMatcher + extends ApplicationContextRequestMatcher { + + private final Set locations; + + private volatile RequestMatcher delegate; + + private StaticResourceRequestMatcher(Set locations) { + super(DispatcherServletPath.class); + this.locations = locations; + } + + /** + * Return a new {@link StaticResourceRequestMatcher} based on this one but + * excluding the specified locations. + * @param first the first location to exclude + * @param rest additional locations to exclude + * @return a new {@link StaticResourceRequestMatcher} + */ + public StaticResourceRequestMatcher excluding(StaticResourceLocation first, StaticResourceLocation... rest) { + return excluding(EnumSet.of(first, rest)); + } + + /** + * Return a new {@link StaticResourceRequestMatcher} based on this one but + * excluding the specified locations. + * @param locations the locations to exclude + * @return a new {@link StaticResourceRequestMatcher} + */ + public StaticResourceRequestMatcher excluding(Set locations) { + Assert.notNull(locations, "'locations' must not be null"); + Set subset = new LinkedHashSet<>(this.locations); + subset.removeAll(locations); + return new StaticResourceRequestMatcher(subset); + } + + @Override + protected void initialized(Supplier dispatcherServletPath) { + this.delegate = new OrRequestMatcher(getDelegateMatchers(dispatcherServletPath.get()).toList()); + } + + private Stream getDelegateMatchers(DispatcherServletPath dispatcherServletPath) { + return getPatterns(dispatcherServletPath).map(PathPatternRequestMatcher.withDefaults()::matcher); + } + + private Stream getPatterns(DispatcherServletPath dispatcherServletPath) { + return this.locations.stream() + .flatMap(StaticResourceLocation::getPatterns) + .map(dispatcherServletPath::getRelativePath); + } + + @Override + protected boolean ignoreApplicationContext(WebApplicationContext applicationContext) { + return WebServerApplicationContext.hasServerNamespace(applicationContext, "management"); + } + + @Override + protected boolean matches(HttpServletRequest request, Supplier context) { + return this.delegate.matches(request); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/UserDetailsServiceAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/UserDetailsServiceAutoConfiguration.java index b8b78f31b62b..8e415fff3740 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/UserDetailsServiceAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.servlet; import java.util.List; import java.util.regex.Pattern; @@ -33,8 +33,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration.MissingAlternativeOrUserPropertiesConfigured; +import org.springframework.boot.security.autoconfigure.SecurityProperties; +import org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration.MissingAlternativeOrUserPropertiesConfigured; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.security.authentication.AuthenticationManager; @@ -56,7 +56,7 @@ * @author Rob Winch * @author Madhura Bhave * @author Lasse Wulff - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(AuthenticationManager.class) diff --git a/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..f7018ddb5227 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Servlet-based Spring Security. + */ +package org.springframework.boot.security.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcher.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcher.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcher.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcher.java index fc5562b6b3a4..247d092b6de7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcher.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcher.java @@ -36,7 +36,7 @@ * an {@link ApplicationContext} or a class of an {@link ApplicationContext#getBean(Class) * existing bean}. * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ public abstract class ApplicationContextServerWebExchangeMatcher implements ServerWebExchangeMatcher { @@ -73,7 +73,6 @@ public final Mono matches(ServerWebExchange exchange) { * the {@link #matches(ServerWebExchange) matches} method will return {@code false}. * @param applicationContext the candidate application context * @return if the application context should be ignored - * @since 2.2.5 */ protected boolean ignoreApplicationContext(ApplicationContext applicationContext) { return false; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/reactive/package-info.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/reactive/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/reactive/package-info.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/reactive/package-info.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcher.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcher.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcher.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcher.java index 9f686ae78c82..fd07393204ef 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcher.java +++ b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcher.java @@ -37,7 +37,7 @@ * an {@link ApplicationContext} or a class of an {@link ApplicationContext#getBean(Class) * existing bean}. * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ public abstract class ApplicationContextRequestMatcher implements RequestMatcher { @@ -85,7 +85,6 @@ private C getContext(WebApplicationContext webApplicationContext) { * the {@link #matches(HttpServletRequest) matches} method will return {@code false}. * @param webApplicationContext the candidate web application context * @return if the application context should be ignored - * @since 2.1.8 */ protected boolean ignoreApplicationContext(WebApplicationContext webApplicationContext) { return false; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/servlet/package-info.java b/spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/servlet/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/servlet/package-info.java rename to spring-boot-project/spring-boot-security/src/main/java/org/springframework/boot/security/servlet/package-info.java diff --git a/spring-boot-project/spring-boot-security/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-security/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..e12f6d393538 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,19 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.security.filter.dispatcher-types", + "defaultValue": [ + "async", + "error", + "forward", + "include", + "request" + ] + }, + { + "name": "spring.security.filter.order", + "defaultValue": -100 + } + ] +} diff --git a/spring-boot-project/spring-boot-security/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-security/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..91a140d1ded2 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.security.autoconfigure.actuate.servlet.SecurityRequestMatchersManagementContextConfiguration diff --git a/spring-boot-project/spring-boot-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..0ebb4e22caa7 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,8 @@ +org.springframework.boot.security.autoconfigure.actuate.reactive.ReactiveManagementWebSecurityAutoConfiguration +org.springframework.boot.security.autoconfigure.actuate.servlet.ManagementWebSecurityAutoConfiguration +org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration +org.springframework.boot.security.autoconfigure.reactive.ReactiveUserDetailsServiceAutoConfiguration +org.springframework.boot.security.autoconfigure.rsocket.RSocketSecurityAutoConfiguration +org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration +org.springframework.boot.security.autoconfigure.servlet.SecurityFilterAutoConfiguration +org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityPropertiesTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/SecurityPropertiesTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityPropertiesTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/SecurityPropertiesTests.java index 5628c49c85ee..1096184c5c84 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityPropertiesTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/SecurityPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security; +package org.springframework.boot.security.autoconfigure; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestIntegrationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequestIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestIntegrationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequestIntegrationTests.java index 29858d30a68e..30884d7681d8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestIntegrationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequestIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.reactive; +package org.springframework.boot.security.autoconfigure.actuate.reactive; import java.time.Duration; import java.util.Base64; @@ -29,17 +29,17 @@ import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveUserDetailsServiceAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; diff --git a/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequestTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequestTests.java new file mode 100644 index 000000000000..549c2c8dc543 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequestTests.java @@ -0,0 +1,472 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.actuate.reactive; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.assertj.core.api.AssertDelegateTarget; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.ExposableEndpoint; +import org.springframework.boot.actuate.endpoint.Operation; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; +import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.http.HttpMethod; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.http.server.reactive.MockServerHttpResponse; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; +import org.springframework.web.context.support.StaticWebApplicationContext; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebHandler; +import org.springframework.web.server.adapter.HttpWebHandlerAdapter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link EndpointRequest}. + * + * @author Madhura Bhave + * @author Phillip Webb + * @author Chris Bono + */ +class EndpointRequestTests { + + @Test + void toAnyEndpointShouldMatchEndpointPath() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher).matches("/actuator/foo"); + assertMatcher(matcher).matches("/actuator/bar"); + assertMatcher(matcher).matches("/actuator"); + } + + @Test + void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().withHttpMethod(HttpMethod.POST); + assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/foo"); + assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo"); + } + + @Test + void toAnyEndpointShouldMatchEndpointPathWithTrailingSlash() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher).matches("/actuator/foo/"); + assertMatcher(matcher).matches("/actuator/bar/"); + assertMatcher(matcher).matches("/actuator/"); + } + + @Test + void toAnyEndpointWhenBasePathIsEmptyShouldNotMatchLinks() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); + assertMatcher.doesNotMatch("/"); + assertMatcher.matches("/foo"); + assertMatcher.matches("/bar"); + } + + @Test + void toAnyEndpointShouldNotMatchOtherPath() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher).doesNotMatch("/actuator/baz"); + } + + @Test + void toEndpointClassShouldMatchEndpointPath() { + ServerWebExchangeMatcher matcher = EndpointRequest.to(FooEndpoint.class); + assertMatcher(matcher).matches("/actuator/foo"); + assertMatcher(matcher).matches("/actuator/foo/"); + } + + @Test + void toEndpointClassShouldNotMatchOtherPath() { + ServerWebExchangeMatcher matcher = EndpointRequest.to(FooEndpoint.class); + assertMatcher(matcher).doesNotMatch("/actuator/bar"); + assertMatcher(matcher).doesNotMatch("/actuator/bar/"); + } + + @Test + void toEndpointIdShouldMatchEndpointPath() { + ServerWebExchangeMatcher matcher = EndpointRequest.to("foo"); + assertMatcher(matcher).matches("/actuator/foo"); + assertMatcher(matcher).matches("/actuator/foo/"); + } + + @Test + void toEndpointIdShouldNotMatchOtherPath() { + ServerWebExchangeMatcher matcher = EndpointRequest.to("foo"); + assertMatcher(matcher).doesNotMatch("/actuator/bar"); + assertMatcher(matcher).doesNotMatch("/actuator/bar/"); + } + + @Test + void toLinksShouldOnlyMatchLinks() { + ServerWebExchangeMatcher matcher = EndpointRequest.toLinks(); + assertMatcher(matcher).doesNotMatch("/actuator/foo"); + assertMatcher(matcher).doesNotMatch("/actuator/bar"); + assertMatcher(matcher).matches("/actuator"); + assertMatcher(matcher).matches("/actuator/"); + } + + @Test + void toLinksWhenBasePathEmptyShouldNotMatch() { + ServerWebExchangeMatcher matcher = EndpointRequest.toLinks(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); + assertMatcher.doesNotMatch("/actuator/foo"); + assertMatcher.doesNotMatch("/actuator/bar"); + assertMatcher.doesNotMatch("/"); + } + + @Test + void excludeByClassShouldNotMatchExcluded() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint() + .excluding(FooEndpoint.class, BazServletEndpoint.class); + List> endpoints = new ArrayList<>(); + endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo")); + endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar")); + endpoints.add(mockEndpoint(EndpointId.of("baz"), "baz")); + PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator", () -> endpoints); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo"); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo/"); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz"); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz/"); + assertMatcher(matcher).matches("/actuator/bar"); + assertMatcher(matcher).matches("/actuator/bar/"); + assertMatcher(matcher).matches("/actuator"); + assertMatcher(matcher).matches("/actuator/"); + } + + @Test + void excludeByClassShouldNotMatchLinksIfExcluded() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint() + .excludingLinks() + .excluding(FooEndpoint.class); + assertMatcher(matcher).doesNotMatch("/actuator/foo"); + assertMatcher(matcher).doesNotMatch("/actuator/foo/"); + assertMatcher(matcher).doesNotMatch("/actuator"); + assertMatcher(matcher).doesNotMatch("/actuator/"); + } + + @Test + void excludeByIdShouldNotMatchExcluded() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("foo"); + assertMatcher(matcher).doesNotMatch("/actuator/foo"); + assertMatcher(matcher).doesNotMatch("/actuator/foo/"); + assertMatcher(matcher).matches("/actuator/bar"); + assertMatcher(matcher).matches("/actuator/bar/"); + assertMatcher(matcher).matches("/actuator"); + assertMatcher(matcher).matches("/actuator/"); + } + + @Test + void excludeByIdShouldNotMatchLinksIfExcluded() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks().excluding("foo"); + assertMatcher(matcher).doesNotMatch("/actuator/foo"); + assertMatcher(matcher).doesNotMatch("/actuator/foo/"); + assertMatcher(matcher).doesNotMatch("/actuator"); + assertMatcher(matcher).doesNotMatch("/actuator/"); + } + + @Test + void excludeLinksShouldNotMatchBasePath() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks(); + assertMatcher(matcher).doesNotMatch("/actuator"); + assertMatcher(matcher).doesNotMatch("/actuator/"); + assertMatcher(matcher).matches("/actuator/foo"); + assertMatcher(matcher).matches("/actuator/foo/"); + assertMatcher(matcher).matches("/actuator/bar"); + assertMatcher(matcher).matches("/actuator/bar/"); + } + + @Test + void excludeLinksShouldNotMatchBasePathIfEmptyAndExcluded() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); + assertMatcher.doesNotMatch("/"); + assertMatcher.matches("/foo"); + assertMatcher.matches("/foo/"); + assertMatcher.matches("/bar"); + assertMatcher.matches("/bar/"); + } + + @Test + void noEndpointPathsBeansShouldNeverMatch() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/foo"); + assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/foo/"); + assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/bar"); + assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/bar/"); + } + + @Test + void toStringWhenIncludedEndpoints() { + ServerWebExchangeMatcher matcher = EndpointRequest.to("foo", "bar"); + assertThat(matcher).hasToString("EndpointRequestMatcher includes=[foo, bar], excludes=[], includeLinks=false"); + } + + @Test + void toStringWhenEmptyIncludedEndpoints() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertThat(matcher).hasToString("EndpointRequestMatcher includes=[*], excludes=[], includeLinks=true"); + } + + @Test + void toStringWhenIncludedEndpointsClasses() { + ServerWebExchangeMatcher matcher = EndpointRequest.to(FooEndpoint.class).excluding("bar"); + assertThat(matcher).hasToString("EndpointRequestMatcher includes=[foo], excludes=[bar], includeLinks=false"); + } + + @Test + void toStringWhenIncludedExcludedEndpoints() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("bar").excludingLinks(); + assertThat(matcher).hasToString("EndpointRequestMatcher includes=[*], excludes=[bar], includeLinks=false"); + } + + @Test + void toStringWhenToAdditionalPaths() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "test"); + assertThat(matcher) + .hasToString("AdditionalPathsEndpointServerWebExchangeMatcher endpoints=[test], webServerNamespace=server"); + } + + @Test + void toAnyEndpointWhenEndpointPathMappedToRootIsExcludedShouldNotMatchRoot() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("root"); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("/", () -> List + .of(mockEndpoint(EndpointId.of("root"), "/"), mockEndpoint(EndpointId.of("alpha"), "alpha")))); + assertMatcher.doesNotMatch("/"); + assertMatcher.matches("/alpha"); + assertMatcher.matches("/alpha/sub"); + } + + @Test + void toEndpointWhenEndpointPathMappedToRootShouldMatchRoot() { + ServerWebExchangeMatcher matcher = EndpointRequest.to("root"); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, + new PathMappedEndpoints("/", () -> List.of(mockEndpoint(EndpointId.of("root"), "/")))); + assertMatcher.matches("/"); + } + + @Test + void toAdditionalPathsWithEndpointClassShouldMatchAdditionalPath() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, + FooEndpoint.class); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); + assertMatcher.matches("/additional"); + } + + @Test + void toAdditionalPathsWithEndpointIdShouldMatchAdditionalPath() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "foo"); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); + assertMatcher.matches("/additional"); + } + + @Test + void toAdditionalPathsWithEndpointClassShouldNotMatchOtherPaths() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, + FooEndpoint.class); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); + assertMatcher.doesNotMatch("/foo"); + assertMatcher.doesNotMatch("/bar"); + } + + @Test + void toAdditionalPathsWithEndpointClassShouldNotMatchOtherNamespace() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, + FooEndpoint.class); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional"))), + WebServerNamespace.MANAGEMENT); + assertMatcher.doesNotMatch("/additional"); + } + + private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher) { + return assertMatcher(matcher, mockPathMappedEndpoints("/actuator")); + } + + private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, String basePath) { + return assertMatcher(matcher, mockPathMappedEndpoints(basePath)); + } + + private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, + PathMappedEndpoints pathMappedEndpoints) { + return assertMatcher(matcher, pathMappedEndpoints, null); + } + + private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, + PathMappedEndpoints pathMappedEndpoints, WebServerNamespace namespace) { + StaticApplicationContext context = new StaticApplicationContext(); + if (namespace != null && !WebServerNamespace.SERVER.equals(namespace)) { + NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); + context.setParent(parentContext); + } + context.registerBean(WebEndpointProperties.class); + if (pathMappedEndpoints != null) { + context.registerBean(PathMappedEndpoints.class, () -> pathMappedEndpoints); + WebEndpointProperties properties = context.getBean(WebEndpointProperties.class); + if (!properties.getBasePath().equals(pathMappedEndpoints.getBasePath())) { + properties.setBasePath(pathMappedEndpoints.getBasePath()); + } + } + return assertThat(new RequestMatcherAssert(context, matcher)); + } + + private PathMappedEndpoints mockPathMappedEndpoints(String basePath) { + List> endpoints = new ArrayList<>(); + endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo")); + endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar")); + return new PathMappedEndpoints(basePath, () -> endpoints); + } + + private TestEndpoint mockEndpoint(EndpointId id, String rootPath) { + return mockEndpoint(id, rootPath, WebServerNamespace.SERVER); + } + + private TestEndpoint mockEndpoint(EndpointId id, String rootPath, WebServerNamespace webServerNamespace, + String... additionalPaths) { + TestEndpoint endpoint = mock(TestEndpoint.class); + given(endpoint.getEndpointId()).willReturn(id); + given(endpoint.getRootPath()).willReturn(rootPath); + given(endpoint.getAdditionalPaths(webServerNamespace)).willReturn(Arrays.asList(additionalPaths)); + return endpoint; + } + + static class NamedStaticWebApplicationContext extends StaticWebApplicationContext + implements WebServerApplicationContext { + + private final WebServerNamespace webServerNamespace; + + NamedStaticWebApplicationContext(WebServerNamespace webServerNamespace) { + this.webServerNamespace = webServerNamespace; + } + + @Override + public WebServer getWebServer() { + return null; + } + + @Override + public String getServerNamespace() { + return (this.webServerNamespace != null) ? this.webServerNamespace.getValue() : null; + } + + } + + static class RequestMatcherAssert implements AssertDelegateTarget { + + private final StaticApplicationContext context; + + private final ServerWebExchangeMatcher matcher; + + RequestMatcherAssert(StaticApplicationContext context, ServerWebExchangeMatcher matcher) { + this.context = context; + this.matcher = matcher; + } + + void matches(String path) { + ServerWebExchange exchange = webHandler().createExchange(MockServerHttpRequest.get(path).build(), + new MockServerHttpResponse()); + matches(exchange); + } + + void matches(HttpMethod httpMethod, String path) { + ServerWebExchange exchange = webHandler() + .createExchange(MockServerHttpRequest.method(httpMethod, path).build(), new MockServerHttpResponse()); + matches(exchange); + } + + private void matches(ServerWebExchange exchange) { + assertThat(this.matcher.matches(exchange).block(Duration.ofSeconds(30)).isMatch()) + .as("Matches " + getRequestPath(exchange)) + .isTrue(); + } + + void doesNotMatch(String path) { + ServerWebExchange exchange = webHandler().createExchange(MockServerHttpRequest.get(path).build(), + new MockServerHttpResponse()); + doesNotMatch(exchange); + } + + void doesNotMatch(HttpMethod httpMethod, String path) { + ServerWebExchange exchange = webHandler() + .createExchange(MockServerHttpRequest.method(httpMethod, path).build(), new MockServerHttpResponse()); + doesNotMatch(exchange); + } + + private void doesNotMatch(ServerWebExchange exchange) { + assertThat(this.matcher.matches(exchange).block(Duration.ofSeconds(30)).isMatch()) + .as("Does not match " + getRequestPath(exchange)) + .isFalse(); + } + + private TestHttpWebHandlerAdapter webHandler() { + TestHttpWebHandlerAdapter adapter = new TestHttpWebHandlerAdapter(mock(WebHandler.class)); + adapter.setApplicationContext(this.context); + return adapter; + } + + private String getRequestPath(ServerWebExchange exchange) { + return exchange.getRequest().getPath().toString(); + } + + } + + static class TestHttpWebHandlerAdapter extends HttpWebHandlerAdapter { + + TestHttpWebHandlerAdapter(WebHandler delegate) { + super(delegate); + } + + @Override + protected ServerWebExchange createExchange(ServerHttpRequest request, ServerHttpResponse response) { + return super.createExchange(request, response); + } + + } + + @Endpoint(id = "foo") + static class FooEndpoint { + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "baz") + @SuppressWarnings("removal") + static class BazServletEndpoint { + + } + + interface TestEndpoint extends ExposableEndpoint, PathMappedEndpoint { + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/ReactiveManagementWebSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/ReactiveManagementWebSecurityAutoConfigurationTests.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/ReactiveManagementWebSecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/ReactiveManagementWebSecurityAutoConfigurationTests.java index 159c872352ea..003424471a3e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/ReactiveManagementWebSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/reactive/ReactiveManagementWebSecurityAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.reactive; +package org.springframework.boot.security.autoconfigure.actuate.reactive; import java.net.URI; import java.time.Duration; @@ -27,15 +27,15 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; @@ -68,10 +68,11 @@ class ReactiveManagementWebSecurityAutoConfigurationTests { private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, - HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class, - WebFluxAutoConfiguration.class, EnvironmentEndpointAutoConfiguration.class, - EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ReactiveSecurityAutoConfiguration.class, ReactiveManagementWebSecurityAutoConfiguration.class)); + HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + InfoEndpointAutoConfiguration.class, WebFluxAutoConfiguration.class, + EnvironmentEndpointAutoConfiguration.class, EndpointAutoConfiguration.class, + WebEndpointAutoConfiguration.class, ReactiveSecurityAutoConfiguration.class, + ReactiveManagementWebSecurityAutoConfiguration.class)); @Test void permitAllForHealth() { @@ -143,14 +144,6 @@ void backsOffIfCustomSecurityIsAdded() { }); } - @Test - void backOffIfReactiveOAuth2ResourceServerAutoConfigurationPresent() { - this.contextRunner.withConfiguration(AutoConfigurations.of(ReactiveOAuth2ResourceServerAutoConfiguration.class)) - .withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://authserver") - .run((context) -> assertThat(context) - .doesNotHaveBean(ReactiveManagementWebSecurityAutoConfiguration.class)); - } - @Test void backsOffWhenWebFilterChainProxyBeanPresent() { this.contextRunner.withUserConfiguration(WebFilterChainProxyConfiguration.class).run((context) -> { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/AbstractEndpointRequestIntegrationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/AbstractEndpointRequestIntegrationTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/AbstractEndpointRequestIntegrationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/AbstractEndpointRequestIntegrationTests.java index 0cb8fd1e2a16..6aac6a359c35 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/AbstractEndpointRequestIntegrationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/AbstractEndpointRequestIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.actuate.servlet; import java.io.IOException; import java.time.Duration; @@ -34,11 +34,11 @@ import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; diff --git a/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/EndpointRequestTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/EndpointRequestTests.java new file mode 100644 index 000000000000..c266d69727bc --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/EndpointRequestTests.java @@ -0,0 +1,466 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.actuate.servlet; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import jakarta.servlet.http.HttpServletRequest; +import org.assertj.core.api.AssertDelegateTarget; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.ExposableEndpoint; +import org.springframework.boot.actuate.endpoint.Operation; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; +import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest.AdditionalPathsEndpointRequestMatcher; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest.EndpointRequestMatcher; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.http.HttpMethod; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockServletContext; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.StaticWebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link EndpointRequest}. + * + * @author Phillip Webb + * @author Madhura Bhave + * @author Chris Bono + */ +class EndpointRequestTests { + + @Test + void toAnyEndpointShouldMatchEndpointPath() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher, "/actuator").matches("/actuator/foo"); + assertMatcher(matcher, "/actuator").matches("/actuator/foo/zoo/"); + assertMatcher(matcher, "/actuator").matches("/actuator/bar"); + assertMatcher(matcher, "/actuator").matches("/actuator/bar/baz"); + assertMatcher(matcher, "/actuator").matches("/actuator"); + } + + @Test + void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() { + EndpointRequest.EndpointRequestMatcher matcher = EndpointRequest.toAnyEndpoint() + .withHttpMethod(HttpMethod.POST); + assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/foo"); + assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo"); + } + + @Test + void toAnyEndpointShouldMatchEndpointPathWithTrailingSlash() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher, "/actuator").matches("/actuator/foo/"); + assertMatcher(matcher, "/actuator").matches("/actuator/bar/"); + assertMatcher(matcher, "/actuator").matches("/actuator/"); + } + + @Test + void toAnyEndpointWhenBasePathIsEmptyShouldNotMatchLinks() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); + assertMatcher.doesNotMatch("/"); + assertMatcher.matches("/foo"); + assertMatcher.matches("/bar"); + } + + @Test + void toAnyEndpointShouldNotMatchOtherPath() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher).doesNotMatch("/actuator/baz"); + } + + @Test + void toAnyEndpointWhenDispatcherServletPathProviderNotAvailableUsesEmptyPath() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher, "/actuator").matches("/actuator/foo"); + assertMatcher(matcher, "/actuator").matches("/actuator/bar"); + assertMatcher(matcher, "/actuator").matches("/actuator"); + assertMatcher(matcher, "/actuator").doesNotMatch("/actuator/baz"); + } + + @Test + void toEndpointClassShouldMatchEndpointPath() { + RequestMatcher matcher = EndpointRequest.to(FooEndpoint.class); + assertMatcher(matcher).matches("/actuator/foo"); + } + + @Test + void toEndpointClassShouldNotMatchOtherPath() { + RequestMatcher matcher = EndpointRequest.to(FooEndpoint.class); + assertMatcher(matcher).doesNotMatch("/actuator/bar"); + assertMatcher(matcher).doesNotMatch("/actuator"); + } + + @Test + void toEndpointIdShouldMatchEndpointPath() { + RequestMatcher matcher = EndpointRequest.to("foo"); + assertMatcher(matcher).matches("/actuator/foo"); + } + + @Test + void toEndpointIdShouldNotMatchOtherPath() { + RequestMatcher matcher = EndpointRequest.to("foo"); + assertMatcher(matcher).doesNotMatch("/actuator/bar"); + assertMatcher(matcher).doesNotMatch("/actuator"); + } + + @Test + void toLinksShouldOnlyMatchLinks() { + RequestMatcher matcher = EndpointRequest.toLinks(); + assertMatcher(matcher).doesNotMatch("/actuator/foo"); + assertMatcher(matcher).doesNotMatch("/actuator/bar"); + assertMatcher(matcher).matches("/actuator"); + assertMatcher(matcher).matches("/actuator/"); + } + + @Test + void toLinksWhenBasePathEmptyShouldNotMatch() { + RequestMatcher matcher = EndpointRequest.toLinks(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); + assertMatcher.doesNotMatch("/actuator/foo"); + assertMatcher.doesNotMatch("/actuator/bar"); + assertMatcher.doesNotMatch("/"); + } + + @Test + void excludeByClassShouldNotMatchExcluded() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding(FooEndpoint.class, BazServletEndpoint.class); + List> endpoints = new ArrayList<>(); + endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo")); + endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar")); + endpoints.add(mockEndpoint(EndpointId.of("baz"), "baz")); + PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator", () -> endpoints); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo"); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz"); + assertMatcher(matcher).matches("/actuator/bar"); + assertMatcher(matcher).matches("/actuator"); + } + + @Test + void excludeByClassShouldNotMatchLinksIfExcluded() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks().excluding(FooEndpoint.class); + assertMatcher(matcher).doesNotMatch("/actuator/foo"); + assertMatcher(matcher).doesNotMatch("/actuator"); + } + + @Test + void excludeByIdShouldNotMatchExcluded() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("foo"); + assertMatcher(matcher).doesNotMatch("/actuator/foo"); + assertMatcher(matcher).matches("/actuator/bar"); + assertMatcher(matcher).matches("/actuator"); + } + + @Test + void excludeByIdShouldNotMatchLinksIfExcluded() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks().excluding("foo"); + assertMatcher(matcher).doesNotMatch("/actuator/foo"); + assertMatcher(matcher).doesNotMatch("/actuator"); + } + + @Test + void excludeLinksShouldNotMatchBasePath() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks(); + assertMatcher(matcher).doesNotMatch("/actuator"); + assertMatcher(matcher).matches("/actuator/foo"); + assertMatcher(matcher).matches("/actuator/bar"); + } + + @Test + void excludeLinksShouldNotMatchBasePathIfEmptyAndExcluded() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excludingLinks(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, ""); + assertMatcher.doesNotMatch("/"); + assertMatcher.matches("/foo"); + assertMatcher.matches("/bar"); + } + + @Test + void endpointRequestMatcherShouldUseCustomRequestMatcherProvider() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + RequestMatcher mockRequestMatcher = (request) -> false; + RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), + (pattern, method) -> mockRequestMatcher, null); + assertMatcher.doesNotMatch("/foo"); + assertMatcher.doesNotMatch("/bar"); + } + + @Test + void linksRequestMatcherShouldUseCustomRequestMatcherProvider() { + RequestMatcher matcher = EndpointRequest.toLinks(); + RequestMatcher mockRequestMatcher = (request) -> false; + RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints("/actuator"), + (pattern, method) -> mockRequestMatcher, null); + assertMatcher.doesNotMatch("/actuator"); + } + + @Test + void noEndpointPathsBeansShouldNeverMatch() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/foo"); + assertMatcher(matcher, (PathMappedEndpoints) null).doesNotMatch("/actuator/bar"); + } + + @Test + void toStringWhenIncludedEndpoints() { + RequestMatcher matcher = EndpointRequest.to("foo", "bar"); + assertThat(matcher).hasToString("EndpointRequestMatcher includes=[foo, bar], excludes=[], includeLinks=false"); + } + + @Test + void toStringWhenEmptyIncludedEndpoints() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + assertThat(matcher).hasToString("EndpointRequestMatcher includes=[*], excludes=[], includeLinks=true"); + } + + @Test + void toStringWhenIncludedEndpointsClasses() { + RequestMatcher matcher = EndpointRequest.to(FooEndpoint.class).excluding("bar"); + assertThat(matcher).hasToString("EndpointRequestMatcher includes=[foo], excludes=[bar], includeLinks=false"); + } + + @Test + void toStringWhenIncludedExcludedEndpoints() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("bar").excludingLinks(); + assertThat(matcher).hasToString("EndpointRequestMatcher includes=[*], excludes=[bar], includeLinks=false"); + } + + @Test + void toStringWhenToAdditionalPaths() { + RequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, "test"); + assertThat(matcher) + .hasToString("AdditionalPathsEndpointRequestMatcher endpoints=[test], webServerNamespace=server"); + } + + @Test + void toAnyEndpointWhenEndpointPathMappedToRootIsExcludedShouldNotMatchRoot() { + EndpointRequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("root"); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", () -> List + .of(mockEndpoint(EndpointId.of("root"), "/"), mockEndpoint(EndpointId.of("alpha"), "alpha")))); + assertMatcher.doesNotMatch("/"); + assertMatcher.matches("/alpha"); + assertMatcher.matches("/alpha/sub"); + } + + @Test + void toEndpointWhenEndpointPathMappedToRootShouldMatchRoot() { + EndpointRequestMatcher matcher = EndpointRequest.to("root"); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, + new PathMappedEndpoints("", () -> List.of(mockEndpoint(EndpointId.of("root"), "/")))); + assertMatcher.matches("/"); + } + + @Test + void toAdditionalPathsWithEndpointClassShouldMatchAdditionalPath() { + AdditionalPathsEndpointRequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, + FooEndpoint.class); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); + assertMatcher.matches("/additional"); + } + + @Test + void toAdditionalPathsWithEndpointIdShouldMatchAdditionalPath() { + AdditionalPathsEndpointRequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, + "foo"); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); + assertMatcher.matches("/additional"); + } + + @Test + void toAdditionalPathsWithEndpointClassShouldNotMatchOtherPaths() { + AdditionalPathsEndpointRequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, + FooEndpoint.class); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); + assertMatcher.doesNotMatch("/foo"); + assertMatcher.doesNotMatch("/bar"); + } + + @Test + void toAdditionalPathsWithEndpointClassShouldNotMatchOtherNamespace() { + AdditionalPathsEndpointRequestMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER, + FooEndpoint.class); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional"))), + null, WebServerNamespace.MANAGEMENT); + assertMatcher.doesNotMatch("/additional"); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher) { + return assertMatcher(matcher, mockPathMappedEndpoints("/actuator")); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String basePath) { + return assertMatcher(matcher, mockPathMappedEndpoints(basePath), null, null); + } + + private PathMappedEndpoints mockPathMappedEndpoints(String basePath) { + List> endpoints = new ArrayList<>(); + endpoints.add(mockEndpoint(EndpointId.of("foo"), "foo")); + endpoints.add(mockEndpoint(EndpointId.of("bar"), "bar")); + return new PathMappedEndpoints(basePath, () -> endpoints); + } + + private TestEndpoint mockEndpoint(EndpointId id, String rootPath) { + return mockEndpoint(id, rootPath, WebServerNamespace.SERVER); + } + + private TestEndpoint mockEndpoint(EndpointId id, String rootPath, WebServerNamespace webServerNamespace, + String... additionalPaths) { + TestEndpoint endpoint = mock(TestEndpoint.class); + given(endpoint.getEndpointId()).willReturn(id); + given(endpoint.getRootPath()).willReturn(rootPath); + given(endpoint.getAdditionalPaths(webServerNamespace)).willReturn(Arrays.asList(additionalPaths)); + return endpoint; + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher, PathMappedEndpoints pathMappedEndpoints) { + return assertMatcher(matcher, pathMappedEndpoints, null, null); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher, PathMappedEndpoints pathMappedEndpoints, + RequestMatcherProvider matcherProvider, WebServerNamespace namespace) { + StaticWebApplicationContext context = new StaticWebApplicationContext(); + if (namespace != null && !WebServerNamespace.SERVER.equals(namespace)) { + NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); + context.setParent(parentContext); + } + context.registerBean(WebEndpointProperties.class); + if (pathMappedEndpoints != null) { + context.registerBean(PathMappedEndpoints.class, () -> pathMappedEndpoints); + WebEndpointProperties properties = context.getBean(WebEndpointProperties.class); + if (!properties.getBasePath().equals(pathMappedEndpoints.getBasePath())) { + properties.setBasePath(pathMappedEndpoints.getBasePath()); + } + } + if (matcherProvider != null) { + context.registerBean(RequestMatcherProvider.class, () -> matcherProvider); + } + return assertThat(new RequestMatcherAssert(context, matcher)); + } + + static class NamedStaticWebApplicationContext extends StaticWebApplicationContext + implements WebServerApplicationContext { + + private final WebServerNamespace webServerNamespace; + + NamedStaticWebApplicationContext(WebServerNamespace webServerNamespace) { + this.webServerNamespace = webServerNamespace; + } + + @Override + public WebServer getWebServer() { + return null; + } + + @Override + public String getServerNamespace() { + return (this.webServerNamespace != null) ? this.webServerNamespace.getValue() : null; + } + + } + + static class RequestMatcherAssert implements AssertDelegateTarget { + + private final WebApplicationContext context; + + private final RequestMatcher matcher; + + RequestMatcherAssert(WebApplicationContext context, RequestMatcher matcher) { + this.context = context; + this.matcher = matcher; + } + + void matches(String servletPath) { + matches(mockRequest(null, servletPath)); + } + + void matches(HttpMethod httpMethod, String servletPath) { + matches(mockRequest(httpMethod, servletPath)); + } + + private void matches(HttpServletRequest request) { + assertThat(this.matcher.matches(request)).as("Matches " + getRequestPath(request)).isTrue(); + } + + void doesNotMatch(String requestUri) { + doesNotMatch(mockRequest(null, requestUri)); + } + + void doesNotMatch(HttpMethod httpMethod, String requestUri) { + doesNotMatch(mockRequest(httpMethod, requestUri)); + } + + private void doesNotMatch(HttpServletRequest request) { + assertThat(this.matcher.matches(request)).as("Does not match " + getRequestPath(request)).isFalse(); + } + + private MockHttpServletRequest mockRequest(HttpMethod httpMethod, String requestUri) { + MockServletContext servletContext = new MockServletContext(); + servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); + MockHttpServletRequest request = new MockHttpServletRequest(servletContext); + if (requestUri != null) { + request.setRequestURI(requestUri); + } + if (httpMethod != null) { + request.setMethod(httpMethod.name()); + } + return request; + } + + private String getRequestPath(HttpServletRequest request) { + String url = request.getServletPath(); + if (request.getPathInfo() != null) { + url += request.getPathInfo(); + } + return url; + } + + } + + @Endpoint(id = "foo") + static class FooEndpoint { + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "baz") + @SuppressWarnings("removal") + static class BazServletEndpoint { + + } + + interface TestEndpoint extends ExposableEndpoint, PathMappedEndpoint { + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/JerseyEndpointRequestIntegrationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/JerseyEndpointRequestIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/JerseyEndpointRequestIntegrationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/JerseyEndpointRequestIntegrationTests.java index ce2e417e991f..d1e0701943ef 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/JerseyEndpointRequestIntegrationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/JerseyEndpointRequestIntegrationTests.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.actuate.servlet; import org.glassfish.jersey.server.ResourceConfig; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/ManagementWebSecurityAutoConfigurationTests.java similarity index 79% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/ManagementWebSecurityAutoConfigurationTests.java index 45b963bfb395..804b6decad96 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/ManagementWebSecurityAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.actuate.servlet; import java.io.IOException; import java.util.List; @@ -25,22 +25,20 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.security.autoconfigure.SecurityProperties; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; -import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; @@ -72,10 +70,10 @@ class ManagementWebSecurityAutoConfigurationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(contextSupplier(), WebServerApplicationContext.class) .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, - HealthEndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class, - EnvironmentEndpointAutoConfiguration.class, EndpointAutoConfiguration.class, - WebMvcAutoConfiguration.class, WebEndpointAutoConfiguration.class, SecurityAutoConfiguration.class, - ManagementWebSecurityAutoConfiguration.class)); + HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + InfoEndpointAutoConfiguration.class, EnvironmentEndpointAutoConfiguration.class, + EndpointAutoConfiguration.class, WebMvcAutoConfiguration.class, WebEndpointAutoConfiguration.class, + SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class)); private static Supplier contextSupplier() { return WebApplicationContextRunner.withMockServletContext(MockWebServerApplicationContext::new); @@ -135,27 +133,6 @@ void backsOffIfSecurityFilterChainBeanIsPresent() { }); } - @Test - void backOffIfOAuth2ResourceServerAutoConfigurationPresent() { - this.contextRunner.withConfiguration(AutoConfigurations.of(OAuth2ResourceServerAutoConfiguration.class)) - .withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://authserver") - .run((context) -> assertThat(context).doesNotHaveBean(ManagementWebSecurityAutoConfiguration.class) - .doesNotHaveBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN)); - } - - @Test - @WithPackageResources("saml-certificate") - void backOffIfSaml2RelyingPartyAutoConfigurationPresent() { - this.contextRunner.withConfiguration(AutoConfigurations.of(Saml2RelyingPartyAutoConfiguration.class)) - .withPropertyValues( - "spring.security.saml2.relyingparty.registration.simplesamlphp.assertingparty.single-sign-on.url=https://simplesaml-for-spring-saml/SSOService.php", - "spring.security.saml2.relyingparty.registration.simplesamlphp.assertingparty.single-sign-on.sign-request=false", - "spring.security.saml2.relyingparty.registration.simplesamlphp.assertingparty.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - "spring.security.saml2.relyingparty.registration.simplesamlphp.assertingparty.verification.credentials[0].certificate-location=classpath:saml-certificate") - .run((context) -> assertThat(context).doesNotHaveBean(ManagementWebSecurityAutoConfiguration.class) - .doesNotHaveBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN)); - } - @Test void backOffIfRemoteDevToolsSecurityFilterChainIsPresent() { this.contextRunner.withUserConfiguration(TestRemoteDevToolsSecurityFilterChainConfig.class).run((context) -> { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/MvcEndpointRequestIntegrationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/MvcEndpointRequestIntegrationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/MvcEndpointRequestIntegrationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/MvcEndpointRequestIntegrationTests.java index b656612922b5..a53624695826 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/MvcEndpointRequestIntegrationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/MvcEndpointRequestIntegrationTests.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.actuate.servlet; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.web.reactive.server.WebTestClient; @@ -122,14 +122,14 @@ void toAnyEndpointWhenServletPathSetShouldMatchServletEndpoint() { @Override protected WebApplicationContextRunner createContextRunner() { return new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) - .withUserConfiguration(WebMvcEndpointConfiguration.class) + .withUserConfiguration(InfrastructureTestConfiguration.class) .withConfiguration(AutoConfigurations.of(DispatcherServletAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class)); } @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(WebEndpointProperties.class) - static class WebMvcEndpointConfiguration { + static class InfrastructureTestConfiguration { @Bean TomcatServletWebServerFactory tomcat() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/SecurityRequestMatchersManagementContextConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfigurationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/SecurityRequestMatchersManagementContextConfigurationTests.java index 2f9cd4c0480e..819f2e692ea9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/SecurityRequestMatchersManagementContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/servlet/SecurityRequestMatchersManagementContextConfigurationTests.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.actuate.servlet; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.web.util.matcher.RequestMatcher; diff --git a/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/jpa/City.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/jpa/City.java new file mode 100644 index 000000000000..2cd042dc9e2c --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/jpa/City.java @@ -0,0 +1,78 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.jpa; + +import java.io.Serializable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + @Column(nullable = false) + private String country; + + @Column(nullable = false) + private String map; + + protected City() { + } + + public City(String name, String state, String country, String map) { + this.name = name; + this.state = state; + this.country = country; + this.map = map; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/jpa/JpaUserDetailsTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/jpa/JpaUserDetailsTests.java similarity index 84% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/jpa/JpaUserDetailsTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/jpa/JpaUserDetailsTests.java index 31e017292e15..819ef2d32b48 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/jpa/JpaUserDetailsTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/jpa/JpaUserDetailsTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.jpa; +package org.springframework.boot.security.autoconfigure.jpa; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.EmbeddedDataSourceConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.context.SpringBootContextLoader; import org.springframework.context.annotation.Import; import org.springframework.test.annotation.DirtiesContext; diff --git a/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/PathRequestTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/PathRequestTests.java new file mode 100644 index 000000000000..419dc5a59c16 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/PathRequestTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.reactive; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link PathRequest}. + * + * @author Madhura Bhave + */ +class PathRequestTests { + + @Test + void toStaticResourcesShouldReturnStaticResourceRequest() { + assertThat(PathRequest.toStaticResources()).isInstanceOf(StaticResourceRequest.class); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveSecurityAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveSecurityAutoConfigurationTests.java index 30ed3e3feeef..d47ea67e3a16 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveSecurityAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.reactive; +package org.springframework.boot.security.autoconfigure.reactive; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveUserDetailsServiceAutoConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveUserDetailsServiceAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveUserDetailsServiceAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveUserDetailsServiceAutoConfigurationTests.java index e998a218dd07..d330e2dd7b9a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveUserDetailsServiceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveUserDetailsServiceAutoConfigurationTests.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.reactive; +package org.springframework.boot.security.autoconfigure.reactive; import java.time.Duration; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration; -import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.rsocket.autoconfigure.RSocketMessagingAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketStrategiesAutoConfiguration; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/StaticResourceRequestTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/StaticResourceRequestTests.java new file mode 100644 index 000000000000..552cbedccd94 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/reactive/StaticResourceRequestTests.java @@ -0,0 +1,156 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.reactive; + +import java.time.Duration; + +import org.assertj.core.api.AssertDelegateTarget; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.security.autoconfigure.StaticResourceLocation; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.http.server.reactive.MockServerHttpResponse; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; +import org.springframework.web.context.support.StaticWebApplicationContext; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebHandler; +import org.springframework.web.server.adapter.HttpWebHandlerAdapter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link StaticResourceRequest}. + * + * @author Madhura Bhave + */ +class StaticResourceRequestTests { + + private final StaticResourceRequest resourceRequest = StaticResourceRequest.INSTANCE; + + @Test + void atCommonLocationsShouldMatchCommonLocations() { + ServerWebExchangeMatcher matcher = this.resourceRequest.atCommonLocations(); + assertMatcher(matcher).matches("/css/file.css"); + assertMatcher(matcher).matches("/js/file.js"); + assertMatcher(matcher).matches("/images/file.css"); + assertMatcher(matcher).matches("/webjars/file.css"); + assertMatcher(matcher).matches("/favicon.ico"); + assertMatcher(matcher).matches("/favicon.png"); + assertMatcher(matcher).matches("/icons/icon-48x48.png"); + assertMatcher(matcher).doesNotMatch("/bar"); + } + + @Test + void atCommonLocationsWithExcludeShouldNotMatchExcluded() { + ServerWebExchangeMatcher matcher = this.resourceRequest.atCommonLocations() + .excluding(StaticResourceLocation.CSS); + assertMatcher(matcher).doesNotMatch("/css/file.css"); + assertMatcher(matcher).matches("/js/file.js"); + } + + @Test + void atLocationShouldMatchLocation() { + ServerWebExchangeMatcher matcher = this.resourceRequest.at(StaticResourceLocation.CSS); + assertMatcher(matcher).matches("/css/file.css"); + assertMatcher(matcher).doesNotMatch("/js/file.js"); + } + + @Test + void atLocationsFromSetWhenSetIsNullShouldThrowException() { + assertThatIllegalArgumentException().isThrownBy(() -> this.resourceRequest.at(null)) + .withMessageContaining("'locations' must not be null"); + } + + @Test + void excludeFromSetWhenSetIsNullShouldThrowException() { + assertThatIllegalArgumentException().isThrownBy(() -> this.resourceRequest.atCommonLocations().excluding(null)) + .withMessageContaining("'locations' must not be null"); + } + + private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher) { + StaticWebApplicationContext context = new StaticWebApplicationContext(); + context.registerBean(ServerProperties.class); + return assertThat(new RequestMatcherAssert(context, matcher)); + } + + static class RequestMatcherAssert implements AssertDelegateTarget { + + private final StaticApplicationContext context; + + private final ServerWebExchangeMatcher matcher; + + RequestMatcherAssert(StaticApplicationContext context, ServerWebExchangeMatcher matcher) { + this.context = context; + this.matcher = matcher; + } + + void matches(String path) { + ServerWebExchange exchange = webHandler().createExchange(MockServerHttpRequest.get(path).build(), + new MockServerHttpResponse()); + matches(exchange); + } + + private void matches(ServerWebExchange exchange) { + assertThat(this.matcher.matches(exchange).block(Duration.ofSeconds(30)).isMatch()) + .as("Matches " + getRequestPath(exchange)) + .isTrue(); + } + + void doesNotMatch(String path) { + ServerWebExchange exchange = webHandler().createExchange(MockServerHttpRequest.get(path).build(), + new MockServerHttpResponse()); + doesNotMatch(exchange); + } + + private void doesNotMatch(ServerWebExchange exchange) { + assertThat(this.matcher.matches(exchange).block(Duration.ofSeconds(30)).isMatch()) + .as("Does not match " + getRequestPath(exchange)) + .isFalse(); + } + + private TestHttpWebHandlerAdapter webHandler() { + TestHttpWebHandlerAdapter adapter = new TestHttpWebHandlerAdapter(mock(WebHandler.class)); + adapter.setApplicationContext(this.context); + return adapter; + } + + private String getRequestPath(ServerWebExchange exchange) { + return exchange.getRequest().getPath().toString(); + } + + } + + static class TestHttpWebHandlerAdapter extends HttpWebHandlerAdapter { + + TestHttpWebHandlerAdapter(WebHandler delegate) { + super(delegate); + } + + @Override + protected ServerWebExchange createExchange(ServerHttpRequest request, ServerHttpResponse response) { + return super.createExchange(request, response); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/rsocket/RSocketSecurityAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/rsocket/RSocketSecurityAutoConfigurationTests.java index a74351e5027a..4f22319706ab 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/rsocket/RSocketSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/rsocket/RSocketSecurityAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.rsocket; +package org.springframework.boot.security.autoconfigure.rsocket; import io.rsocket.core.RSocketServer; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration; -import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketMessagingAutoConfiguration; +import org.springframework.boot.rsocket.autoconfigure.RSocketStrategiesAutoConfiguration; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/PathRequestTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/PathRequestTests.java new file mode 100644 index 000000000000..b110e461838e --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/PathRequestTests.java @@ -0,0 +1,117 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.servlet; + +import jakarta.servlet.http.HttpServletRequest; +import org.assertj.core.api.AssertDelegateTarget; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.h2console.autoconfigure.H2ConsoleProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockServletContext; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.StringUtils; +import org.springframework.web.context.WebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link PathRequest}. + * + * @author Madhura Bhave + */ +class PathRequestTests { + + @Test + void toStaticResourcesShouldReturnStaticResourceRequest() { + assertThat(PathRequest.toStaticResources()).isInstanceOf(StaticResourceRequest.class); + } + + @Test + void toH2ConsoleShouldMatchH2ConsolePath() { + RequestMatcher matcher = PathRequest.toH2Console(); + assertMatcher(matcher).matches("/h2-console"); + assertMatcher(matcher).matches("/h2-console/subpath"); + assertMatcher(matcher).doesNotMatch("/js/file.js"); + } + + @Test + void toH2ConsoleWhenManagementContextShouldNeverMatch() { + RequestMatcher matcher = PathRequest.toH2Console(); + assertMatcher(matcher, "management").doesNotMatch("/h2-console"); + assertMatcher(matcher, "management").doesNotMatch("/h2-console/subpath"); + assertMatcher(matcher, "management").doesNotMatch("/js/file.js"); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher) { + return assertMatcher(matcher, null); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String serverNamespace) { + TestWebApplicationContext context = new TestWebApplicationContext(serverNamespace); + context.registerBean(ServerProperties.class); + context.registerBean(H2ConsoleProperties.class); + return assertThat(new RequestMatcherAssert(context, matcher)); + } + + static class RequestMatcherAssert implements AssertDelegateTarget { + + private final WebApplicationContext context; + + private final RequestMatcher matcher; + + RequestMatcherAssert(WebApplicationContext context, RequestMatcher matcher) { + this.context = context; + this.matcher = matcher; + } + + void matches(String path) { + matches(mockRequest(path)); + } + + private void matches(HttpServletRequest request) { + assertThat(this.matcher.matches(request)).as("Matches " + getRequestPath(request)).isTrue(); + } + + void doesNotMatch(String path) { + doesNotMatch(mockRequest(path)); + } + + private void doesNotMatch(HttpServletRequest request) { + assertThat(this.matcher.matches(request)).as("Does not match " + getRequestPath(request)).isFalse(); + } + + private MockHttpServletRequest mockRequest(String path) { + MockServletContext servletContext = new MockServletContext(); + servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); + MockHttpServletRequest request = new MockHttpServletRequest(servletContext); + request.setRequestURI(path); + return request; + } + + private String getRequestPath(HttpServletRequest request) { + String url = request.getServletPath(); + if (StringUtils.hasText(request.getRequestURI())) { + url += request.getRequestURI(); + } + return url; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityAutoConfigurationTests.java index 978ff034ce4c..6d501cbace84 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.servlet; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -30,19 +30,19 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.security.jpa.City; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.convert.ApplicationConversionService; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.security.autoconfigure.jpa.City; +import org.springframework.boot.servlet.filter.OrderedFilter; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; -import org.springframework.boot.web.servlet.filter.OrderedFilter; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java index 475617511574..8308cf76de32 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.servlet; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -29,18 +29,18 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.test.client.TestRestTemplate; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -59,13 +59,13 @@ * @author Phillip Webb */ @ExtendWith(OutputCaptureExtension.class) +@DirtiesUrlFactories class SecurityFilterAutoConfigurationEarlyInitializationTests { private static final Pattern PASSWORD_PATTERN = Pattern.compile("^Using generated security password: (.*)$", Pattern.MULTILINE); @Test - @DirtiesUrlFactories @ClassPathExclusions({ "spring-security-oauth2-client-*.jar", "spring-security-oauth2-resource-server-*.jar", "spring-security-saml2-service-provider-*.jar" }) void testSecurityFilterDoesNotCauseEarlyInitialization(CapturedOutput output) { diff --git a/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfigurationTests.java new file mode 100644 index 000000000000..8779cada15ff --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityFilterAutoConfigurationTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.servlet; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.ConverterBean; +import org.springframework.boot.security.autoconfigure.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.DeserializerBean; +import org.springframework.boot.security.autoconfigure.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.ExampleController; +import org.springframework.boot.security.autoconfigure.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.JacksonModuleBean; +import org.springframework.boot.servlet.filter.OrderedRequestContextFilter; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.mock.web.MockServletContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SecurityFilterAutoConfiguration}. + * + * @author Andy Wilkinson + */ +class SecurityFilterAutoConfigurationTests { + + @Test + void filterAutoConfigurationWorksWithoutSecurityAutoConfiguration() { + try (AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext()) { + context.setServletContext(new MockServletContext()); + context.register(Config.class); + context.refresh(); + } + } + + @Test + void filterIsOrderedShortlyAfterRequestContextFilter() { + try (AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext()) { + context.setServletContext(new MockServletContext()); + context.register(SecurityAutoConfiguration.class); + context.register(Config.class); + context.refresh(); + int securityFilterOrder = context.getBean(DelegatingFilterProxyRegistrationBean.class).getOrder(); + int requestContextFilterOrder = new OrderedRequestContextFilter().getOrder(); + assertThat(securityFilterOrder).isGreaterThan(requestContextFilterOrder) + .isCloseTo(requestContextFilterOrder, Assertions.within(5)); + } + } + + @Configuration(proxyBeanMethods = false) + @Import({ DeserializerBean.class, JacksonModuleBean.class, ExampleController.class, ConverterBean.class }) + @ImportAutoConfiguration({ WebMvcAutoConfiguration.class, JacksonAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + SecurityFilterAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) + static class Config { + + } + +} diff --git a/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/StaticResourceRequestTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/StaticResourceRequestTests.java new file mode 100644 index 000000000000..9576b2babbb1 --- /dev/null +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/StaticResourceRequestTests.java @@ -0,0 +1,178 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.security.autoconfigure.servlet; + +import jakarta.servlet.http.HttpServletRequest; +import org.assertj.core.api.AssertDelegateTarget; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.security.autoconfigure.StaticResourceLocation; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockServletContext; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.StringUtils; +import org.springframework.web.context.WebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +/** + * Tests for {@link StaticResourceRequest}. + * + * @author Madhura Bhave + * @author Phillip Webb + */ +class StaticResourceRequestTests { + + private final StaticResourceRequest resourceRequest = StaticResourceRequest.INSTANCE; + + @Test + void atCommonLocationsShouldMatchCommonLocations() { + RequestMatcher matcher = this.resourceRequest.atCommonLocations(); + assertMatcher(matcher).matches("/css/file.css"); + assertMatcher(matcher).matches("/js/file.js"); + assertMatcher(matcher).matches("/images/file.css"); + assertMatcher(matcher).matches("/webjars/file.css"); + assertMatcher(matcher).matches("/favicon.ico"); + assertMatcher(matcher).matches("/favicon.png"); + assertMatcher(matcher).matches("/icons/icon-48x48.png"); + assertMatcher(matcher).doesNotMatch("/bar"); + } + + @Test + void atCommonLocationsWhenManagementContextShouldNeverMatch() { + RequestMatcher matcher = this.resourceRequest.atCommonLocations(); + assertMatcher(matcher, "management").doesNotMatch("/css/file.css"); + assertMatcher(matcher, "management").doesNotMatch("/js/file.js"); + assertMatcher(matcher, "management").doesNotMatch("/images/file.css"); + assertMatcher(matcher, "management").doesNotMatch("/webjars/file.css"); + assertMatcher(matcher, "management").doesNotMatch("/foo/favicon.ico"); + } + + @Test + void atCommonLocationsWithExcludeShouldNotMatchExcluded() { + RequestMatcher matcher = this.resourceRequest.atCommonLocations().excluding(StaticResourceLocation.CSS); + assertMatcher(matcher).doesNotMatch("/css/file.css"); + assertMatcher(matcher).matches("/js/file.js"); + } + + @Test + void atLocationShouldMatchLocation() { + RequestMatcher matcher = this.resourceRequest.at(StaticResourceLocation.CSS); + assertMatcher(matcher).matches("/css/file.css"); + assertMatcher(matcher).doesNotMatch("/js/file.js"); + } + + @Test + void atLocationWhenHasServletPathShouldMatchLocation() { + RequestMatcher matcher = this.resourceRequest.at(StaticResourceLocation.CSS); + assertMatcher(matcher, null, "/foo").matches("/foo", "/css/file.css"); + assertMatcher(matcher, null, "/foo").doesNotMatch("/foo", "/js/file.js"); + } + + @Test + void atLocationsFromSetWhenSetIsNullShouldThrowException() { + assertThatIllegalArgumentException().isThrownBy(() -> this.resourceRequest.at(null)) + .withMessageContaining("'locations' must not be null"); + } + + @Test + void excludeFromSetWhenSetIsNullShouldThrowException() { + assertThatIllegalArgumentException().isThrownBy(() -> this.resourceRequest.atCommonLocations().excluding(null)) + .withMessageContaining("'locations' must not be null"); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher) { + return assertMatcher(matcher, null, ""); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String serverNamespace) { + return assertMatcher(matcher, serverNamespace, ""); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String serverNamespace, String path) { + DispatcherServletPath dispatcherServletPath = () -> path; + TestWebApplicationContext context = new TestWebApplicationContext(serverNamespace); + context.registerBean(DispatcherServletPath.class, () -> dispatcherServletPath); + return assertThat(new RequestMatcherAssert(context, matcher)); + } + + static class RequestMatcherAssert implements AssertDelegateTarget { + + private final WebApplicationContext context; + + private final RequestMatcher matcher; + + RequestMatcherAssert(WebApplicationContext context, RequestMatcher matcher) { + this.context = context; + this.matcher = matcher; + } + + void matches(String path) { + matches(mockRequest(path)); + } + + void matches(String servletPath, String path) { + matches(mockRequest(servletPath, path)); + } + + private void matches(HttpServletRequest request) { + assertThat(this.matcher.matches(request)).as("Matches " + getRequestPath(request)).isTrue(); + } + + void doesNotMatch(String path) { + doesNotMatch(mockRequest(path)); + } + + void doesNotMatch(String servletPath, String path) { + doesNotMatch(mockRequest(servletPath, path)); + } + + private void doesNotMatch(HttpServletRequest request) { + assertThat(this.matcher.matches(request)).as("Does not match " + getRequestPath(request)).isFalse(); + } + + private MockHttpServletRequest mockRequest(String path) { + return mockRequest(null, path); + } + + private MockHttpServletRequest mockRequest(String servletPath, String path) { + MockServletContext servletContext = new MockServletContext(); + servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); + MockHttpServletRequest request = new MockHttpServletRequest(servletContext); + if (servletPath != null) { + request.setServletPath(servletPath); + request.setRequestURI(servletPath + path); + } + else { + request.setRequestURI(path); + } + return request; + } + + private String getRequestPath(HttpServletRequest request) { + String url = request.getServletPath(); + if (StringUtils.hasText(request.getRequestURI())) { + url += request.getRequestURI(); + } + return url; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/TestWebApplicationContext.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/TestWebApplicationContext.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/TestWebApplicationContext.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/TestWebApplicationContext.java index 97b250a3985d..78917412f0d9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/TestWebApplicationContext.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/TestWebApplicationContext.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.servlet; -import org.springframework.boot.web.context.WebServerApplicationContext; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerApplicationContext; import org.springframework.web.context.support.StaticWebApplicationContext; /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/UserDetailsServiceAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/UserDetailsServiceAutoConfigurationTests.java index 9271d2ae76ef..1436ba904919 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/UserDetailsServiceAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.security.servlet; +package org.springframework.boot.security.autoconfigure.servlet; import java.util.Collections; import java.util.function.Function; @@ -31,9 +31,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcome; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcomes; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; -import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration.MissingAlternativeOrUserPropertiesConfigured; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.security.autoconfigure.SecurityProperties; +import org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration.MissingAlternativeOrUserPropertiesConfigured; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.AbstractApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcherTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcherTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcherTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/reactive/ApplicationContextServerWebExchangeMatcherTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcherTests.java b/spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcherTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcherTests.java rename to spring-boot-project/spring-boot-security/src/test/java/org/springframework/boot/security/servlet/ApplicationContextRequestMatcherTests.java diff --git a/spring-boot-project/spring-boot-sendgrid/build.gradle b/spring-boot-project/spring-boot-sendgrid/build.gradle new file mode 100644 index 000000000000..d318d283b4eb --- /dev/null +++ b/spring-boot-project/spring-boot-sendgrid/build.gradle @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot SendGrid" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("com.sendgrid:sendgrid-java") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfiguration.java b/spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/SendGridAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfiguration.java rename to spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/SendGridAutoConfiguration.java index e406e06ac4b7..5d4b7320429c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfiguration.java +++ b/spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/SendGridAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sendgrid; +package org.springframework.boot.sendgrid.autoconfigure; import com.sendgrid.Client; import com.sendgrid.SendGrid; @@ -36,7 +36,7 @@ * @author Maciej Walkowiak * @author Patrick Bray * @author Andy Wilkinson - * @since 1.3.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(SendGrid.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridProperties.java b/spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/SendGridProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridProperties.java rename to spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/SendGridProperties.java index 8027fc544b08..6d79cc132459 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridProperties.java +++ b/spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/SendGridProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sendgrid; +package org.springframework.boot.sendgrid.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -23,7 +23,7 @@ * * @author Maciej Walkowiak * @author Andy Wilkinson - * @since 1.3.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.sendgrid") public class SendGridProperties { diff --git a/spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/package-info.java b/spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/package-info.java new file mode 100644 index 000000000000..35239ab01d1a --- /dev/null +++ b/spring-boot-project/spring-boot-sendgrid/src/main/java/org/springframework/boot/sendgrid/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for SendGrid. + */ +package org.springframework.boot.sendgrid.autoconfigure; diff --git a/spring-boot-project/spring-boot-sendgrid/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-sendgrid/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..b9f4adc626f7 --- /dev/null +++ b/spring-boot-project/spring-boot-sendgrid/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.sendgrid.autoconfigure.SendGridAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfigurationTests.java b/spring-boot-project/spring-boot-sendgrid/src/test/java/org/springframework/boot/sendgrid/autoconfigure/SendGridAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfigurationTests.java rename to spring-boot-project/spring-boot-sendgrid/src/test/java/org/springframework/boot/sendgrid/autoconfigure/SendGridAutoConfigurationTests.java index abd9b26f5ad0..b9da6cc4cd13 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-sendgrid/src/test/java/org/springframework/boot/sendgrid/autoconfigure/SendGridAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sendgrid; +package org.springframework.boot.sendgrid.autoconfigure; import com.sendgrid.SendGrid; import org.apache.http.impl.conn.DefaultProxyRoutePlanner; diff --git a/spring-boot-project/spring-boot-servlet/build.gradle b/spring-boot-project/spring-boot-servlet/build.gradle new file mode 100644 index 000000000000..d08f63784700 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/build.gradle @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Servlet" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-web") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-web-server")) + optional("jakarta.servlet:jakarta.servlet-api") + optional("org.springframework.security:spring-security-config") + + testImplementation(project(":spring-boot-project:spring-boot-jetty")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-undertow")) + testImplementation("org.springframework:spring-webmvc") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("org.apache.httpcomponents.client5:httpclient5") +} + +tasks.named("test") { + jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/MultipartConfigFactory.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/MultipartConfigFactory.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/MultipartConfigFactory.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/MultipartConfigFactory.java index 4f6d031c77b1..cfe76fe92eea 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/MultipartConfigFactory.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/MultipartConfigFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.servlet; import jakarta.servlet.MultipartConfigElement; @@ -24,7 +24,7 @@ * Factory that can be used to create a {@link MultipartConfigElement}. * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 */ public class MultipartConfigFactory { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilter.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilter.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilter.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilter.java index b02537214aeb..8b82c9938e4a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilter.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import java.io.IOException; import java.net.URI; @@ -43,7 +43,7 @@ * @author Andy Wilkinson * @author Venil Noronha * @author Madhura Bhave - * @since 3.0.0 + * @since 4.0.0 */ public class HttpExchangesFilter extends OncePerRequestFilter implements Ordered { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequest.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequest.java index 20ec61db570c..aaefc148da4c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequest.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import java.net.URI; import java.net.URISyntaxException; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpResponse.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpResponse.java index f6cfb7ed4e95..2666dbf112c1 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpResponse.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import java.util.ArrayList; import java.util.LinkedHashMap; diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/package-info.java new file mode 100644 index 000000000000..dce4f92c9ec5 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/exchanges/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator HTTP exchanges support for Servlet servers. + * + * @see org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository + */ +package org.springframework.boot.servlet.actuate.exchanges; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FilterRegistrationMappingDescription.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/FilterRegistrationMappingDescription.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FilterRegistrationMappingDescription.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/FilterRegistrationMappingDescription.java index 86bda7a209b6..0766b4f21476 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FilterRegistrationMappingDescription.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/FilterRegistrationMappingDescription.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.servlet.actuate.mappings; import java.util.Collection; @@ -24,7 +24,7 @@ * A {@link RegistrationMappingDescription} derived from a {@link FilterRegistration}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class FilterRegistrationMappingDescription extends RegistrationMappingDescription { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProvider.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/FiltersMappingDescriptionProvider.java similarity index 91% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProvider.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/FiltersMappingDescriptionProvider.java index b50e05f5bdbf..5e6cb27cf918 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProvider.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/FiltersMappingDescriptionProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.servlet.actuate.mappings; import java.util.Collections; import java.util.List; @@ -26,7 +26,7 @@ import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.FiltersMappingDescriptionProvider.FiltersMappingDescriptionProviderRuntimeHints; +import org.springframework.boot.servlet.actuate.mappings.FiltersMappingDescriptionProvider.FiltersMappingDescriptionProviderRuntimeHints; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.web.context.WebApplicationContext; @@ -36,7 +36,7 @@ * Filters} registered with a {@link ServletContext}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(FiltersMappingDescriptionProviderRuntimeHints.class) public class FiltersMappingDescriptionProvider implements MappingDescriptionProvider { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/RegistrationMappingDescription.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/RegistrationMappingDescription.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/RegistrationMappingDescription.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/RegistrationMappingDescription.java index c95e1bd7c679..a11228f17b94 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/RegistrationMappingDescription.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/RegistrationMappingDescription.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.servlet.actuate.mappings; import jakarta.servlet.Registration; @@ -23,7 +23,7 @@ * * @param type of the registration * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class RegistrationMappingDescription { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletRegistrationMappingDescription.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/ServletRegistrationMappingDescription.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletRegistrationMappingDescription.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/ServletRegistrationMappingDescription.java index 9af8548aeddc..364957a53eb3 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletRegistrationMappingDescription.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/ServletRegistrationMappingDescription.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.servlet.actuate.mappings; import java.util.Collection; @@ -24,7 +24,7 @@ * A mapping description derived from a {@link ServletRegistration}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class ServletRegistrationMappingDescription extends RegistrationMappingDescription { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProvider.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/ServletsMappingDescriptionProvider.java similarity index 91% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProvider.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/ServletsMappingDescriptionProvider.java index 0f87777cc9ae..1fa32fe3051c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProvider.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/ServletsMappingDescriptionProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.servlet.actuate.mappings; import java.util.Collections; import java.util.List; @@ -26,7 +26,7 @@ import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider.ServletsMappingDescriptionProviderRuntimeHints; +import org.springframework.boot.servlet.actuate.mappings.ServletsMappingDescriptionProvider.ServletsMappingDescriptionProviderRuntimeHints; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.web.context.WebApplicationContext; @@ -36,7 +36,7 @@ * Servlets} registered with a {@link ServletContext}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(ServletsMappingDescriptionProviderRuntimeHints.class) public class ServletsMappingDescriptionProvider implements MappingDescriptionProvider { diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/package-info.java new file mode 100644 index 000000000000..18de59bf6401 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/actuate/mappings/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator servlet request mappings support. + */ +package org.springframework.boot.servlet.actuate.mappings; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfiguration.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/HttpEncodingAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfiguration.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/HttpEncodingAutoConfiguration.java index 377bcf6c0015..bde8ad0314e6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/HttpEncodingAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.servlet.autoconfigure; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -23,7 +23,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter; +import org.springframework.boot.servlet.filter.OrderedCharacterEncodingFilter; import org.springframework.context.annotation.Bean; import org.springframework.web.filter.CharacterEncodingFilter; @@ -33,7 +33,7 @@ * * @author Stephane Nicoll * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration @EnableConfigurationProperties(ServletEncodingProperties.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfiguration.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfiguration.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfiguration.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfiguration.java index fb5136ac2191..3dbbed019005 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfiguration.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.servlet.autoconfigure; import jakarta.servlet.MultipartConfigElement; import jakarta.servlet.Servlet; @@ -27,18 +27,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.StandardServletMultipartResolver; -import org.springframework.web.servlet.DispatcherServlet; /** * {@link EnableAutoConfiguration Auto-configuration} for multipart uploads. Adds a * {@link StandardServletMultipartResolver} if none is present, and adds a * {@link jakarta.servlet.MultipartConfigElement multipartConfigElement} if none is - * otherwise defined. The {@link ServletWebServerApplicationContext} will associate the - * {@link MultipartConfigElement} bean to any {@link Servlet} beans. + * otherwise defined. *

* The {@link jakarta.servlet.MultipartConfigElement} is a Servlet API that's used to * configure how the server handles file uploads. @@ -47,7 +44,7 @@ * @author Josh Long * @author Toshiaki Maki * @author Yanming Zhou - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class }) @@ -56,6 +53,12 @@ @EnableConfigurationProperties(MultipartProperties.class) public class MultipartAutoConfiguration { + /** + * Well-known name for the MultipartResolver object in the bean factory for this + * namespace. + */ + private static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver"; + private final MultipartProperties multipartProperties; public MultipartAutoConfiguration(MultipartProperties multipartProperties) { @@ -68,7 +71,7 @@ public MultipartConfigElement multipartConfigElement() { return this.multipartProperties.createMultipartConfig(); } - @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) + @Bean(name = MULTIPART_RESOLVER_BEAN_NAME) @ConditionalOnMissingBean(MultipartResolver.class) public StandardServletMultipartResolver multipartResolver() { StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/MultipartProperties.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/MultipartProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/MultipartProperties.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/MultipartProperties.java index 725e103b29bd..aecac5dca7f5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/MultipartProperties.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/MultipartProperties.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.servlet.autoconfigure; import jakarta.servlet.MultipartConfigElement; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.servlet.MultipartConfigFactory; +import org.springframework.boot.servlet.MultipartConfigFactory; import org.springframework.util.unit.DataSize; /** @@ -44,7 +44,7 @@ * @author Toshiaki Maki * @author Stephane Nicoll * @author Yanming Zhou - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties(prefix = "spring.servlet.multipart", ignoreUnknownFields = false) public class MultipartProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletEncodingProperties.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/ServletEncodingProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletEncodingProperties.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/ServletEncodingProperties.java index 206ff2a34f51..89c535ab1875 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletEncodingProperties.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/ServletEncodingProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.servlet.autoconfigure; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletHttpExchangesAutoConfiguration.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletHttpExchangesAutoConfiguration.java new file mode 100644 index 000000000000..f7667949994d --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletHttpExchangesAutoConfiguration.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate; + +import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesProperties; +import org.springframework.boot.actuate.web.exchanges.HttpExchange; +import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.servlet.actuate.exchanges.HttpExchangesFilter; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} to record {@link HttpExchange HTTP + * exchanges}. + * + * @author Dave Syer + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnBooleanProperty(name = "management.httpexchanges.recording.enabled", matchIfMissing = true) +@ConditionalOnBean(HttpExchangeRepository.class) +@EnableConfigurationProperties(HttpExchangesProperties.class) +public class ServletHttpExchangesAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + HttpExchangesFilter httpExchangesFilter(HttpExchangeRepository repository, HttpExchangesProperties properties) { + return new HttpExchangesFilter(repository, properties.getRecording().getInclude()); + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletMappingsAutoConfiguration.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletMappingsAutoConfiguration.java new file mode 100644 index 000000000000..51f33ab1e93a --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletMappingsAutoConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; +import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.servlet.actuate.mappings.FiltersMappingDescriptionProvider; +import org.springframework.boot.servlet.actuate.mappings.ServletsMappingDescriptionProvider; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} to describe Servlet-related + * {@link MappingDescriptionProvider mappings}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ConditionalOnAvailableEndpoint.class, MappingsEndpoint.class }) +@ConditionalOnAvailableEndpoint(MappingsEndpoint.class) +@ConditionalOnWebApplication(type = Type.SERVLET) +public class ServletMappingsAutoConfiguration { + + @Bean + ServletsMappingDescriptionProvider servletMappingDescriptionProvider() { + return new ServletsMappingDescriptionProvider(); + } + + @Bean + FiltersMappingDescriptionProvider filterMappingDescriptionProvider() { + return new FiltersMappingDescriptionProvider(); + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/package-info.java new file mode 100644 index 000000000000..2f7a54b2aa2f --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator Servlet support. + */ +package org.springframework.boot.servlet.autoconfigure.actuate; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementServletContext.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ManagementServletContext.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementServletContext.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ManagementServletContext.java index 11f95d73a688..fbe444579e15 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementServletContext.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ManagementServletContext.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.servlet.autoconfigure.actuate.web; /** * Provides information about the management servlet context for MVC controllers to use. * * @author Phillip Webb * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface ManagementServletContext { diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletEndpointManagementContextConfiguration.java new file mode 100644 index 000000000000..eeef21ea971a --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletEndpointManagementContextConfiguration.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate.web; + +import org.springframework.boot.actuate.autoconfigure.endpoint.expose.IncludeExcludeEndpointFilter; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for servlet + * endpoints. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Madhura Bhave + * @since 4.0.0 + */ +@ManagementContextConfiguration(proxyBeanMethods = false) +@ConditionalOnWebApplication(type = Type.SERVLET) +public class ServletEndpointManagementContextConfiguration { + + @Bean + @SuppressWarnings("removal") + public IncludeExcludeEndpointFilter servletExposeExcludePropertyEndpointFilter( + WebEndpointProperties properties) { + WebEndpointProperties.Exposure exposure = properties.getExposure(); + return new IncludeExcludeEndpointFilter<>( + org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint.class, exposure.getInclude(), + exposure.getExclude()); + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementChildContextConfiguration.java new file mode 100644 index 000000000000..7cacf754c078 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementChildContextConfiguration.java @@ -0,0 +1,79 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate.web; + +import jakarta.servlet.Filter; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.HierarchicalBeanFactory; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.autoconfigure.condition.SearchStrategy; +import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.BeanIds; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Servlet web + * endpoint infrastructure when a separate management context with a web server running on + * a different port is required. + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Eddú Meléndez + * @author Phillip Webb + * @author Moritz Halbritter + */ +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +@ConditionalOnWebApplication(type = Type.SERVLET) +class ServletManagementChildContextConfiguration { + + @Bean + ServletManagementWebServerFactoryCustomizer servletManagementWebServerFactoryCustomizer( + ListableBeanFactory beanFactory) { + return new ServletManagementWebServerFactoryCustomizer(beanFactory); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ EnableWebSecurity.class, Filter.class }) + @ConditionalOnBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN, search = SearchStrategy.ANCESTORS) + static class ServletManagementContextSecurityConfiguration { + + @Bean + Filter springSecurityFilterChain(HierarchicalBeanFactory beanFactory) { + BeanFactory parent = beanFactory.getParentBeanFactory(); + return parent.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN, Filter.class); + } + + @Bean + @ConditionalOnBean(name = "securityFilterChainRegistration", search = SearchStrategy.ANCESTORS) + DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(HierarchicalBeanFactory beanFactory) { + return beanFactory.getParentBeanFactory() + .getBean("securityFilterChainRegistration", DelegatingFilterProxyRegistrationBean.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementContextAutoConfiguration.java new file mode 100644 index 000000000000..51b85c9af94d --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementContextAutoConfiguration.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate.web; + +import jakarta.servlet.Servlet; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.servlet.filter.ApplicationContextHeaderFilter; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Servlet-specific management + * context concerns. + * + * @author Phillip Webb + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ Servlet.class, WebEndpointProperties.class }) +@ConditionalOnWebApplication(type = Type.SERVLET) +@EnableConfigurationProperties(WebEndpointProperties.class) +public class ServletManagementContextAutoConfiguration { + + @Bean + public ManagementServletContext managementServletContext(WebEndpointProperties properties) { + return properties::getBasePath; + } + + // Put Servlets and Filters in their own nested class so they don't force early + // instantiation of ManagementServerProperties. + @Configuration(proxyBeanMethods = false) + @ConditionalOnBooleanProperty("management.server.add-application-context-header") + protected static class ApplicationContextFilterConfiguration { + + @Bean + public ApplicationContextHeaderFilter applicationContextIdFilter(ApplicationContext context) { + return new ApplicationContextHeaderFilter(context); + } + + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..fdbf63680d16 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementWebServerFactoryCustomizer.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate.web; + +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.util.StringUtils; + +/** + * {@link ManagementWebServerFactoryCustomizer} for a servlet web server. + * + * @author Andy Wilkinson + */ +class ServletManagementWebServerFactoryCustomizer + extends ManagementWebServerFactoryCustomizer { + + ServletManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory) { + super(beanFactory); + } + + @Override + protected void customize(ConfigurableServletWebServerFactory webServerFactory, + ManagementServerProperties managementServerProperties, ServerProperties serverProperties) { + super.customize(webServerFactory, managementServerProperties, serverProperties); + webServerFactory.setContextPath(getContextPath(managementServerProperties)); + } + + private String getContextPath(ManagementServerProperties managementServerProperties) { + String basePath = managementServerProperties.getBasePath(); + return StringUtils.hasText(basePath) ? basePath : ""; + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/package-info.java new file mode 100644 index 000000000000..a2aaffb08537 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/actuate/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for {@code jakarta.servlet} actuator web concerns. + */ +package org.springframework.boot.servlet.autoconfigure.actuate.web; diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/package-info.java new file mode 100644 index 000000000000..69a68f58580d --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/autoconfigure/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for application support of the {@code jakarta.servlet} + * specification. + */ +package org.springframework.boot.servlet.autoconfigure; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/ApplicationContextHeaderFilter.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/ApplicationContextHeaderFilter.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/ApplicationContextHeaderFilter.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/ApplicationContextHeaderFilter.java index da58d911b4b5..a4f899fdf694 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/ApplicationContextHeaderFilter.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/ApplicationContextHeaderFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.filter; +package org.springframework.boot.servlet.filter; import java.io.IOException; @@ -32,7 +32,7 @@ * * @author Phillip Webb * @author Venil Noronha - * @since 2.0.0 + * @since 4.0.0 */ public class ApplicationContextHeaderFilter extends OncePerRequestFilter { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedCharacterEncodingFilter.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedCharacterEncodingFilter.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedCharacterEncodingFilter.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedCharacterEncodingFilter.java index ddf29c1b9084..7dfb4000b87c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedCharacterEncodingFilter.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedCharacterEncodingFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.filter; +package org.springframework.boot.servlet.filter; import org.springframework.core.Ordered; import org.springframework.web.filter.CharacterEncodingFilter; @@ -23,7 +23,7 @@ * {@link CharacterEncodingFilter} that also implements {@link Ordered}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ public class OrderedCharacterEncodingFilter extends CharacterEncodingFilter implements OrderedFilter { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFilter.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedFilter.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFilter.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedFilter.java index ef1b3d0f5eb2..d556d007cd8d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFilter.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.filter; +package org.springframework.boot.servlet.filter; import jakarta.servlet.Filter; @@ -24,7 +24,7 @@ * An {@link Ordered} {@link jakarta.servlet.Filter}. * * @author Phillip Webb - * @since 2.1.0 + * @since 4.0.0 */ public interface OrderedFilter extends Filter, Ordered { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFormContentFilter.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedFormContentFilter.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFormContentFilter.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedFormContentFilter.java index c285a64a9ffa..6db5b237180d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedFormContentFilter.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedFormContentFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.filter; +package org.springframework.boot.servlet.filter; import org.springframework.core.Ordered; import org.springframework.web.filter.FormContentFilter; @@ -24,7 +24,7 @@ * * @author Joao Pedro Evangelista * @author Brian Clozel - * @since 2.1.0 + * @since 4.0.0 */ public class OrderedFormContentFilter extends FormContentFilter implements OrderedFilter { diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedHiddenHttpMethodFilter.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedHiddenHttpMethodFilter.java new file mode 100644 index 000000000000..08dbbbb70ab0 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedHiddenHttpMethodFilter.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.filter; + +import org.springframework.core.Ordered; +import org.springframework.web.filter.HiddenHttpMethodFilter; + +/** + * {@link HiddenHttpMethodFilter} that also implements {@link Ordered}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter implements OrderedFilter { + + /** + * The default order is high to ensure the filter is applied before Spring Security. + */ + public static final int DEFAULT_ORDER = REQUEST_WRAPPER_FILTER_MAX_ORDER - 10000; + + private int order = DEFAULT_ORDER; + + @Override + public int getOrder() { + return this.order; + } + + /** + * Set the order for this filter. + * @param order the order to set + */ + public void setOrder(int order) { + this.order = order; + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedRequestContextFilter.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedRequestContextFilter.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedRequestContextFilter.java rename to spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedRequestContextFilter.java index c9c02205a9bd..17a677b861dc 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedRequestContextFilter.java +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/OrderedRequestContextFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.filter; +package org.springframework.boot.servlet.filter; import org.springframework.core.Ordered; import org.springframework.web.filter.RequestContextFilter; @@ -23,7 +23,7 @@ * {@link RequestContextFilter} that also implements {@link Ordered}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ public class OrderedRequestContextFilter extends RequestContextFilter implements OrderedFilter { diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/package-info.java new file mode 100644 index 000000000000..c7c2b1ac032f --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/filter/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring Boot specific {@link jakarta.servlet.Filter} implementations. + */ +package org.springframework.boot.servlet.filter; diff --git a/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/package-info.java b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/package-info.java new file mode 100644 index 000000000000..2ab8c421218d --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/java/org/springframework/boot/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Application support for the {@code jakarta.servlet} specification. + */ +package org.springframework.boot.servlet; diff --git a/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..78428c95f43e --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,79 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.http.encoding.charset", + "type": "java.nio.charset.Charset", + "description": "Charset of HTTP requests and responses. Added to the Content-Type header if not set explicitly.", + "deprecation": { + "replacement": "server.servlet.encoding.charset", + "level": "error" + } + }, + { + "name": "spring.http.encoding.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable http encoding support.", + "defaultValue": true, + "deprecation": { + "replacement": "server.servlet.encoding.enabled", + "level": "error" + } + }, + { + "name": "spring.http.encoding.force", + "type": "java.lang.Boolean", + "description": "Whether to force the encoding to the configured charset on HTTP requests and responses.", + "defaultValue": false, + "deprecation": { + "replacement": "server.servlet.encoding.force", + "level": "error" + } + }, + { + "name": "spring.http.encoding.force-request", + "type": "java.lang.Boolean", + "description": "Whether to force the encoding to the configured charset on HTTP requests. Defaults to true when force has not been specified.", + "defaultValue": true, + "deprecation": { + "replacement": "server.servlet.encoding.force-request", + "level": "error" + } + }, + { + "name": "spring.http.encoding.force-response", + "type": "java.lang.Boolean", + "description": "Whether to force the encoding to the configured charset on HTTP responses.", + "defaultValue": false, + "deprecation": { + "replacement": "server.servlet.encoding.force-response", + "level": "error" + } + }, + { + "name": "spring.http.encoding.mapping", + "type": "java.util.Map", + "description": "Locale in which to encode mapping.", + "deprecation": { + "replacement": "server.servlet.encoding.mapping", + "level": "error" + } + }, + { + "name": "spring.http.log-request-details", + "type": "java.lang.Boolean", + "description": "Whether logging of (potentially sensitive) request details at DEBUG and TRACE level is allowed.", + "defaultValue": false, + "deprecation": { + "replacement": "spring.mvc.log-request-details", + "level": "error" + } + }, + { + "name": "spring.servlet.encoding.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Servlet HTTP encoding support.", + "defaultValue": true + } + ] +} diff --git a/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..b5310b4e654f --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.servlet.autoconfigure.actuate.web.ServletEndpointManagementContextConfiguration +org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementChildContextConfiguration diff --git a/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..e1c2a52afa2d --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,5 @@ +org.springframework.boot.servlet.autoconfigure.HttpEncodingAutoConfiguration +org.springframework.boot.servlet.autoconfigure.MultipartAutoConfiguration +org.springframework.boot.servlet.autoconfigure.actuate.ServletHttpExchangesAutoConfiguration +org.springframework.boot.servlet.autoconfigure.actuate.ServletMappingsAutoConfiguration +org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/MultipartConfigFactoryTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/MultipartConfigFactoryTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/MultipartConfigFactoryTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/MultipartConfigFactoryTests.java index 68a3ce72b9a8..810addccd405 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/MultipartConfigFactoryTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/MultipartConfigFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.servlet; import jakarta.servlet.MultipartConfigElement; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilterTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilterTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilterTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilterTests.java index d203e86828aa..9b04520a7a82 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/HttpExchangesFilterTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/HttpExchangesFilterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import java.io.IOException; import java.security.Principal; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequestTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequestTests.java index 361ae1706dc1..53606ecb5a01 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/servlet/RecordableServletHttpRequestTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/exchanges/RecordableServletHttpRequestTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.servlet; +package org.springframework.boot.servlet.actuate.exchanges; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/mappings/FiltersMappingDescriptionProviderTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/mappings/FiltersMappingDescriptionProviderTests.java index 28021ce6cc92..1055e9b48f23 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/mappings/FiltersMappingDescriptionProviderTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.servlet.actuate.mappings; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.web.mappings.servlet.FiltersMappingDescriptionProvider.FiltersMappingDescriptionProviderRuntimeHints; +import org.springframework.boot.servlet.actuate.mappings.FiltersMappingDescriptionProvider.FiltersMappingDescriptionProviderRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/mappings/ServletsMappingDescriptionProviderTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/mappings/ServletsMappingDescriptionProviderTests.java index 57e0654aef10..dfce44aae543 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/actuate/mappings/ServletsMappingDescriptionProviderTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.servlet.actuate.mappings; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider.ServletsMappingDescriptionProviderRuntimeHints; +import org.springframework.boot.servlet.actuate.mappings.ServletsMappingDescriptionProvider.ServletsMappingDescriptionProviderRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfigurationTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/HttpEncodingAutoConfigurationTests.java similarity index 86% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfigurationTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/HttpEncodingAutoConfigurationTests.java index 46ccd8ac9607..0aec3b4258b2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/HttpEncodingAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.servlet.autoconfigure; import java.util.ArrayList; import java.util.List; @@ -24,12 +24,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.boot.servlet.filter.OrderedFormContentFilter; +import org.springframework.boot.servlet.filter.OrderedHiddenHttpMethodFilter; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.boot.web.servlet.filter.OrderedFormContentFilter; -import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter; -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.AnnotationAwareOrderComparator; @@ -140,7 +138,7 @@ private AnnotationConfigServletWebApplicationContext doLoad(Class[] configs, AnnotationConfigServletWebApplicationContext applicationContext = new AnnotationConfigServletWebApplicationContext(); TestPropertyValues.of(environment).applyTo(applicationContext); applicationContext.register(configs); - applicationContext.register(MinimalWebAutoConfiguration.class, HttpEncodingAutoConfiguration.class); + applicationContext.register(HttpEncodingAutoConfiguration.class); applicationContext.setServletContext(new MockServletContext()); applicationContext.refresh(); return applicationContext; @@ -179,19 +177,4 @@ OrderedFormContentFilter formContentFilter() { } - @Configuration(proxyBeanMethods = false) - static class MinimalWebAutoConfiguration { - - @Bean - MockServletWebServerFactory mockServletWebServerFactory() { - return new MockServletWebServerFactory(); - } - - @Bean - static WebServerFactoryCustomizerBeanPostProcessor servletWebServerCustomizerBeanPostProcessor() { - return new WebServerFactoryCustomizerBeanPostProcessor(); - } - - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfigurationTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfigurationTests.java rename to spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfigurationTests.java index 15eabb0a1b76..4aa99d3b955c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/MultipartAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.servlet.autoconfigure; import java.net.URI; import java.util.stream.Stream; @@ -26,15 +26,16 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.testsupport.classpath.ForkedClassPath; import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -263,8 +264,7 @@ WebController controller() { } @Configuration(proxyBeanMethods = false) - @Import({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - MultipartAutoConfiguration.class }) + @Import({ TomcatServletWebServerAutoConfiguration.class, MultipartAutoConfiguration.class }) @EnableConfigurationProperties(MultipartProperties.class) static class BaseConfiguration { @@ -275,6 +275,11 @@ ServerProperties serverProperties() { return properties; } + @Bean + DispatcherServlet dispatcherServlet() { + return new DispatcherServlet(); + } + } @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletHttpExchangesAutoConfigurationTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletHttpExchangesAutoConfigurationTests.java new file mode 100644 index 000000000000..01c1a6bcc396 --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletHttpExchangesAutoConfigurationTests.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate; + +import java.util.EnumSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; +import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; +import org.springframework.boot.actuate.web.exchanges.Include; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.servlet.actuate.exchanges.HttpExchangesFilter; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ServletHttpExchangesAutoConfiguration}. + * + * @author Andy Wilkinson + */ +class ServletHttpExchangesAutoConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ServletHttpExchangesAutoConfiguration.class)); + + @Test + void whenRecordingIsDisabledThenFilterIsNotCreated() { + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class) + .withPropertyValues("management.httpexchanges.recording.enabled=false") + .run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesFilter.class)); + } + + @Test + void whenNoRepositoryIsDefinedThenFilterIsNotCreated() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesFilter.class)); + } + + @Test + void filterIsCreated() { + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class) + .run((context) -> assertThat(context).hasSingleBean(HttpExchangesFilter.class)); + } + + @Test + void usesUserProvidedWebFilter() { + InMemoryHttpExchangeRepository repository = new InMemoryHttpExchangeRepository(); + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class, () -> repository) + .withBean(CustomHttpExchangesFilter.class, + () -> new CustomHttpExchangesFilter(repository, EnumSet.allOf(Include.class))) + .run((context) -> { + assertThat(context).hasSingleBean(HttpExchangesFilter.class); + assertThat(context.getBean(HttpExchangesFilter.class)).isInstanceOf(CustomHttpExchangesFilter.class); + }); + } + + private static final class CustomHttpExchangesFilter extends HttpExchangesFilter { + + private CustomHttpExchangesFilter(HttpExchangeRepository repository, Set includes) { + super(repository, includes); + } + + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletMappingsAutoConfigurationTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletMappingsAutoConfigurationTests.java new file mode 100644 index 000000000000..2347c8a5f6bc --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/ServletMappingsAutoConfigurationTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.servlet.actuate.mappings.FiltersMappingDescriptionProvider; +import org.springframework.boot.servlet.actuate.mappings.ServletsMappingDescriptionProvider; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ServletMappingsAutoConfiguration}. + * + * @author Andy Wilkinson + */ +class ServletMappingsAutoConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ServletMappingsAutoConfiguration.class)); + + @Test + void whenEndpointIsUnavailableThenDescriptionProvidersAreNotCreated() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(FiltersMappingDescriptionProvider.class) + .doesNotHaveBean(ServletsMappingDescriptionProvider.class)); + } + + @Test + void whenEndpointIsAvailableThenDescriptionProvidersAreCreated() { + this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=mappings") + .run((context) -> assertThat(context).hasSingleBean(FiltersMappingDescriptionProvider.class) + .hasSingleBean(ServletsMappingDescriptionProvider.class)); + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementChildContextConfigurationTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementChildContextConfigurationTests.java new file mode 100644 index 000000000000..722cc776c1df --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementChildContextConfigurationTests.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate.web; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ServletManagementChildContextConfiguration}. + * + * @author Moritz Halbritter + */ +class ServletManagementChildContextConfigurationTests { + + @Test // gh-45857 + void doesNotCreateManagementServerPropertiesInChildContext() { + new WebApplicationContextRunner().withBean(ManagementServerProperties.class) + .run((parent) -> new WebApplicationContextRunner().withParent(parent) + .withUserConfiguration(ServletManagementChildContextConfiguration.class) + .run((context) -> assertThat(context.getBean(ManagementServerProperties.class)) + .isSameAs(parent.getBean(ManagementServerProperties.class)))); + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementContextAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementContextAutoConfigurationIntegrationTests.java new file mode 100644 index 000000000000..d94545db823d --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/autoconfigure/actuate/web/ServletManagementContextAutoConfigurationIntegrationTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.autoconfigure.actuate.web; + +import java.util.function.Consumer; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatServletManagementContextAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.util.StringUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link ServletManagementContextAutoConfiguration}. + * + * @author Madhura Bhave + * @author Andy Wilkinson + */ +@ExtendWith(OutputCaptureExtension.class) +class ServletManagementContextAutoConfigurationIntegrationTests { + + @Test + void childManagementContextShouldStartForEmbeddedServer(CapturedOutput output) { + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, + TomcatServletManagementContextAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, + EndpointAutoConfiguration.class)); + contextRunner.withPropertyValues("server.port=0", "management.server.port=0") + .run((context) -> assertThat(output).satisfies(numberOfOccurrences("Tomcat started on port", 2))); + } + + @Test + void childManagementContextShouldNotStartWithoutEmbeddedServer(CapturedOutput output) { + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, + TomcatServletManagementContextAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, + EndpointAutoConfiguration.class)); + contextRunner.withPropertyValues("server.port=0", "management.server.port=0").run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(output).doesNotContain("Tomcat started"); + }); + } + + @Test + void childManagementContextShouldRestartWhenParentIsStoppedThenStarted(CapturedOutput output) { + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, + TomcatServletManagementContextAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, + EndpointAutoConfiguration.class)); + contextRunner.withPropertyValues("server.port=0", "management.server.port=0").run((context) -> { + assertThat(output).satisfies(numberOfOccurrences("Tomcat started on port", 2)); + context.getSourceApplicationContext().stop(); + context.getSourceApplicationContext().start(); + assertThat(output).satisfies(numberOfOccurrences("Tomcat started on port", 4)); + }); + } + + @Test + void givenSamePortManagementServerWhenManagementServerAddressIsConfiguredThenContextRefreshFails() { + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, + WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)); + contextRunner.withPropertyValues("server.port=0", "management.server.address=127.0.0.1") + .run((context) -> assertThat(context).getFailure() + .hasMessageStartingWith("Management-specific server address cannot be configured")); + } + + private Consumer numberOfOccurrences(String substring, int expectedCount) { + return (charSequence) -> { + int count = StringUtils.countOccurrencesOf(charSequence.toString(), substring); + assertThat(count).isEqualTo(expectedCount); + }; + } + +} diff --git a/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/filter/OrderedFilterOrderingTests.java b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/filter/OrderedFilterOrderingTests.java new file mode 100644 index 000000000000..c41a4d2dff3d --- /dev/null +++ b/spring-boot-project/spring-boot-servlet/src/test/java/org/springframework/boot/servlet/filter/OrderedFilterOrderingTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.servlet.filter; + +import java.util.ArrayList; +import java.util.List; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import org.springframework.core.annotation.AnnotationAwareOrderComparator; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the ordering of various {@link OrderedFilter} implementations. + * + * @author Andy Wilkinson + */ +class OrderedFilterOrderingTests { + + @Test + void ordering() { + OrderedCharacterEncodingFilter characterEncoding = new OrderedCharacterEncodingFilter(); + OrderedFormContentFilter formContent = new OrderedFormContentFilter(); + OrderedHiddenHttpMethodFilter hiddenHttpMethod = new OrderedHiddenHttpMethodFilter(); + OrderedRequestContextFilter requestContext = new OrderedRequestContextFilter(); + List filters = new ArrayList<>( + List.of(characterEncoding, formContent, hiddenHttpMethod, requestContext)); + AnnotationAwareOrderComparator.sort(filters); + assertThat(filters).containsExactly(characterEncoding, hiddenHttpMethod, formContent, requestContext); + } + + @Test + void requestContextOrderingIsCloseToRequestWrapperFilterMaxOrder() { + assertThat(new OrderedRequestContextFilter().getOrder()) + .isCloseTo(OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER, Assertions.within(105)); + } + +} diff --git a/spring-boot-project/spring-boot-session-data-mongodb/build.gradle b/spring-boot-project/spring-boot-session-data-mongodb/build.gradle new file mode 100644 index 000000000000..1077ec7da149 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-mongodb/build.gradle @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Session Data MongoDB" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-session")) + api("org.springframework.session:spring-session-data-mongodb") + + implementation(project(":spring-boot-project:spring-boot-data-mongodb")) + implementation(project(":spring-boot-project:spring-boot-web-server")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-webflux")) + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-session"))) + dockerTestImplementation("org.mongodb:mongodb-driver-reactivestreams") + dockerTestImplementation("org.mongodb:mongodb-driver-sync") + dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:mongodb") + + dockerTestRuntimeOnly("ch.qos.logback:logback-classic") + dockerTestRuntimeOnly("jakarta.servlet:jakarta.servlet-api") +} diff --git a/spring-boot-project/spring-boot-session-data-mongodb/src/dockerTest/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoReactiveSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session-data-mongodb/src/dockerTest/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoReactiveSessionAutoConfigurationTests.java new file mode 100644 index 000000000000..2c33a2b65a8d --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-mongodb/src/dockerTest/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoReactiveSessionAutoConfigurationTests.java @@ -0,0 +1,133 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.data.mongodb.autoconfigure; + +import java.time.Duration; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveDataAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration; +import org.springframework.boot.session.autoconfigure.AbstractReactiveSessionAutoConfigurationTests; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.webflux.autoconfigure.WebSessionIdResolverAutoConfiguration; +import org.springframework.http.ResponseCookie; +import org.springframework.session.MapSession; +import org.springframework.session.data.mongo.ReactiveMongoSessionRepository; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the reactive support of {@link MongoSessionAutoConfiguration}. + * + * @author Andy Wilkinson + * @author Weix Sun + */ +@Testcontainers(disabledWithoutDocker = true) +class MongoReactiveSessionAutoConfigurationTests extends AbstractReactiveSessionAutoConfigurationTests { + + @Container + static final MongoDBContainer mongoDb = TestImage.container(MongoDBContainer.class); + + @BeforeEach + void prepareContextRunner() { + this.contextRunner = new ReactiveWebApplicationContextRunner().withConfiguration( + AutoConfigurations.of(SessionAutoConfiguration.class, MongoSessionAutoConfiguration.class, + MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class)); + } + + @Test + void defaultConfig() { + this.contextRunner.withPropertyValues("spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) + .run(validateSpringSessionUsesMongo("sessions")); + } + + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner + .withPropertyValues("spring.session.timeout=1m", "spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) + .run((context) -> { + ReactiveMongoSessionRepository repository = validateSessionRepository(context, + ReactiveMongoSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); + }); + } + + @Test + void defaultConfigWithCustomSessionTimeout() { + this.contextRunner + .withPropertyValues("server.reactive.session.timeout=1m", + "spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) + .run((context) -> { + ReactiveMongoSessionRepository repository = validateSessionRepository(context, + ReactiveMongoSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); + }); + } + + @Test + void mongoSessionStoreWithCustomizations() { + this.contextRunner + .withPropertyValues("spring.session.mongodb.collection-name=foo", + "spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) + .run(validateSpringSessionUsesMongo("foo")); + } + + @Test + void sessionCookieConfigurationIsAppliedToAutoConfiguredWebSessionIdResolver() { + this.contextRunner.withConfiguration(AutoConfigurations.of(WebSessionIdResolverAutoConfiguration.class)) + .withUserConfiguration(ReactiveWebServerConfiguration.class) + .withPropertyValues("server.reactive.session.cookie.name:JSESSIONID", + "server.reactive.session.cookie.domain:.example.com", + "server.reactive.session.cookie.path:/example", "server.reactive.session.cookie.max-age:60", + "server.reactive.session.cookie.http-only:false", "server.reactive.session.cookie.secure:false", + "server.reactive.session.cookie.same-site:strict", + "spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()) + .run(assertExchangeWithSession((exchange) -> { + List cookies = exchange.getResponse().getCookies().get("JSESSIONID"); + assertThat(cookies).isNotEmpty(); + assertThat(cookies).allMatch((cookie) -> cookie.getDomain().equals(".example.com")); + assertThat(cookies).allMatch((cookie) -> cookie.getPath().equals("/example")); + assertThat(cookies).allMatch((cookie) -> cookie.getMaxAge().equals(Duration.ofSeconds(60))); + assertThat(cookies).allMatch((cookie) -> !cookie.isHttpOnly()); + assertThat(cookies).allMatch((cookie) -> !cookie.isSecure()); + assertThat(cookies).allMatch((cookie) -> cookie.getSameSite().equals("Strict")); + })); + } + + private ContextConsumer validateSpringSessionUsesMongo( + String collectionName) { + return (context) -> { + ReactiveMongoSessionRepository repository = validateSessionRepository(context, + ReactiveMongoSessionRepository.class); + assertThat(repository.getCollectionName()).isEqualTo(collectionName); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + MapSession.DEFAULT_MAX_INACTIVE_INTERVAL); + }; + } + +} diff --git a/spring-boot-project/spring-boot-session-data-mongodb/src/dockerTest/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session-data-mongodb/src/dockerTest/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionAutoConfigurationTests.java new file mode 100644 index 000000000000..9596c02b020d --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-mongodb/src/dockerTest/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionAutoConfigurationTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.data.mongodb.autoconfigure; + +import java.time.Duration; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.boot.session.autoconfigure.AbstractSessionAutoConfigurationTests; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.session.config.SessionRepositoryCustomizer; +import org.springframework.session.data.mongo.MongoIndexedSessionRepository; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the servlet support of {@link MongoSessionAutoConfiguration}. + * + * @author Andy Wilkinson + */ +@Testcontainers(disabledWithoutDocker = true) +class MongoSessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTests { + + @Container + static final MongoDBContainer mongoDb = TestImage.container(MongoDBContainer.class); + + @BeforeEach + void prepareContextRunner() { + this.contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, + SessionAutoConfiguration.class, MongoSessionAutoConfiguration.class)) + .withPropertyValues("spring.data.mongodb.uri=" + mongoDb.getReplicaSetUrl()); + } + + @Test + void defaultConfig() { + this.contextRunner.run(validateSpringSessionUsesMongo("sessions")); + } + + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner.withPropertyValues("spring.session.timeout=1m") + .run(validateSpringSessionUsesMongo("sessions", Duration.ofMinutes(1))); + } + + @Test + void mongoSessionStoreWithCustomizations() { + this.contextRunner.withPropertyValues("spring.session.mongodb.collection-name=foo") + .run(validateSpringSessionUsesMongo("foo")); + } + + @Test + void whenTheUserDefinesTheirOwnSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { + this.contextRunner.withUserConfiguration(CustomizerConfiguration.class) + .withPropertyValues("spring.session.mongodb.collection-name=foo") + .run(validateSpringSessionUsesMongo("customized")); + } + + private ContextConsumer validateSpringSessionUsesMongo(String collectionName) { + return validateSpringSessionUsesMongo(collectionName, + new ServerProperties().getServlet().getSession().getTimeout()); + } + + private ContextConsumer validateSpringSessionUsesMongo(String collectionName, + Duration timeout) { + return (context) -> { + MongoIndexedSessionRepository repository = validateSessionRepository(context, + MongoIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("collectionName", collectionName); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", timeout); + }; + } + + @Configuration(proxyBeanMethods = false) + static class CustomizerConfiguration { + + @Bean + SessionRepositoryCustomizer sessionRepositoryCustomizer() { + return (repository) -> repository.setCollectionName("customized"); + } + + } + +} diff --git a/spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionAutoConfiguration.java b/spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionAutoConfiguration.java new file mode 100644 index 000000000000..aaf1d4ca7255 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionAutoConfiguration.java @@ -0,0 +1,111 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.data.mongodb.autoconfigure; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration; +import org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveDataAutoConfiguration; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.session.autoconfigure.SessionProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.session.ReactiveSessionRepository; +import org.springframework.session.SessionRepository; +import org.springframework.session.config.ReactiveSessionRepositoryCustomizer; +import org.springframework.session.config.SessionRepositoryCustomizer; +import org.springframework.session.data.mongo.MongoIndexedSessionRepository; +import org.springframework.session.data.mongo.ReactiveMongoSessionRepository; +import org.springframework.session.data.mongo.config.annotation.web.http.MongoHttpSessionConfiguration; +import org.springframework.session.data.mongo.config.annotation.web.reactive.ReactiveMongoWebSessionConfiguration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Session Data MongoDB. + * + * @author Eddú Meléndez + * @author Stephane Nicoll + * @author Vedran Pavic + * @since 4.0.0 + */ +@AutoConfiguration(before = SessionAutoConfiguration.class, + beforeName = { "org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration", + "org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration" }, + after = { MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class }, + afterName = "org.springframework.boot.webflux.autoconfigure.WebSessionIdResolverAutoConfiguration") +@EnableConfigurationProperties(MongoSessionProperties.class) +public class MongoSessionAutoConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ MongoOperations.class, MongoIndexedSessionRepository.class }) + @ConditionalOnBean(MongoOperations.class) + @ConditionalOnMissingBean(SessionRepository.class) + @ConditionalOnWebApplication(type = Type.SERVLET) + @Import(MongoHttpSessionConfiguration.class) + class ServletMongoSessionConfiguration { + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( + SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties, + ServerProperties serverProperties) { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + return (sessionRepository) -> { + map.from(sessionProperties + .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) + .to(sessionRepository::setDefaultMaxInactiveInterval); + map.from(mongoSessionProperties::getCollectionName).to(sessionRepository::setCollectionName); + }; + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ ReactiveMongoOperations.class, ReactiveMongoSessionRepository.class }) + @ConditionalOnMissingBean(ReactiveSessionRepository.class) + @ConditionalOnBean(ReactiveMongoOperations.class) + @Import(ReactiveMongoWebSessionConfiguration.class) + class ReactiveMongoSessionConfiguration { + + @Bean + ReactiveSessionRepositoryCustomizer springBootSessionRepositoryCustomizer( + SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties, + ServerProperties serverProperties) { + return (sessionRepository) -> { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(sessionProperties + .determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout())) + .to(sessionRepository::setDefaultMaxInactiveInterval); + map.from(mongoSessionProperties::getCollectionName).to(sessionRepository::setCollectionName); + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionProperties.java b/spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionProperties.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionProperties.java rename to spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionProperties.java index a51bcd42a4d2..2f3a69cb5eb3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionProperties.java +++ b/spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/MongoSessionProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.data.mongodb.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -22,7 +22,7 @@ * Configuration properties for Mongo-backed Spring Session. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.session.mongodb") public class MongoSessionProperties { diff --git a/spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/package-info.java b/spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/package-info.java new file mode 100644 index 000000000000..e9095f4c8c1c --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-mongodb/src/main/java/org/springframework/boot/session/data/mongodb/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Session Data MongoDB. + */ +package org.springframework.boot.session.data.mongodb.autoconfigure; diff --git a/spring-boot-project/spring-boot-session-data-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-session-data-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-mongodb/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-session-data-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-session-data-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..06b2e2944c44 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.session.data.mongodb.autoconfigure.MongoSessionAutoConfiguration diff --git a/spring-boot-project/spring-boot-session-data-redis/build.gradle b/spring-boot-project/spring-boot-session-data-redis/build.gradle new file mode 100644 index 000000000000..89c474680a07 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-redis/build.gradle @@ -0,0 +1,55 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Session Data Redis" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-session")) + api("org.springframework.session:spring-session-data-redis") + + implementation(project(":spring-boot-project:spring-boot-data-redis")) + implementation(project(":spring-boot-project:spring-boot-web-server")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-webflux")) + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-session"))) + dockerTestImplementation("com.redis:testcontainers-redis") + dockerTestImplementation("org.testcontainers:junit-jupiter") + + dockerTestRuntimeOnly("jakarta.servlet:jakarta.servlet-api") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("jakarta.servlet:jakarta.servlet-api") + testImplementation("org.springframework:spring-web") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-session-data-redis/src/dockerTest/java/org/springframework/boot/session/data/redis/autoconfigure/ReactiveRedisSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session-data-redis/src/dockerTest/java/org/springframework/boot/session/data/redis/autoconfigure/ReactiveRedisSessionAutoConfigurationTests.java new file mode 100644 index 000000000000..ac209da06df5 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-redis/src/dockerTest/java/org/springframework/boot/session/data/redis/autoconfigure/ReactiveRedisSessionAutoConfigurationTests.java @@ -0,0 +1,223 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.data.redis.autoconfigure; + +import java.time.Duration; +import java.util.List; +import java.util.Map; + +import com.redis.testcontainers.RedisContainer; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisReactiveAutoConfiguration; +import org.springframework.boot.session.autoconfigure.AbstractReactiveSessionAutoConfigurationTests; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webflux.autoconfigure.WebSessionIdResolverAutoConfiguration; +import org.springframework.data.redis.connection.ReactiveRedisConnection; +import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.http.ResponseCookie; +import org.springframework.session.MapSession; +import org.springframework.session.SaveMode; +import org.springframework.session.data.redis.ReactiveRedisIndexedSessionRepository; +import org.springframework.session.data.redis.ReactiveRedisSessionRepository; +import org.springframework.session.data.redis.config.ConfigureReactiveRedisAction; +import org.springframework.session.data.redis.config.annotation.ConfigureNotifyKeyspaceEventsReactiveAction; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +/** + * Tests for the reactive support of {@link RedisSessionAutoConfiguration}. + * + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Vedran Pavic + * @author Weix Sun + */ +@Testcontainers(disabledWithoutDocker = true) +class ReactiveRedisSessionAutoConfigurationTests extends AbstractReactiveSessionAutoConfigurationTests { + + @Container + public static RedisContainer redis = TestImage.container(RedisContainer.class); + + @BeforeEach + void prepareRunner() { + this.contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class, + WebSessionIdResolverAutoConfiguration.class, RedisSessionAutoConfiguration.class, + RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class)); + } + + @Test + void defaultConfig() { + this.contextRunner.run(validateSpringSessionUsesRedis("spring:session:", SaveMode.ON_SET_ATTRIBUTE)); + } + + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner.withPropertyValues("spring.session.timeout=1m").run((context) -> { + ReactiveRedisSessionRepository repository = validateSessionRepository(context, + ReactiveRedisSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); + }); + } + + @Test + void defaultConfigWithCustomWebFluxTimeout() { + this.contextRunner.withPropertyValues("server.reactive.session.timeout=1m").run((context) -> { + ReactiveRedisSessionRepository repository = validateSessionRepository(context, + ReactiveRedisSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); + }); + } + + @Test + void redisSessionStoreWithCustomizations() { + this.contextRunner + .withPropertyValues("spring.session.redis.namespace=foo", "spring.session.redis.save-mode=on-get-attribute") + .run(validateSpringSessionUsesRedis("foo:", SaveMode.ON_GET_ATTRIBUTE)); + } + + @Test + void sessionCookieConfigurationIsAppliedToAutoConfiguredWebSessionIdResolver() { + this.contextRunner.withUserConfiguration(ReactiveWebServerConfiguration.class) + .withPropertyValues("spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort(), + "server.reactive.session.cookie.name:JSESSIONID", + "server.reactive.session.cookie.domain:.example.com", + "server.reactive.session.cookie.path:/example", "server.reactive.session.cookie.max-age:60", + "server.reactive.session.cookie.http-only:false", "server.reactive.session.cookie.secure:false", + "server.reactive.session.cookie.same-site:strict") + .run(assertExchangeWithSession((exchange) -> { + List cookies = exchange.getResponse().getCookies().get("JSESSIONID"); + assertThat(cookies).isNotEmpty(); + assertThat(cookies).allMatch((cookie) -> cookie.getDomain().equals(".example.com")); + assertThat(cookies).allMatch((cookie) -> cookie.getPath().equals("/example")); + assertThat(cookies).allMatch((cookie) -> cookie.getMaxAge().equals(Duration.ofSeconds(60))); + assertThat(cookies).allMatch((cookie) -> !cookie.isHttpOnly()); + assertThat(cookies).allMatch((cookie) -> !cookie.isSecure()); + assertThat(cookies).allMatch((cookie) -> cookie.getSameSite().equals("Strict")); + })); + } + + @Test + void indexedRedisSessionDefaultConfig() { + this.contextRunner + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateSpringSessionUsesIndexedRedis("spring:session:", SaveMode.ON_SET_ATTRIBUTE)); + } + + @Test + void indexedRedisSessionStoreWithCustomizations() { + this.contextRunner + .withPropertyValues("spring.session.redis.repository-type=indexed", "spring.session.redis.namespace=foo", + "spring.session.redis.save-mode=on-get-attribute", "spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateSpringSessionUsesIndexedRedis("foo:", SaveMode.ON_GET_ATTRIBUTE)); + } + + @Test + void indexedRedisSessionWithConfigureActionNone() { + this.contextRunner + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.session.redis.configure-action=none", "spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateStrategy(ConfigureReactiveRedisAction.NO_OP.getClass())); + } + + @Test + void indexedRedisSessionWithDefaultConfigureActionNone() { + this.contextRunner + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateStrategy(ConfigureNotifyKeyspaceEventsReactiveAction.class, + entry("notify-keyspace-events", "gxE"))); + } + + @Test + void indexedRedisSessionWithCustomConfigureReactiveRedisActionBean() { + this.contextRunner.withUserConfiguration(MaxEntriesReactiveRedisAction.class) + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateStrategy(MaxEntriesReactiveRedisAction.class, entry("set-max-intset-entries", "1024"))); + + } + + private ContextConsumer validateSpringSessionUsesRedis(String namespace, + SaveMode saveMode) { + return (context) -> { + ReactiveRedisSessionRepository repository = validateSessionRepository(context, + ReactiveRedisSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + MapSession.DEFAULT_MAX_INACTIVE_INTERVAL); + assertThat(repository).hasFieldOrPropertyWithValue("namespace", namespace); + assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); + }; + } + + private ContextConsumer validateSpringSessionUsesIndexedRedis( + String keyNamespace, SaveMode saveMode) { + return (context) -> { + ReactiveRedisIndexedSessionRepository repository = validateSessionRepository(context, + ReactiveRedisIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + new ServerProperties().getReactive().getSession().getTimeout()); + assertThat(repository).hasFieldOrPropertyWithValue("namespace", keyNamespace); + assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); + }; + } + + private ContextConsumer validateStrategy( + Class expectedConfigureReactiveRedisActionType, + Map.Entry... expectedConfig) { + return (context) -> { + assertThat(context).hasSingleBean(ConfigureReactiveRedisAction.class); + assertThat(context).hasSingleBean(RedisConnectionFactory.class); + assertThat(context.getBean(ConfigureReactiveRedisAction.class)) + .isInstanceOf(expectedConfigureReactiveRedisActionType); + ReactiveRedisConnection connection = context.getBean(ReactiveRedisConnectionFactory.class) + .getReactiveConnection(); + if (expectedConfig.length > 0) { + assertThat(connection.serverCommands().getConfig("*").block(Duration.ofSeconds(30))) + .contains(expectedConfig); + } + }; + } + + static class MaxEntriesReactiveRedisAction implements ConfigureReactiveRedisAction { + + @Override + public Mono configure(ReactiveRedisConnection connection) { + return Mono.when(connection.serverCommands().setConfig("set-max-intset-entries", "1024")); + } + + } + +} diff --git a/spring-boot-project/spring-boot-session-data-redis/src/dockerTest/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session-data-redis/src/dockerTest/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionAutoConfigurationTests.java new file mode 100644 index 000000000000..3249fc1722bd --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-redis/src/dockerTest/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionAutoConfigurationTests.java @@ -0,0 +1,252 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.data.redis.autoconfigure; + +import java.time.Duration; +import java.util.Map; + +import com.redis.testcontainers.RedisContainer; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.session.autoconfigure.AbstractSessionAutoConfigurationTests; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.session.FlushMode; +import org.springframework.session.SaveMode; +import org.springframework.session.config.SessionRepositoryCustomizer; +import org.springframework.session.data.redis.RedisIndexedSessionRepository; +import org.springframework.session.data.redis.RedisSessionRepository; +import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction; +import org.springframework.session.data.redis.config.ConfigureRedisAction; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +/** + * Tests for {@link RedisSessionAutoConfiguration}. + * + * @author Stephane Nicoll + * @author Vedran Pavic + */ +@Testcontainers(disabledWithoutDocker = true) +class RedisSessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTests { + + @Container + public static RedisContainer redis = TestImage.container(RedisContainer.class); + + @BeforeEach + void prepareContextRunner() { + this.contextRunner = new WebApplicationContextRunner().withConfiguration(AutoConfigurations + .of(SessionAutoConfiguration.class, RedisSessionAutoConfiguration.class, RedisAutoConfiguration.class)); + } + + @Test + void defaultConfig() { + this.contextRunner + .withPropertyValues("spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort()) + .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) + .run(validateSpringSessionUsesDefaultRedis("spring:session:", FlushMode.ON_SAVE, + SaveMode.ON_SET_ATTRIBUTE)); + } + + @Test + void invalidConfigurationPropertyValueWhenDefaultConfigIsUsedWithCustomCronCleanup() { + this.contextRunner.withPropertyValues("spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort(), "spring.session.redis.cleanup-cron=0 0 * * * *") + .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) + .run((context) -> { + assertThat(context).hasFailed(); + assertThat(context.getStartupFailure()) + .hasRootCauseExactlyInstanceOf(InvalidConfigurationPropertyValueException.class); + }); + } + + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner + .withPropertyValues("spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort(), "spring.session.timeout=1m") + .run((context) -> { + RedisSessionRepository repository = validateSessionRepository(context, RedisSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); + }); + } + + @Test + void defaultRedisSessionStoreWithCustomizations() { + this.contextRunner + .withPropertyValues("spring.session.redis.namespace=foo", "spring.session.redis.flush-mode=immediate", + "spring.session.redis.save-mode=on-get-attribute", "spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateSpringSessionUsesDefaultRedis("foo:", FlushMode.IMMEDIATE, SaveMode.ON_GET_ATTRIBUTE)); + } + + @Test + void indexedRedisSessionDefaultConfig() { + this.contextRunner + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) + .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) + .run(validateSpringSessionUsesIndexedRedis("spring:session:", FlushMode.ON_SAVE, SaveMode.ON_SET_ATTRIBUTE, + "0 * * * * *")); + } + + @Test + void indexedRedisSessionStoreWithCustomizations() { + this.contextRunner + .withPropertyValues("spring.session.redis.repository-type=indexed", "spring.session.redis.namespace=foo", + "spring.session.redis.flush-mode=immediate", "spring.session.redis.save-mode=on-get-attribute", + "spring.session.redis.cleanup-cron=0 0 12 * * *", "spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateSpringSessionUsesIndexedRedis("foo:", FlushMode.IMMEDIATE, SaveMode.ON_GET_ATTRIBUTE, + "0 0 12 * * *")); + } + + @Test + void indexedRedisSessionWithConfigureActionNone() { + this.contextRunner + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.session.redis.configure-action=none", "spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateStrategy(ConfigureRedisAction.NO_OP.getClass())); + } + + @Test + void indexedRedisSessionWithDefaultConfigureActionNone() { + this.contextRunner + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateStrategy(ConfigureNotifyKeyspaceEventsAction.class, entry("notify-keyspace-events", "gxE"))); + } + + @Test + void indexedRedisSessionWithCustomConfigureRedisActionBean() { + this.contextRunner.withUserConfiguration(MaxEntriesRedisAction.class) + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run(validateStrategy(MaxEntriesRedisAction.class, entry("set-max-intset-entries", "1024"))); + + } + + @Test + void whenTheUserDefinesTheirOwnSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { + this.contextRunner.withUserConfiguration(CustomizerConfiguration.class) + .withPropertyValues("spring.session.redis.flush-mode=immediate", + "spring.data.redis.host=" + redis.getHost(), "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run((context) -> { + RedisSessionRepository repository = validateSessionRepository(context, RedisSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.ON_SAVE); + }); + } + + @Test + void whenIndexedAndTheUserDefinesTheirOwnSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { + this.contextRunner.withUserConfiguration(IndexedCustomizerConfiguration.class) + .withPropertyValues("spring.session.redis.repository-type=indexed", + "spring.session.redis.flush-mode=immediate", "spring.data.redis.host=" + redis.getHost(), + "spring.data.redis.port=" + redis.getFirstMappedPort()) + .run((context) -> { + RedisIndexedSessionRepository repository = validateSessionRepository(context, + RedisIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.ON_SAVE); + }); + } + + private ContextConsumer validateSpringSessionUsesDefaultRedis(String keyNamespace, + FlushMode flushMode, SaveMode saveMode) { + return (context) -> { + RedisSessionRepository repository = validateSessionRepository(context, RedisSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + new ServerProperties().getServlet().getSession().getTimeout()); + assertThat(repository).hasFieldOrPropertyWithValue("keyNamespace", keyNamespace); + assertThat(repository).hasFieldOrPropertyWithValue("flushMode", flushMode); + assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); + }; + } + + private ContextConsumer validateSpringSessionUsesIndexedRedis(String keyNamespace, + FlushMode flushMode, SaveMode saveMode, String cleanupCron) { + return (context) -> { + RedisIndexedSessionRepository repository = validateSessionRepository(context, + RedisIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + new ServerProperties().getServlet().getSession().getTimeout()); + assertThat(repository).hasFieldOrPropertyWithValue("namespace", keyNamespace); + assertThat(repository).hasFieldOrPropertyWithValue("flushMode", flushMode); + assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); + assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", cleanupCron); + }; + } + + private ContextConsumer validateStrategy( + Class expectedConfigureRedisActionType, Map.Entry... expectedConfig) { + return (context) -> { + assertThat(context).hasSingleBean(ConfigureRedisAction.class); + assertThat(context).hasSingleBean(RedisConnectionFactory.class); + assertThat(context.getBean(ConfigureRedisAction.class)).isInstanceOf(expectedConfigureRedisActionType); + RedisConnection connection = context.getBean(RedisConnectionFactory.class).getConnection(); + if (expectedConfig.length > 0) { + assertThat(connection.serverCommands().getConfig("*")).contains(expectedConfig); + } + }; + } + + static class MaxEntriesRedisAction implements ConfigureRedisAction { + + @Override + public void configure(RedisConnection connection) { + connection.serverCommands().setConfig("set-max-intset-entries", "1024"); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomizerConfiguration { + + @Bean + SessionRepositoryCustomizer sessionRepositoryCustomizer() { + return (repository) -> repository.setFlushMode(FlushMode.ON_SAVE); + } + + } + + @Configuration(proxyBeanMethods = false) + static class IndexedCustomizerConfiguration { + + @Bean + SessionRepositoryCustomizer sessionRepositoryCustomizer() { + return (repository) -> repository.setFlushMode(FlushMode.ON_SAVE); + } + + } + +} diff --git a/spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionAutoConfiguration.java b/spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionAutoConfiguration.java new file mode 100644 index 000000000000..2963a4d49061 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionAutoConfiguration.java @@ -0,0 +1,211 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.data.redis.autoconfigure; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; +import org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration; +import org.springframework.boot.data.redis.autoconfigure.RedisReactiveAutoConfiguration; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.session.autoconfigure.SessionProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.session.ReactiveSessionRepository; +import org.springframework.session.SessionRepository; +import org.springframework.session.config.ReactiveSessionRepositoryCustomizer; +import org.springframework.session.config.SessionRepositoryCustomizer; +import org.springframework.session.data.redis.ReactiveRedisIndexedSessionRepository; +import org.springframework.session.data.redis.ReactiveRedisSessionRepository; +import org.springframework.session.data.redis.RedisIndexedSessionRepository; +import org.springframework.session.data.redis.RedisSessionRepository; +import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction; +import org.springframework.session.data.redis.config.ConfigureReactiveRedisAction; +import org.springframework.session.data.redis.config.ConfigureRedisAction; +import org.springframework.session.data.redis.config.annotation.ConfigureNotifyKeyspaceEventsReactiveAction; +import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration; +import org.springframework.session.data.redis.config.annotation.web.http.RedisIndexedHttpSessionConfiguration; +import org.springframework.session.data.redis.config.annotation.web.server.RedisIndexedWebSessionConfiguration; +import org.springframework.session.data.redis.config.annotation.web.server.RedisWebSessionConfiguration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Session Data Redis. + * + * @author Andy Wilkinson + * @author Tommy Ludwig + * @author Eddú Meléndez + * @author Stephane Nicoll + * @author Vedran Pavic + * @since 4.0.0 + */ +@AutoConfiguration(before = SessionAutoConfiguration.class, + beforeName = { "org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration", + "org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration" }, + after = { RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class }, + afterName = "org.springframework.boot.webflux.autoconfigure.WebSessionIdResolverAutoConfiguration") +@EnableConfigurationProperties({ RedisSessionProperties.class, ServerProperties.class, SessionProperties.class }) +public class RedisSessionAutoConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ RedisTemplate.class, RedisIndexedSessionRepository.class }) + @ConditionalOnMissingBean(SessionRepository.class) + @ConditionalOnBean(RedisConnectionFactory.class) + @ConditionalOnWebApplication(type = Type.SERVLET) + static class ServletRedisSessionConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(name = "spring.session.redis.repository-type", havingValue = "default", + matchIfMissing = true) + @Import(RedisHttpSessionConfiguration.class) + static class DefaultRedisSessionConfiguration { + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( + SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, + ServerProperties serverProperties) { + String cleanupCron = redisSessionProperties.getCleanupCron(); + if (cleanupCron != null) { + throw new InvalidConfigurationPropertyValueException("spring.session.redis.cleanup-cron", + cleanupCron, "Cron-based cleanup is only supported when " + + "spring.session.redis.repository-type is set to indexed."); + } + return (sessionRepository) -> { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(sessionProperties + .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) + .to(sessionRepository::setDefaultMaxInactiveInterval); + map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace); + map.from(redisSessionProperties::getFlushMode).to(sessionRepository::setFlushMode); + map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); + }; + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(name = "spring.session.redis.repository-type", havingValue = "indexed") + @Import(RedisIndexedHttpSessionConfiguration.class) + static class IndexedRedisSessionConfiguration { + + @Bean + @ConditionalOnMissingBean + ConfigureRedisAction configureRedisAction(RedisSessionProperties redisSessionProperties) { + return switch (redisSessionProperties.getConfigureAction()) { + case NOTIFY_KEYSPACE_EVENTS -> new ConfigureNotifyKeyspaceEventsAction(); + case NONE -> ConfigureRedisAction.NO_OP; + }; + } + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( + SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, + ServerProperties serverProperties) { + return (sessionRepository) -> { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(sessionProperties + .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) + .to(sessionRepository::setDefaultMaxInactiveInterval); + map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace); + map.from(redisSessionProperties::getFlushMode).to(sessionRepository::setFlushMode); + map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); + map.from(redisSessionProperties::getCleanupCron).to(sessionRepository::setCleanupCron); + }; + } + + } + + } + + @ConditionalOnWebApplication(type = Type.REACTIVE) + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ ReactiveRedisConnectionFactory.class, ReactiveRedisSessionRepository.class }) + @ConditionalOnMissingBean(ReactiveSessionRepository.class) + @ConditionalOnBean(ReactiveRedisConnectionFactory.class) + class ReactiveRedisSessionConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(name = "spring.session.redis.repository-type", havingValue = "default", + matchIfMissing = true) + @Import(RedisWebSessionConfiguration.class) + static class DefaultRedisSessionConfiguration { + + @Bean + ReactiveSessionRepositoryCustomizer springBootSessionRepositoryCustomizer( + SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, + ServerProperties serverProperties) { + return (sessionRepository) -> { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(sessionProperties + .determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout())) + .to(sessionRepository::setDefaultMaxInactiveInterval); + map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace); + map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); + }; + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(name = "spring.session.redis.repository-type", havingValue = "indexed") + @Import(RedisIndexedWebSessionConfiguration.class) + static class IndexedRedisSessionConfiguration { + + @Bean + @ConditionalOnMissingBean + ConfigureReactiveRedisAction configureReactiveRedisAction(RedisSessionProperties redisSessionProperties) { + return switch (redisSessionProperties.getConfigureAction()) { + case NOTIFY_KEYSPACE_EVENTS -> new ConfigureNotifyKeyspaceEventsReactiveAction(); + case NONE -> ConfigureReactiveRedisAction.NO_OP; + }; + } + + @Bean + ReactiveSessionRepositoryCustomizer springBootSessionRepositoryCustomizer( + SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, + ServerProperties serverProperties) { + return (sessionRepository) -> { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(sessionProperties + .determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout())) + .to(sessionRepository::setDefaultMaxInactiveInterval); + map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace); + map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); + }; + } + + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionProperties.java b/spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionProperties.java rename to spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionProperties.java index ec7eea6149ce..86d20eed4a18 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionProperties.java +++ b/spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/RedisSessionProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.data.redis.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.session.FlushMode; @@ -24,7 +24,7 @@ * Configuration properties for Redis backed Spring Session. * * @author Vedran Pavic - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.session.redis") public class RedisSessionProperties { diff --git a/spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/package-info.java b/spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/package-info.java new file mode 100644 index 000000000000..5b75b2887e93 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-redis/src/main/java/org/springframework/boot/session/data/redis/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Session Data Redis. + */ +package org.springframework.boot.session.data.redis.autoconfigure; diff --git a/spring-boot-project/spring-boot-session-data-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-session-data-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..72de9b1f7675 --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,8 @@ +{ + "properties": [ + { + "name": "spring.session.redis.cleanup-cron", + "defaultValue": "0 * * * * *" + } + ] +} diff --git a/spring-boot-project/spring-boot-session-data-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-session-data-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..be2f677f57db --- /dev/null +++ b/spring-boot-project/spring-boot-session-data-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.session.data.redis.autoconfigure.RedisSessionAutoConfiguration diff --git a/spring-boot-project/spring-boot-session-hazelcast/build.gradle b/spring-boot-project/spring-boot-session-hazelcast/build.gradle new file mode 100644 index 000000000000..0e2c43d9887d --- /dev/null +++ b/spring-boot-project/spring-boot-session-hazelcast/build.gradle @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Session Hazelcast" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-session")) + api("org.springframework.session:spring-session-hazelcast") + + implementation(project(":spring-boot-project:spring-boot-hazelcast")) + implementation(project(":spring-boot-project:spring-boot-web-server")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-session"))) + testImplementation("jakarta.servlet:jakarta.servlet-api") + testImplementation("org.springframework:spring-web") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionAutoConfiguration.java b/spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionAutoConfiguration.java new file mode 100644 index 000000000000..9dc88163ee3d --- /dev/null +++ b/spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionAutoConfiguration.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.hazelcast.autoconfigure; + +import com.hazelcast.core.HazelcastInstance; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.hazelcast.autoconfigure.HazelcastAutoConfiguration; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.session.autoconfigure.SessionProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.session.SessionRepository; +import org.springframework.session.config.SessionRepositoryCustomizer; +import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository; +import org.springframework.session.hazelcast.config.annotation.web.http.HazelcastHttpSessionConfiguration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Session Hazelcast. + * + * @author Tommy Ludwig + * @author Eddú Meléndez + * @author Stephane Nicoll + * @author Vedran Pavic + * @since 4.0.0 + */ +@AutoConfiguration(before = SessionAutoConfiguration.class, after = HazelcastAutoConfiguration.class) +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnClass(HazelcastIndexedSessionRepository.class) +@ConditionalOnMissingBean(SessionRepository.class) +@ConditionalOnBean(HazelcastInstance.class) +@EnableConfigurationProperties({ HazelcastSessionProperties.class, ServerProperties.class, SessionProperties.class }) +@Import(HazelcastHttpSessionConfiguration.class) +public class HazelcastSessionAutoConfiguration { + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( + SessionProperties sessionProperties, HazelcastSessionProperties hazelcastSessionProperties, + ServerProperties serverProperties) { + return (sessionRepository) -> { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(sessionProperties.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) + .to(sessionRepository::setDefaultMaxInactiveInterval); + map.from(hazelcastSessionProperties::getMapName).to(sessionRepository::setSessionMapName); + map.from(hazelcastSessionProperties::getFlushMode).to(sessionRepository::setFlushMode); + map.from(hazelcastSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); + }; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionProperties.java b/spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionProperties.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionProperties.java rename to spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionProperties.java index c7d8e6f37376..2873d2549e4c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionProperties.java +++ b/spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.hazelcast.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.session.FlushMode; @@ -24,7 +24,7 @@ * Configuration properties for Hazelcast backed Spring Session. * * @author Vedran Pavic - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.session.hazelcast") public class HazelcastSessionProperties { diff --git a/spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/package-info.java b/spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/package-info.java new file mode 100644 index 000000000000..2c6217c88a3e --- /dev/null +++ b/spring-boot-project/spring-boot-session-hazelcast/src/main/java/org/springframework/boot/session/hazelcast/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Session Hazelcast. + */ +package org.springframework.boot.session.hazelcast.autoconfigure; diff --git a/spring-boot-project/spring-boot-session-hazelcast/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-session-hazelcast/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-session-hazelcast/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-session-hazelcast/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-session-hazelcast/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..09d2ab42384f --- /dev/null +++ b/spring-boot-project/spring-boot-session-hazelcast/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.session.hazelcast.autoconfigure.HazelcastSessionAutoConfiguration diff --git a/spring-boot-project/spring-boot-session-hazelcast/src/test/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session-hazelcast/src/test/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionAutoConfigurationTests.java new file mode 100644 index 000000000000..58b5a10d2cd4 --- /dev/null +++ b/spring-boot-project/spring-boot-session-hazelcast/src/test/java/org/springframework/boot/session/hazelcast/autoconfigure/HazelcastSessionAutoConfigurationTests.java @@ -0,0 +1,142 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.hazelcast.autoconfigure; + +import java.time.Duration; + +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.map.IMap; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.session.autoconfigure.AbstractSessionAutoConfigurationTests; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.session.FlushMode; +import org.springframework.session.SaveMode; +import org.springframework.session.config.SessionRepositoryCustomizer; +import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link HazelcastSessionAutoConfiguration}. + * + * @author Vedran Pavic + */ +class HazelcastSessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTests { + + @BeforeEach + void prepareContextRunner() { + this.contextRunner = new WebApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(SessionAutoConfiguration.class, HazelcastSessionAutoConfiguration.class)) + .withUserConfiguration(HazelcastConfiguration.class); + } + + @Test + void defaultConfig() { + this.contextRunner.run((context) -> { + HazelcastIndexedSessionRepository repository = validateSessionRepository(context, + HazelcastIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + new ServerProperties().getServlet().getSession().getTimeout()); + HazelcastInstance hazelcastInstance = context.getBean(HazelcastInstance.class); + then(hazelcastInstance).should().getMap("spring:session:sessions"); + }); + } + + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner.withPropertyValues("spring.session.timeout=1m").run((context) -> { + HazelcastIndexedSessionRepository repository = validateSessionRepository(context, + HazelcastIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); + }); + } + + @Test + void customMapName() { + this.contextRunner.withPropertyValues("spring.session.hazelcast.map-name=foo:bar:biz").run((context) -> { + validateSessionRepository(context, HazelcastIndexedSessionRepository.class); + HazelcastInstance hazelcastInstance = context.getBean(HazelcastInstance.class); + then(hazelcastInstance).should().getMap("foo:bar:biz"); + }); + } + + @Test + void customFlushMode() { + this.contextRunner.withPropertyValues("spring.session.hazelcast.flush-mode=immediate").run((context) -> { + HazelcastIndexedSessionRepository repository = validateSessionRepository(context, + HazelcastIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.IMMEDIATE); + }); + } + + @Test + void customSaveMode() { + this.contextRunner.withPropertyValues("spring.session.hazelcast.save-mode=on-get-attribute").run((context) -> { + HazelcastIndexedSessionRepository repository = validateSessionRepository(context, + HazelcastIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("saveMode", SaveMode.ON_GET_ATTRIBUTE); + }); + } + + @Test + void whenTheUserDefinesTheirOwnSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { + this.contextRunner.withUserConfiguration(CustomizerConfiguration.class) + .withPropertyValues("spring.session.hazelcast.save-mode=on-get-attribute") + .run((context) -> { + HazelcastIndexedSessionRepository repository = validateSessionRepository(context, + HazelcastIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("saveMode", SaveMode.ALWAYS); + }); + } + + @Configuration(proxyBeanMethods = false) + static class HazelcastConfiguration { + + @Bean + @SuppressWarnings("unchecked") + HazelcastInstance hazelcastInstance() { + IMap map = mock(IMap.class); + HazelcastInstance mock = mock(HazelcastInstance.class); + given(mock.getMap("spring:session:sessions")).willReturn(map); + given(mock.getMap("foo:bar:biz")).willReturn(map); + return mock; + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomizerConfiguration { + + @Bean + SessionRepositoryCustomizer sessionRepositoryCustomizer() { + return (repository) -> repository.setSaveMode(SaveMode.ALWAYS); + } + + } + +} diff --git a/spring-boot-project/spring-boot-session-jdbc/build.gradle b/spring-boot-project/spring-boot-session-jdbc/build.gradle new file mode 100644 index 000000000000..93585fa80f2b --- /dev/null +++ b/spring-boot-project/spring-boot-session-jdbc/build.gradle @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Session JDBC" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-session")) + api("org.springframework.session:spring-session-jdbc") + + implementation(project(":spring-boot-project:spring-boot-jdbc")) + implementation(project(":spring-boot-project:spring-boot-web-server")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-flyway")) + testImplementation(project(":spring-boot-project:spring-boot-liquibase")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-session"))) + testImplementation("jakarta.servlet:jakarta.servlet-api") + testImplementation("org.apache.commons:commons-dbcp2") + testImplementation("org.springframework:spring-web") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("org.flywaydb:flyway-database-hsqldb") + testRuntimeOnly("org.hsqldb:hsqldb") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector.java index c550852e8efb..3b1d799ca536 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector.java +++ b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.jdbc.autoconfigure; import java.util.Collections; import java.util.Set; diff --git a/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionAutoConfiguration.java b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionAutoConfiguration.java new file mode 100644 index 000000000000..8981db8677f9 --- /dev/null +++ b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionAutoConfiguration.java @@ -0,0 +1,99 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.jdbc.autoconfigure; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.session.autoconfigure.SessionProperties; +import org.springframework.boot.sql.autoconfigure.init.OnDatabaseInitializationCondition; +import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.session.SessionRepository; +import org.springframework.session.config.SessionRepositoryCustomizer; +import org.springframework.session.jdbc.JdbcIndexedSessionRepository; +import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource; +import org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration; + +/** + * {@link EnableAutoConfiguration Auto-configuraion} for Spring Session JDBC. + * + * @author Eddú Meléndez + * @author Stephane Nicoll + * @author Vedran Pavic + * @since 4.0.0 + */ +@AutoConfiguration(before = SessionAutoConfiguration.class) +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnClass({ JdbcTemplate.class, JdbcIndexedSessionRepository.class }) +@ConditionalOnMissingBean(SessionRepository.class) +@ConditionalOnBean(DataSource.class) +@EnableConfigurationProperties({ JdbcSessionProperties.class, SessionProperties.class }) +@Import({ DatabaseInitializationDependencyConfigurer.class, JdbcHttpSessionConfiguration.class }) +public class JdbcSessionAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @Conditional(OnJdbcSessionDatasourceInitializationCondition.class) + JdbcSessionDataSourceScriptDatabaseInitializer jdbcSessionDataSourceScriptDatabaseInitializer( + @SpringSessionDataSource ObjectProvider sessionDataSource, + ObjectProvider dataSource, JdbcSessionProperties properties) { + DataSource dataSourceToInitialize = sessionDataSource.getIfAvailable(dataSource::getObject); + return new JdbcSessionDataSourceScriptDatabaseInitializer(dataSourceToInitialize, properties); + } + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + SessionRepositoryCustomizer springBootSessionRepositoryCustomizer( + SessionProperties sessionProperties, JdbcSessionProperties jdbcSessionProperties, + ServerProperties serverProperties) { + return (sessionRepository) -> { + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(sessionProperties.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout())) + .to(sessionRepository::setDefaultMaxInactiveInterval); + map.from(jdbcSessionProperties::getTableName).to(sessionRepository::setTableName); + map.from(jdbcSessionProperties::getFlushMode).to(sessionRepository::setFlushMode); + map.from(jdbcSessionProperties::getSaveMode).to(sessionRepository::setSaveMode); + map.from(jdbcSessionProperties::getCleanupCron).to(sessionRepository::setCleanupCron); + }; + } + + static class OnJdbcSessionDatasourceInitializationCondition extends OnDatabaseInitializationCondition { + + OnJdbcSessionDatasourceInitializationCondition() { + super("Jdbc Session", "spring.session.jdbc.initialize-schema"); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionDataSourceScriptDatabaseInitializer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializer.java rename to spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionDataSourceScriptDatabaseInitializer.java index 1495589edefb..8ecffd4f19a4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializer.java +++ b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionDataSourceScriptDatabaseInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.jdbc.autoconfigure; import java.util.List; @@ -34,7 +34,7 @@ * @author Vedran Pavic * @author Andy Wilkinson * @author Phillip Webb - * @since 2.6.0 + * @since 4.0.0 */ public class JdbcSessionDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionProperties.java b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionProperties.java rename to spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionProperties.java index 5b326120bc4d..1a3d194e75ae 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionProperties.java +++ b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.jdbc.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.sql.init.DatabaseInitializationMode; @@ -22,10 +22,10 @@ import org.springframework.session.SaveMode; /** - * Configuration properties for JDBC backed Spring Session. + * Configuration properties for JDBC-backed Spring Session. * * @author Vedran Pavic - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.session.jdbc") public class JdbcSessionProperties { diff --git a/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/package-info.java b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/package-info.java new file mode 100644 index 000000000000..94a2bfb9e0e7 --- /dev/null +++ b/spring-boot-project/spring-boot-session-jdbc/src/main/java/org/springframework/boot/session/jdbc/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Session JDBC. + */ +package org.springframework.boot.session.jdbc.autoconfigure; diff --git a/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..74138988b338 --- /dev/null +++ b/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Depends on Database Initialization Detectors +org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ +org.springframework.boot.session.jdbc.autoconfigure.JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector diff --git a/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..824964ec89e5 --- /dev/null +++ b/spring-boot-project/spring-boot-session-jdbc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.session.jdbc.autoconfigure.JdbcSessionAutoConfiguration diff --git a/spring-boot-project/spring-boot-session-jdbc/src/test/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session-jdbc/src/test/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionAutoConfigurationTests.java new file mode 100644 index 000000000000..5a6759b5b1a4 --- /dev/null +++ b/spring-boot-project/spring-boot-session-jdbc/src/test/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionAutoConfigurationTests.java @@ -0,0 +1,304 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.jdbc.autoconfigure; + +import java.time.Duration; + +import javax.sql.DataSource; + +import org.apache.commons.dbcp2.BasicDataSource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration; +import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; +import org.springframework.boot.session.autoconfigure.AbstractSessionAutoConfigurationTests; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.sql.init.DatabaseInitializationMode; +import org.springframework.boot.sql.init.DatabaseInitializationSettings; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.BadSqlGrammarException; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.session.FlushMode; +import org.springframework.session.SaveMode; +import org.springframework.session.jdbc.JdbcIndexedSessionRepository; +import org.springframework.session.jdbc.PostgreSqlJdbcIndexedSessionRepositoryCustomizer; +import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * Tests for {@link JdbcSessionAutoConfiguration}. + * + * @author Vedran Pavic + * @author Stephane Nicoll + */ +class JdbcSessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTests { + + @BeforeEach + void prepareRunner() { + this.contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, + SessionAutoConfiguration.class, JdbcSessionAutoConfiguration.class)) + .withPropertyValues("spring.datasource.generate-unique-name=true"); + } + + @Test + void defaultConfig() { + this.contextRunner.run((context) -> { + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + new ServerProperties().getServlet().getSession().getTimeout()); + assertThat(repository).hasFieldOrPropertyWithValue("tableName", "SPRING_SESSION"); + assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", "0 * * * * *"); + assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema()) + .isEqualTo(DatabaseInitializationMode.EMBEDDED); + assertThat(context.getBean(JdbcOperations.class).queryForList("select * from SPRING_SESSION")).isEmpty(); + }); + } + + @Test + void disableDataSourceInitializer() { + this.contextRunner.withPropertyValues("spring.session.jdbc.initialize-schema=never").run((context) -> { + assertThat(context).doesNotHaveBean(JdbcSessionDataSourceScriptDatabaseInitializer.class); + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("tableName", "SPRING_SESSION"); + assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema()) + .isEqualTo(DatabaseInitializationMode.NEVER); + assertThatExceptionOfType(BadSqlGrammarException.class) + .isThrownBy(() -> context.getBean(JdbcOperations.class).queryForList("select * from SPRING_SESSION")); + }); + } + + @Test + void customTimeout() { + this.contextRunner.withPropertyValues("spring.session.timeout=1m").run((context) -> { + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", Duration.ofMinutes(1)); + }); + } + + @Test + void customTableName() { + this.contextRunner.withPropertyValues("spring.session.jdbc.table-name=FOO_BAR", + "spring.session.jdbc.schema=classpath:org/springframework/boot/session/jdbc/autoconfigure/custom-schema-h2.sql") + .run((context) -> { + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("tableName", "FOO_BAR"); + assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema()) + .isEqualTo(DatabaseInitializationMode.EMBEDDED); + assertThat(context.getBean(JdbcOperations.class).queryForList("select * from FOO_BAR")).isEmpty(); + }); + } + + @Test + void customCleanupCron() { + this.contextRunner.withPropertyValues("spring.session.jdbc.cleanup-cron=0 0 12 * * *").run((context) -> { + assertThat(context.getBean(JdbcSessionProperties.class).getCleanupCron()).isEqualTo("0 0 12 * * *"); + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", "0 0 12 * * *"); + }); + } + + @Test + void customFlushMode() { + this.contextRunner.withPropertyValues("spring.session.jdbc.flush-mode=immediate").run((context) -> { + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.IMMEDIATE); + }); + } + + @Test + void customSaveMode() { + this.contextRunner.withPropertyValues("spring.session.jdbc.save-mode=on-get-attribute").run((context) -> { + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("saveMode", SaveMode.ON_GET_ATTRIBUTE); + }); + } + + @Test + void sessionDataSourceIsUsedWhenAvailable() { + this.contextRunner.withUserConfiguration(SessionDataSourceConfiguration.class).run((context) -> { + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + DataSource sessionDataSource = context.getBean("sessionDataSource", DataSource.class); + assertThat(repository).extracting("jdbcOperations.dataSource").isEqualTo(sessionDataSource); + assertThat(context.getBean(JdbcSessionDataSourceScriptDatabaseInitializer.class)) + .hasFieldOrPropertyWithValue("dataSource", sessionDataSource); + assertThatExceptionOfType(BadSqlGrammarException.class) + .isThrownBy(() -> context.getBean(JdbcOperations.class).queryForList("select * from SPRING_SESSION")); + }); + } + + @Test + void sessionRepositoryBeansDependOnJdbcSessionDataSourceInitializer() { + this.contextRunner.run((context) -> { + ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); + String[] sessionRepositoryNames = beanFactory.getBeanNamesForType(JdbcIndexedSessionRepository.class); + assertThat(sessionRepositoryNames).isNotEmpty(); + for (String sessionRepositoryName : sessionRepositoryNames) { + assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn()) + .contains("jdbcSessionDataSourceScriptDatabaseInitializer"); + } + }); + } + + @Test + void sessionRepositoryBeansDependOnFlyway() { + this.contextRunner.withConfiguration(AutoConfigurations.of(FlywayAutoConfiguration.class)) + .withPropertyValues("spring.session.jdbc.initialize-schema=never") + .run((context) -> { + ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); + String[] sessionRepositoryNames = beanFactory.getBeanNamesForType(JdbcIndexedSessionRepository.class); + assertThat(sessionRepositoryNames).isNotEmpty(); + for (String sessionRepositoryName : sessionRepositoryNames) { + assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn()).contains("flyway", + "flywayInitializer"); + } + }); + } + + @Test + @WithResource(name = "db/changelog/db.changelog-master.yaml", content = "databaseChangeLog:") + void sessionRepositoryBeansDependOnLiquibase() { + this.contextRunner.withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class)) + .withPropertyValues("spring.session.jdbc.initialize-schema=never") + .run((context) -> { + ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); + String[] sessionRepositoryNames = beanFactory.getBeanNamesForType(JdbcIndexedSessionRepository.class); + assertThat(sessionRepositoryNames).isNotEmpty(); + for (String sessionRepositoryName : sessionRepositoryNames) { + assertThat(beanFactory.getBeanDefinition(sessionRepositoryName).getDependsOn()) + .contains("liquibase"); + } + }); + } + + @Test + void whenTheUserDefinesTheirOwnJdbcSessionDatabaseInitializerThenTheAutoConfiguredInitializerBacksOff() { + this.contextRunner.withUserConfiguration(CustomJdbcSessionDatabaseInitializerConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class)) + .run((context) -> assertThat(context).hasSingleBean(JdbcSessionDataSourceScriptDatabaseInitializer.class) + .doesNotHaveBean("jdbcSessionDataSourceScriptDatabaseInitializer") + .hasBean("customInitializer")); + } + + @Test + void whenTheUserDefinesTheirOwnDatabaseInitializerThenTheAutoConfiguredJdbcSessionInitializerRemains() { + this.contextRunner.withUserConfiguration(CustomDatabaseInitializerConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class)) + .run((context) -> assertThat(context).hasSingleBean(JdbcSessionDataSourceScriptDatabaseInitializer.class) + .hasBean("customInitializer")); + } + + @Test + void whenTheUserDefinesTheirOwnJdbcIndexedSessionRepositoryCustomizerThenDefaultConfigurationIsOverwritten() { + String expectedCreateSessionAttributeQuery = """ + INSERT INTO SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID, ATTRIBUTE_NAME, ATTRIBUTE_BYTES) + VALUES (?, ?, ?) + ON CONFLICT (SESSION_PRIMARY_ID, ATTRIBUTE_NAME) + DO UPDATE SET ATTRIBUTE_BYTES = EXCLUDED.ATTRIBUTE_BYTES + """; + this.contextRunner.withUserConfiguration(CustomJdbcIndexedSessionRepositoryCustomizerConfiguration.class) + .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class)) + .run((context) -> { + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("createSessionAttributeQuery", + expectedCreateSessionAttributeQuery); + }); + } + + @Configuration + static class SessionDataSourceConfiguration { + + @Bean + @SpringSessionDataSource + DataSource sessionDataSource() { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); + dataSource.setUrl("jdbc:hsqldb:mem:sessiondb"); + dataSource.setUsername("sa"); + return dataSource; + } + + @Bean + @Primary + DataSource mainDataSource() { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); + dataSource.setUrl("jdbc:hsqldb:mem:maindb"); + dataSource.setUsername("sa"); + return dataSource; + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomJdbcSessionDatabaseInitializerConfiguration { + + @Bean + JdbcSessionDataSourceScriptDatabaseInitializer customInitializer(DataSource dataSource, + JdbcSessionProperties properties) { + return new JdbcSessionDataSourceScriptDatabaseInitializer(dataSource, properties); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomDatabaseInitializerConfiguration { + + @Bean + DataSourceScriptDatabaseInitializer customInitializer(DataSource dataSource) { + return new DataSourceScriptDatabaseInitializer(dataSource, new DatabaseInitializationSettings()); + } + + } + + @Configuration + static class CustomJdbcIndexedSessionRepositoryCustomizerConfiguration { + + @Bean + PostgreSqlJdbcIndexedSessionRepositoryCustomizer postgreSqlJdbcIndexedSessionRepositoryCustomizer() { + return new PostgreSqlJdbcIndexedSessionRepositoryCustomizer(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-session-jdbc/src/test/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionDataSourceScriptDatabaseInitializerTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializerTests.java rename to spring-boot-project/spring-boot-session-jdbc/src/test/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionDataSourceScriptDatabaseInitializerTests.java index ffc77f751fcd..4b01bb3d9d10 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/JdbcSessionDataSourceScriptDatabaseInitializerTests.java +++ b/spring-boot-project/spring-boot-session-jdbc/src/test/java/org/springframework/boot/session/jdbc/autoconfigure/JdbcSessionDataSourceScriptDatabaseInitializerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.jdbc.autoconfigure; import javax.sql.DataSource; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/session/custom-schema-h2.sql b/spring-boot-project/spring-boot-session-jdbc/src/test/resources/org/springframework/boot/session/jdbc/autoconfigure/custom-schema-h2.sql similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/session/custom-schema-h2.sql rename to spring-boot-project/spring-boot-session-jdbc/src/test/resources/org/springframework/boot/session/jdbc/autoconfigure/custom-schema-h2.sql diff --git a/spring-boot-project/spring-boot-session/build.gradle b/spring-boot-project/spring-boot-session/build.gradle new file mode 100644 index 000000000000..d8f78f6589dd --- /dev/null +++ b/spring-boot-project/spring-boot-session/build.gradle @@ -0,0 +1,61 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "java-test-fixtures" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Session" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework.session:spring-session-core") + + implementation(project(":spring-boot-project:spring-boot-web-server")) + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("io.projectreactor:reactor-core") + optional("jakarta.servlet:jakarta.servlet-api") + optional("org.springframework.security:spring-security-web") + + testFixturesImplementation(project(":spring-boot-project:spring-boot-reactor")) + testFixturesImplementation(project(":spring-boot-project:spring-boot-test")) + testFixturesImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testFixturesImplementation(testFixtures(project(":spring-boot-project:spring-boot"))) + testFixturesImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testFixturesImplementation("io.projectreactor:reactor-core") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-webflux")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation("net.minidev:json-smart") + testImplementation("io.projectreactor:reactor-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/DefaultCookieSerializerCustomizer.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/DefaultCookieSerializerCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/DefaultCookieSerializerCustomizer.java rename to spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/DefaultCookieSerializerCustomizer.java index 56451ae0c7c2..10dd3bc56706 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/DefaultCookieSerializerCustomizer.java +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/DefaultCookieSerializerCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.autoconfigure; import org.springframework.session.web.http.DefaultCookieSerializer; @@ -23,7 +23,7 @@ * {@link DefaultCookieSerializer} configuration. * * @author Vedran Pavic - * @since 2.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface DefaultCookieSerializerCustomizer { diff --git a/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionAutoConfiguration.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionAutoConfiguration.java new file mode 100644 index 000000000000..d38336e163b2 --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionAutoConfiguration.java @@ -0,0 +1,127 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.autoconfigure; + +import java.time.Duration; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.web.server.Cookie; +import org.springframework.boot.web.server.Cookie.SameSite; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.security.web.authentication.RememberMeServices; +import org.springframework.session.Session; +import org.springframework.session.security.web.authentication.SpringSessionRememberMeServices; +import org.springframework.session.web.http.CookieHttpSessionIdResolver; +import org.springframework.session.web.http.CookieSerializer; +import org.springframework.session.web.http.DefaultCookieSerializer; +import org.springframework.session.web.http.HttpSessionIdResolver; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Session. + * + * @author Andy Wilkinson + * @author Tommy Ludwig + * @author Eddú Meléndez + * @author Stephane Nicoll + * @author Vedran Pavic + * @author Weix Sun + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass(Session.class) +@ConditionalOnWebApplication +@EnableConfigurationProperties({ ServerProperties.class, SessionProperties.class }) +public class SessionAutoConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnWebApplication(type = Type.SERVLET) + @Import(SessionRepositoryFilterConfiguration.class) + static class ServletSessionConfiguration { + + @Bean + @Conditional(DefaultCookieSerializerCondition.class) + DefaultCookieSerializer cookieSerializer(ServerProperties serverProperties, + ObjectProvider cookieSerializerCustomizers) { + Cookie cookie = serverProperties.getServlet().getSession().getCookie(); + DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(cookie::getName).to(cookieSerializer::setCookieName); + map.from(cookie::getDomain).to(cookieSerializer::setDomainName); + map.from(cookie::getPath).to(cookieSerializer::setCookiePath); + map.from(cookie::getHttpOnly).to(cookieSerializer::setUseHttpOnlyCookie); + map.from(cookie::getSecure).to(cookieSerializer::setUseSecureCookie); + map.from(cookie::getMaxAge).asInt(Duration::getSeconds).to(cookieSerializer::setCookieMaxAge); + map.from(cookie::getSameSite).as(SameSite::attributeValue).to(cookieSerializer::setSameSite); + map.from(cookie::getPartitioned).to(cookieSerializer::setPartitioned); + cookieSerializerCustomizers.orderedStream().forEach((customizer) -> customizer.customize(cookieSerializer)); + return cookieSerializer; + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(RememberMeServices.class) + static class RememberMeServicesConfiguration { + + @Bean + DefaultCookieSerializerCustomizer rememberMeServicesCookieSerializerCustomizer() { + return (cookieSerializer) -> cookieSerializer + .setRememberMeRequestAttribute(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR); + } + + } + + } + + /** + * Condition to trigger the creation of a {@link DefaultCookieSerializer}. This kicks + * in if either no {@link HttpSessionIdResolver} and {@link CookieSerializer} beans + * are registered, or if {@link CookieHttpSessionIdResolver} is registered but + * {@link CookieSerializer} is not. + */ + static class DefaultCookieSerializerCondition extends AnyNestedCondition { + + DefaultCookieSerializerCondition() { + super(ConfigurationPhase.REGISTER_BEAN); + } + + @ConditionalOnMissingBean({ HttpSessionIdResolver.class, CookieSerializer.class }) + static class NoComponentsAvailable { + + } + + @ConditionalOnBean(CookieHttpSessionIdResolver.class) + @ConditionalOnMissingBean(CookieSerializer.class) + static class CookieHttpSessionIdResolverAvailable { + + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java rename to spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionProperties.java index 3cfabc17824b..7fb5004e8bf2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.autoconfigure; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -34,7 +34,7 @@ * @author Tommy Ludwig * @author Stephane Nicoll * @author Vedran Pavic - * @since 1.4.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.session") public class SessionProperties { @@ -68,7 +68,6 @@ public void setServlet(Servlet servlet) { * {@code fallbackTimeout} is used. * @param fallbackTimeout a fallback timeout value if the timeout isn't configured * @return the session timeout - * @since 2.4.0 */ public Duration determineTimeout(Supplier fallbackTimeout) { return (this.timeout != null) ? this.timeout : fallbackTimeout.get(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionRepositoryFilterConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.java rename to spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionRepositoryFilterConfiguration.java index c2faf2fecf49..434c6fd133b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.java +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/SessionRepositoryFilterConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.autoconfigure; import java.util.EnumSet; import java.util.stream.Collectors; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/endpoint/SessionsEndpointAutoConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointAutoConfiguration.java rename to spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/endpoint/SessionsEndpointAutoConfiguration.java index e244210124ed..841d883d3dc7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/endpoint/SessionsEndpointAutoConfiguration.java @@ -14,12 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.session; +package org.springframework.boot.session.autoconfigure.endpoint; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.session.ReactiveSessionsEndpoint; -import org.springframework.boot.actuate.session.SessionsEndpoint; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -27,7 +25,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration; +import org.springframework.boot.session.autoconfigure.SessionAutoConfiguration; +import org.springframework.boot.session.endpoint.ReactiveSessionsEndpoint; +import org.springframework.boot.session.endpoint.SessionsEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.session.FindByIndexNameSessionRepository; @@ -40,10 +40,10 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link SessionsEndpoint}. * * @author Vedran Pavic - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = SessionAutoConfiguration.class) -@ConditionalOnClass(Session.class) +@ConditionalOnClass({ Session.class, SessionsEndpoint.class, ConditionalOnAvailableEndpoint.class }) @ConditionalOnAvailableEndpoint(SessionsEndpoint.class) public class SessionsEndpointAutoConfiguration { diff --git a/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/endpoint/package-info.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/endpoint/package-info.java new file mode 100644 index 000000000000..f5f86eed51d9 --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Session endpoint. + */ +package org.springframework.boot.session.autoconfigure.endpoint; diff --git a/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/package-info.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/package-info.java new file mode 100644 index 000000000000..6dc9ff08257e --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Session. + */ +package org.springframework.boot.session.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpoint.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpoint.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpoint.java rename to spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpoint.java index 6f303620b905..6de8cddc6bec 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpoint.java +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpoint.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.session; +package org.springframework.boot.session.endpoint; import reactor.core.publisher.Mono; @@ -22,7 +22,7 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.Selector; -import org.springframework.boot.actuate.session.SessionsDescriptor.SessionDescriptor; +import org.springframework.boot.session.endpoint.SessionsDescriptor.SessionDescriptor; import org.springframework.session.ReactiveFindByIndexNameSessionRepository; import org.springframework.session.ReactiveSessionRepository; import org.springframework.session.Session; @@ -34,7 +34,7 @@ * * @author Vedran Pavic * @author Moritz Halbritter - * @since 3.3.0 + * @since 4.0.0 */ @Endpoint(id = "sessions") public class ReactiveSessionsEndpoint { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/SessionsDescriptor.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/SessionsDescriptor.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/SessionsDescriptor.java rename to spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/SessionsDescriptor.java index b6ea3910350a..0a6eaafd5181 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/SessionsDescriptor.java +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/SessionsDescriptor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.session; +package org.springframework.boot.session.endpoint; import java.time.Instant; import java.util.List; @@ -28,7 +28,7 @@ * Description of user's {@link Session sessions}. * * @author Moritz Halbritter - * @since 3.3.0 + * @since 4.0.0 */ public final class SessionsDescriptor implements OperationResponseBody { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/SessionsEndpoint.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/SessionsEndpoint.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/SessionsEndpoint.java rename to spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/SessionsEndpoint.java index ab896019a65d..1324be0258fa 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/session/SessionsEndpoint.java +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/SessionsEndpoint.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.session; +package org.springframework.boot.session.endpoint; import java.util.Map; @@ -22,7 +22,7 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.Selector; -import org.springframework.boot.actuate.session.SessionsDescriptor.SessionDescriptor; +import org.springframework.boot.session.endpoint.SessionsDescriptor.SessionDescriptor; import org.springframework.session.FindByIndexNameSessionRepository; import org.springframework.session.Session; import org.springframework.session.SessionRepository; @@ -33,7 +33,7 @@ * Servlet stack. * * @author Vedran Pavic - * @since 2.0.0 + * @since 4.0.0 */ @Endpoint(id = "sessions") public class SessionsEndpoint { @@ -46,7 +46,6 @@ public class SessionsEndpoint { * Create a new {@link SessionsEndpoint} instance. * @param sessionRepository the session repository * @param indexedSessionRepository the indexed session repository - * @since 3.3.0 */ public SessionsEndpoint(SessionRepository sessionRepository, FindByIndexNameSessionRepository indexedSessionRepository) { diff --git a/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/package-info.java b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/package-info.java new file mode 100644 index 000000000000..8dc6b6a01d71 --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/main/java/org/springframework/boot/session/endpoint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator endpoint for Spring Session. + */ +package org.springframework.boot.session.endpoint; diff --git a/spring-boot-project/spring-boot-session/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-session/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..db8128cf7afc --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,12 @@ +{ + "properties": [ + { + "name": "spring.session.servlet.filter-dispatcher-types", + "defaultValue": [ + "async", + "error", + "request" + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-session/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-session/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..a07a84eafb5d --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.session.autoconfigure.SessionAutoConfiguration +org.springframework.boot.session.autoconfigure.endpoint.SessionsEndpointAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationEarlyInitializationIntegrationTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationEarlyInitializationIntegrationTests.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationEarlyInitializationIntegrationTests.java rename to spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationEarlyInitializationIntegrationTests.java index 513be3dbae56..360abcde2b7b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationEarlyInitializationIntegrationTests.java +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationEarlyInitializationIntegrationTests.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.autoconfigure; import java.util.LinkedHashMap; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -52,7 +52,7 @@ void configurationIsFrozenWhenSessionRepositoryAccessed() { @Configuration(proxyBeanMethods = false) @EnableSpringHttpSession - @ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, SessionAutoConfiguration.class }) + @ImportAutoConfiguration({ TomcatServletWebServerAutoConfiguration.class, SessionAutoConfiguration.class }) static class TestConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationTests.java similarity index 82% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java rename to spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationTests.java index 7bd93a78884c..91650bd17f8c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.session; +package org.springframework.boot.session.autoconfigure; import java.util.Collections; @@ -24,24 +24,15 @@ import org.mockito.InOrder; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.session.MapSessionRepository; -import org.springframework.session.ReactiveMapSessionRepository; -import org.springframework.session.SessionRepository; import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; -import org.springframework.session.config.annotation.web.server.EnableSpringWebSession; -import org.springframework.session.data.mongo.MongoIndexedSessionRepository; -import org.springframework.session.data.redis.RedisIndexedSessionRepository; -import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository; -import org.springframework.session.jdbc.JdbcIndexedSessionRepository; import org.springframework.session.security.web.authentication.SpringSessionRememberMeServices; import org.springframework.session.web.http.CookieHttpSessionIdResolver; import org.springframework.session.web.http.DefaultCookieSerializer; @@ -63,39 +54,11 @@ * @author Stephane Nicoll * @author Vedran Pavic */ -class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTests { +class SessionAutoConfigurationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class)); - @Test - void autoConfigurationDisabledIfNoImplementationMatches() { - this.contextRunner - .withClassLoader(new FilteredClassLoader(RedisIndexedSessionRepository.class, - HazelcastIndexedSessionRepository.class, JdbcIndexedSessionRepository.class, - MongoIndexedSessionRepository.class)) - .run((context) -> assertThat(context).doesNotHaveBean(SessionRepository.class)); - } - - @Test - void backOffIfSessionRepositoryIsPresent() { - this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> { - MapSessionRepository repository = validateSessionRepository(context, MapSessionRepository.class); - assertThat(context).getBean("mySessionRepository").isSameAs(repository); - }); - } - - @Test - void backOffIfReactiveSessionRepositoryIsPresent() { - ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class)); - contextRunner.withUserConfiguration(ReactiveSessionRepositoryConfiguration.class).run((context) -> { - ReactiveMapSessionRepository repository = validateSessionRepository(context, - ReactiveMapSessionRepository.class); - assertThat(context).getBean("mySessionRepository").isSameAs(repository); - }); - } - @Test void filterIsRegisteredWithAsyncErrorAndRequestDispatcherTypes() { this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> { @@ -247,17 +210,6 @@ MapSessionRepository mySessionRepository() { } - @Configuration(proxyBeanMethods = false) - @EnableSpringWebSession - static class ReactiveSessionRepositoryConfiguration { - - @Bean - ReactiveMapSessionRepository mySessionRepository() { - return new ReactiveMapSessionRepository(Collections.emptyMap()); - } - - } - @EnableConfigurationProperties(ServerProperties.class) static class ServerPropertiesConfiguration { diff --git a/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationWithoutSecurityTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationWithoutSecurityTests.java new file mode 100644 index 000000000000..22db789d88f5 --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionAutoConfigurationWithoutSecurityTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.autoconfigure; + +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.testsupport.classpath.ClassPathExclusions; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.session.MapSessionRepository; +import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; +import org.springframework.session.web.http.DefaultCookieSerializer; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SessionAutoConfiguration} when Spring Security is not on the + * classpath. + * + * @author Vedran Pavic + */ +@ClassPathExclusions("spring-security-*") +class SessionAutoConfigurationWithoutSecurityTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class)); + + @Test + void sessionCookieConfigurationIsAppliedToAutoConfiguredCookieSerializer() { + this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> { + DefaultCookieSerializer cookieSerializer = context.getBean(DefaultCookieSerializer.class); + assertThat(cookieSerializer).hasFieldOrPropertyWithValue("rememberMeRequestAttribute", null); + }); + } + + @Configuration(proxyBeanMethods = false) + @EnableSpringHttpSession + static class SessionRepositoryConfiguration { + + @Bean + MapSessionRepository mySessionRepository() { + return new MapSessionRepository(Collections.emptyMap()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionPropertiesTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionPropertiesTests.java new file mode 100644 index 000000000000..d67d97723f5e --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/SessionPropertiesTests.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.autoconfigure; + +import java.time.Duration; +import java.util.function.Supplier; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import org.springframework.core.Ordered; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link SessionProperties}. + * + * @author Stephane Nicoll + */ +class SessionPropertiesTests { + + private final SessionProperties properties = new SessionProperties(); + + @Test + @SuppressWarnings("unchecked") + void determineTimeoutWithTimeoutIgnoreFallback() { + this.properties.setTimeout(Duration.ofMinutes(1)); + Supplier fallback = mock(Supplier.class); + assertThat(this.properties.determineTimeout(fallback)).isEqualTo(Duration.ofMinutes(1)); + then(fallback).shouldHaveNoInteractions(); + } + + @Test + void determineTimeoutWithNoTimeoutUseFallback() { + this.properties.setTimeout(null); + Duration fallback = Duration.ofMinutes(2); + assertThat(this.properties.determineTimeout(() -> fallback)).isSameAs(fallback); + } + + @Test + void defaultFilterOrderIsCloseToHighestPrecedence() { + assertThat(this.properties.getServlet().getFilterOrder()).isCloseTo(Ordered.HIGHEST_PRECEDENCE, + Assertions.within(50)); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/endpoint/SessionsEndpointAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointAutoConfigurationTests.java rename to spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/endpoint/SessionsEndpointAutoConfigurationTests.java index b28faf74327f..a587c7633f2e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/session/SessionsEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/autoconfigure/endpoint/SessionsEndpointAutoConfigurationTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.session; +package org.springframework.boot.session.autoconfigure.endpoint; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.session.ReactiveSessionsEndpoint; -import org.springframework.boot.actuate.session.SessionsEndpoint; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.session.endpoint.ReactiveSessionsEndpoint; +import org.springframework.boot.session.endpoint.SessionsEndpoint; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpointTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpointTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpointTests.java rename to spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpointTests.java index 32c521d72471..d8d3609e5fe3 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpointTests.java +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpointTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.session; +package org.springframework.boot.session.endpoint; import java.time.Duration; import java.util.Collections; @@ -24,7 +24,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import org.springframework.boot.actuate.session.SessionsDescriptor.SessionDescriptor; +import org.springframework.boot.session.endpoint.SessionsDescriptor.SessionDescriptor; import org.springframework.session.MapSession; import org.springframework.session.ReactiveFindByIndexNameSessionRepository; import org.springframework.session.ReactiveSessionRepository; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpointWebIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpointWebIntegrationTests.java index 2ec25c8b1d34..c0d2596a9122 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/ReactiveSessionsEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/ReactiveSessionsEndpointWebIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.session; +package org.springframework.boot.session.endpoint; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/SessionsEndpointTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/SessionsEndpointTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/SessionsEndpointTests.java rename to spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/SessionsEndpointTests.java index 1cd4dad209c4..9d3a23eb3c5d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/SessionsEndpointTests.java +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/SessionsEndpointTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.session; +package org.springframework.boot.session.endpoint; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.session.SessionsDescriptor.SessionDescriptor; +import org.springframework.boot.session.endpoint.SessionsDescriptor.SessionDescriptor; import org.springframework.session.FindByIndexNameSessionRepository; import org.springframework.session.MapSession; import org.springframework.session.Session; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/SessionsEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/SessionsEndpointWebIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/SessionsEndpointWebIntegrationTests.java rename to spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/SessionsEndpointWebIntegrationTests.java index 1d93a12738a3..93eebd271fd2 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/session/SessionsEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-session/src/test/java/org/springframework/boot/session/endpoint/SessionsEndpointWebIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.session; +package org.springframework.boot.session.endpoint; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-session/src/testFixtures/java/org/springframework/boot/session/autoconfigure/AbstractReactiveSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session/src/testFixtures/java/org/springframework/boot/session/autoconfigure/AbstractReactiveSessionAutoConfigurationTests.java new file mode 100644 index 000000000000..f1be4c8b359b --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/testFixtures/java/org/springframework/boot/session/autoconfigure/AbstractReactiveSessionAutoConfigurationTests.java @@ -0,0 +1,105 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.autoconfigure; + +import java.util.Collections; +import java.util.function.Consumer; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; +import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.session.ReactiveMapSessionRepository; +import org.springframework.session.ReactiveSessionRepository; +import org.springframework.session.config.annotation.web.server.EnableSpringWebSession; +import org.springframework.web.server.WebSession; +import org.springframework.web.server.session.WebSessionManager; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Base class for Spring Session auto-configuration tests when the backing store is + * reactive. + * + * @author Andy Wilkinson + */ +public abstract class AbstractReactiveSessionAutoConfigurationTests { + + private static final MockReactiveWebServerFactory mockReactiveWebServerFactory = new MockReactiveWebServerFactory(); + + protected ReactiveWebApplicationContextRunner contextRunner; + + @Test + void backOffIfReactiveSessionRepositoryIsPresent() { + this.contextRunner.withUserConfiguration(ReactiveSessionRepositoryConfiguration.class).run((context) -> { + ReactiveMapSessionRepository repository = validateSessionRepository(context, + ReactiveMapSessionRepository.class); + assertThat(context).getBean("mySessionRepository").isSameAs(repository); + }); + } + + protected ContextConsumer assertExchangeWithSession( + Consumer exchange) { + return (context) -> { + MockServerHttpRequest request = MockServerHttpRequest.get("/").build(); + MockServerWebExchange webExchange = MockServerWebExchange.from(request); + WebSessionManager webSessionManager = context.getBean(WebSessionManager.class); + WebSession webSession = webSessionManager.getSession(webExchange).block(); + webSession.start(); + webExchange.getResponse().setComplete().block(); + exchange.accept(webExchange); + }; + } + + protected > T validateSessionRepository( + AssertableReactiveWebApplicationContext context, Class type) { + assertThat(context).hasSingleBean(WebSessionManager.class); + assertThat(context).hasSingleBean(ReactiveSessionRepository.class); + ReactiveSessionRepository repository = context.getBean(ReactiveSessionRepository.class); + assertThat(repository).as("Wrong session repository type").isInstanceOf(type); + return type.cast(repository); + } + + @Configuration(proxyBeanMethods = false) + protected static class ReactiveWebServerConfiguration { + + @Bean + MockReactiveWebServerFactory mockReactiveWebServerFactory() { + return mockReactiveWebServerFactory; + } + + } + + @Configuration(proxyBeanMethods = false) + @EnableSpringWebSession + static class ReactiveSessionRepositoryConfiguration { + + @Bean + ReactiveMapSessionRepository mySessionRepository() { + return new ReactiveMapSessionRepository(Collections.emptyMap()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-session/src/testFixtures/java/org/springframework/boot/session/autoconfigure/AbstractSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-session/src/testFixtures/java/org/springframework/boot/session/autoconfigure/AbstractSessionAutoConfigurationTests.java new file mode 100644 index 000000000000..bb9ed83da5d7 --- /dev/null +++ b/spring-boot-project/spring-boot-session/src/testFixtures/java/org/springframework/boot/session/autoconfigure/AbstractSessionAutoConfigurationTests.java @@ -0,0 +1,74 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.session.autoconfigure; + +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.session.MapSessionRepository; +import org.springframework.session.SessionRepository; +import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; +import org.springframework.session.web.http.SessionRepositoryFilter; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Base class for Spring Session auto-configuration tests when the backing store cannot be + * reactive. + * + * @author Stephane Nicoll + * @author Weix Sun + * @see AbstractReactiveSessionAutoConfigurationTests + */ +public abstract class AbstractSessionAutoConfigurationTests { + + protected WebApplicationContextRunner contextRunner; + + @Test + void backOffIfSessionRepositoryIsPresent() { + this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> { + MapSessionRepository repository = validateSessionRepository(context, MapSessionRepository.class); + assertThat(context).getBean("mySessionRepository").isSameAs(repository); + }); + } + + protected > T validateSessionRepository(AssertableWebApplicationContext context, + Class type) { + assertThat(context).hasSingleBean(SessionRepositoryFilter.class); + assertThat(context).hasSingleBean(SessionRepository.class); + SessionRepository repository = context.getBean(SessionRepository.class); + assertThat(repository).as("Wrong session repository type").isInstanceOf(type); + return type.cast(repository); + } + + @Configuration + @EnableSpringHttpSession + static class SessionRepositoryConfiguration { + + @Bean + MapSessionRepository mySessionRepository() { + return new MapSessionRepository(Collections.emptyMap()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-sql/build.gradle b/spring-boot-project/spring-boot-sql/build.gradle new file mode 100644 index 000000000000..5150f617cc12 --- /dev/null +++ b/spring-boot-project/spring-boot-sql/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "java-test-fixtures" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot SQL" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testFixturesImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testFixturesImplementation("org.springframework:spring-tx") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/ApplicationScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/ApplicationScriptDatabaseInitializer.java new file mode 100644 index 000000000000..19167fafa768 --- /dev/null +++ b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/ApplicationScriptDatabaseInitializer.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.sql.autoconfigure.init; + +import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer; +import org.springframework.boot.sql.init.DatabaseInitializationSettings; +import org.springframework.context.annotation.ImportRuntimeHints; + +/** + * Marker interface for a script-based database initializer that initializes the + * application's database. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 4.0.0 + * @see AbstractScriptDatabaseInitializer + */ +@ImportRuntimeHints(SqlInitializationScriptsRuntimeHints.class) +public interface ApplicationScriptDatabaseInitializer { + + /** + * Adapts {@link SqlInitializationProperties} to + * {@link DatabaseInitializationSettings}. + * @param properties the properties to adapt + * @return the settings + */ + static DatabaseInitializationSettings getSettings(SqlInitializationProperties properties) { + return SettingsCreator.createFrom(properties); + } + +} diff --git a/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/ConditionalOnSqlInitialization.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/ConditionalOnSqlInitialization.java new file mode 100644 index 000000000000..4aa8d3cc3453 --- /dev/null +++ b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/ConditionalOnSqlInitialization.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.sql.autoconfigure.init; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.boot.sql.init.DatabaseInitializationMode; +import org.springframework.context.annotation.Conditional; + +/** + * Condition that matches when {@code spring.sql.init.mode} is set to a value other than + * {@link DatabaseInitializationMode#NEVER}. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 4.0.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Conditional(OnSqlInitializationCondition.class) +public @interface ConditionalOnSqlInitialization { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/OnDatabaseInitializationCondition.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/OnDatabaseInitializationCondition.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/OnDatabaseInitializationCondition.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/OnDatabaseInitializationCondition.java index 3a322910690d..2e9069bfa172 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/OnDatabaseInitializationCondition.java +++ b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/OnDatabaseInitializationCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sql.init; +package org.springframework.boot.sql.autoconfigure.init; import java.util.Locale; @@ -32,7 +32,7 @@ * be considered. * * @author Stephane Nicoll - * @since 2.6.2 + * @since 4.0.0 * @see DatabaseInitializationMode */ public abstract class OnDatabaseInitializationCondition extends SpringBootCondition { diff --git a/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/OnSqlInitializationCondition.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/OnSqlInitializationCondition.java new file mode 100644 index 000000000000..949b63905345 --- /dev/null +++ b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/OnSqlInitializationCondition.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.sql.autoconfigure.init; + +import org.springframework.context.annotation.Condition; + +/** + * {@link Condition} implementation for {@link ConditionalOnSqlInitialization}. + * + * @author Andy Wilkinson + * @author Phillip Webb + */ +class OnSqlInitializationCondition extends OnDatabaseInitializationCondition { + + OnSqlInitializationCondition() { + super("SQL Initialization", "spring.sql.init.mode"); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SettingsCreator.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SettingsCreator.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SettingsCreator.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SettingsCreator.java index bcb956b1d400..1912271b5a0e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SettingsCreator.java +++ b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SettingsCreator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sql.init; +package org.springframework.boot.sql.autoconfigure.init; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationProperties.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationProperties.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationProperties.java index dcfdf2c234d1..ac3444e97701 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationProperties.java +++ b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sql.init; +package org.springframework.boot.sql.autoconfigure.init; import java.nio.charset.Charset; import java.util.List; @@ -27,7 +27,7 @@ * database. * * @author Andy Wilkinson - * @since 2.5.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.sql.init") public class SqlInitializationProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationScriptsRuntimeHints.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationScriptsRuntimeHints.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationScriptsRuntimeHints.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationScriptsRuntimeHints.java index fba704795291..9526def869d2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationScriptsRuntimeHints.java +++ b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationScriptsRuntimeHints.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sql.init; +package org.springframework.boot.sql.autoconfigure.init; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; diff --git a/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/package-info.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/package-info.java new file mode 100644 index 000000000000..08af5cdc63bb --- /dev/null +++ b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/autoconfigure/init/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for basic script-based initialization of an SQL database. + */ +package org.springframework.boot.sql.autoconfigure.init; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializer.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializer.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/DatabaseInitializationMode.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/DatabaseInitializationMode.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/DatabaseInitializationMode.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/DatabaseInitializationMode.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/DatabaseInitializationSettings.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/DatabaseInitializationSettings.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/DatabaseInitializationSettings.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/DatabaseInitializationSettings.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/AbstractBeansOfTypeDatabaseInitializerDetector.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/AbstractBeansOfTypeDatabaseInitializerDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/AbstractBeansOfTypeDatabaseInitializerDetector.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/AbstractBeansOfTypeDatabaseInitializerDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/AbstractBeansOfTypeDependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/AbstractBeansOfTypeDependsOnDatabaseInitializationDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/AbstractBeansOfTypeDependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/AbstractBeansOfTypeDependsOnDatabaseInitializationDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/AnnotationDependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/AnnotationDependsOnDatabaseInitializationDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/AnnotationDependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/AnnotationDependsOnDatabaseInitializationDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/BeansOfTypeDetector.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/BeansOfTypeDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/BeansOfTypeDetector.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/BeansOfTypeDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurer.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurer.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/DatabaseInitializerDetector.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/DatabaseInitializerDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/DatabaseInitializerDetector.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/DatabaseInitializerDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/DependsOnDatabaseInitialization.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/DependsOnDatabaseInitialization.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/DependsOnDatabaseInitialization.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/DependsOnDatabaseInitialization.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/DependsOnDatabaseInitializationDetector.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/DependsOnDatabaseInitializationDetector.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/DependsOnDatabaseInitializationDetector.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/DependsOnDatabaseInitializationDetector.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/package-info.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/dependency/package-info.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/dependency/package-info.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/package-info.java b/spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/sql/init/package-info.java rename to spring-boot-project/spring-boot-sql/src/main/java/org/springframework/boot/sql/init/package-info.java diff --git a/spring-boot-project/spring-boot-sql/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-sql/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..c7df526ef4eb --- /dev/null +++ b/spring-boot-project/spring-boot-sql/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,38 @@ +{ + "properties": [ + { + "name": "spring.sql.init.enabled", + "type": "java.lang.Boolean", + "description": "Whether basic script-based initialization of an SQL database is enabled.", + "defaultValue": true, + "deprecation": { + "replacement": "spring.sql.init.mode", + "level": "warning" + } + } + ], + "hints": [ + { + "name": "spring.sql.init.data-locations", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "java.util.List" + } + } + ] + }, + { + "name": "spring.sql.init.schema-locations", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "java.util.List" + } + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-sql/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-sql/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..735af3fc681c --- /dev/null +++ b/spring-boot-project/spring-boot-sql/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Depends On Database Initialization Detectors +org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ +org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/simple-jndi b/spring-boot-project/spring-boot-sql/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/simple-jndi rename to spring-boot-project/spring-boot-sql/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/OnDatabaseInitializationConditionTests.java b/spring-boot-project/spring-boot-sql/src/test/java/org/springframework/boot/sql/autoconfigure/init/OnDatabaseInitializationConditionTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/OnDatabaseInitializationConditionTests.java rename to spring-boot-project/spring-boot-sql/src/test/java/org/springframework/boot/sql/autoconfigure/init/OnDatabaseInitializationConditionTests.java index 87496b047dab..be15b6188bff 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/OnDatabaseInitializationConditionTests.java +++ b/spring-boot-project/spring-boot-sql/src/test/java/org/springframework/boot/sql/autoconfigure/init/OnDatabaseInitializationConditionTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sql.init; +package org.springframework.boot.sql.autoconfigure.init; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationScriptsRuntimeHintsTests.java b/spring-boot-project/spring-boot-sql/src/test/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationScriptsRuntimeHintsTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationScriptsRuntimeHintsTests.java rename to spring-boot-project/spring-boot-sql/src/test/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationScriptsRuntimeHintsTests.java index cf76f9818761..7f3658863d20 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/sql/init/SqlInitializationScriptsRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-sql/src/test/java/org/springframework/boot/sql/autoconfigure/init/SqlInitializationScriptsRuntimeHintsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.sql.init; +package org.springframework.boot.sql.autoconfigure.init; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurerTests.java b/spring-boot-project/spring-boot-sql/src/test/java/org/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurerTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurerTests.java rename to spring-boot-project/spring-boot-sql/src/test/java/org/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurerTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializerTests.java b/spring-boot-project/spring-boot-sql/src/testFixtures/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializerTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializerTests.java rename to spring-boot-project/spring-boot-sql/src/testFixtures/java/org/springframework/boot/sql/init/AbstractScriptDatabaseInitializerTests.java diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-activemq/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-activemq/build.gradle index 3a7f5d8801f5..45fd5892c462 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-activemq/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-activemq/build.gradle @@ -22,6 +22,5 @@ description = "Starter for JMS messaging using Apache ActiveMQ" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework:spring-jms") - api("org.apache.activemq:activemq-client") + api(project(":spring-boot-project:spring-boot-activemq")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle index c34502e36d97..19ed5e74e4f1 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle @@ -21,8 +21,11 @@ plugins { description = "Starter for using Spring Boot's Actuator which provides production ready features to help you monitor and manage your application" dependencies { - api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + api(project(":spring-boot-project:spring-boot-health")) + api(project(":spring-boot-project:spring-boot-metrics")) + api(project(":spring-boot-project:spring-boot-tracing")) + api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api("io.micrometer:micrometer-observation") api("io.micrometer:micrometer-jakarta9") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-amqp/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-amqp/build.gradle index ad5d72c0b218..9be3645ba950 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-amqp/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-amqp/build.gradle @@ -22,6 +22,5 @@ description = "Starter for using Spring AMQP and Rabbit MQ" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework:spring-messaging") - api("org.springframework.amqp:spring-rabbit") + api(project(":spring-boot-project:spring-boot-amqp")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-artemis/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-artemis/build.gradle index cc531740ce24..3ec51045b09a 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-artemis/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-artemis/build.gradle @@ -22,6 +22,5 @@ description = "Starter for JMS messaging using Apache Artemis" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework:spring-jms") - api("org.apache.activemq:artemis-jakarta-client") + api(project(":spring-boot-project:spring-boot-artemis")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-batch/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-batch/build.gradle index 066fc29d2137..e802ac43ff30 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-batch/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-batch/build.gradle @@ -21,7 +21,7 @@ plugins { description = "Starter for using Spring Batch" dependencies { + api(project(":spring-boot-project:spring-boot-batch")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc")) - api("org.springframework.batch:spring-batch-core") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-cache/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-cache/build.gradle index 35a0955b17b3..2dfea954acaf 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-cache/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-cache/build.gradle @@ -22,5 +22,5 @@ description = "Starter for using Spring Framework's caching support" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework:spring-context-support") + api(project(":spring-boot-project:spring-boot-cache")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-cassandra-reactive/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-cassandra-reactive/build.gradle index 25b20dcfc4a9..9bd399803c1d 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-cassandra-reactive/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-cassandra-reactive/build.gradle @@ -21,8 +21,8 @@ plugins { description = "Starter for using Cassandra distributed database and Spring Data Cassandra Reactive" dependencies { + api(project(":spring-boot-project:spring-boot-data-cassandra")) + api(project(":spring-boot-project:spring-boot-reactor")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework:spring-tx") - api("org.springframework.data:spring-data-cassandra") - api("io.projectreactor:reactor-core") + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-cassandra/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-cassandra/build.gradle index 9ba78c0c43c4..27f4c4c97866 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-cassandra/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-cassandra/build.gradle @@ -22,6 +22,6 @@ description = "Starter for using Cassandra distributed database and Spring Data dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework:spring-tx") - api("org.springframework.data:spring-data-cassandra") + api(project(":spring-boot-project:spring-boot-data-cassandra")) + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-couchbase-reactive/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-couchbase-reactive/build.gradle index 4465bb31a0a8..507dbab02b70 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-couchbase-reactive/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-couchbase-reactive/build.gradle @@ -21,7 +21,8 @@ plugins { description = "Starter for using Couchbase document-oriented database and Spring Data Couchbase Reactive" dependencies { + api(project(":spring-boot-project:spring-boot-data-couchbase")) + api(project(":spring-boot-project:spring-boot-reactor")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("io.projectreactor:reactor-core") - api("org.springframework.data:spring-data-couchbase") + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-couchbase/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-couchbase/build.gradle index e0eebbc84f3a..ccd0a5a62d9a 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-couchbase/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-couchbase/build.gradle @@ -22,5 +22,6 @@ description = "Starter for using Couchbase document-oriented database and Spring dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.data:spring-data-couchbase") + api(project(":spring-boot-project:spring-boot-data-couchbase")) + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-elasticsearch/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-elasticsearch/build.gradle index c7ad91fd6c7d..b2d756e8c434 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-elasticsearch/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-elasticsearch/build.gradle @@ -22,7 +22,8 @@ description = "Starter for using Elasticsearch search and analytics engine and S dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.data:spring-data-elasticsearch") + api(project(":spring-boot-project:spring-boot-data-elasticsearch")) + api(project(":spring-boot-project:spring-boot-tx")) runtimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-jdbc/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-jdbc/build.gradle index a5dfdbf8ccbe..242d7694caea 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-jdbc/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-jdbc/build.gradle @@ -22,5 +22,5 @@ description = "Starter for using Spring Data JDBC" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc")) - api("org.springframework.data:spring-data-jdbc") + api(project(":spring-boot-project:spring-boot-data-jdbc")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-jpa/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-jpa/build.gradle index 44e8362009f3..7cdca51d7cb1 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-jpa/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-jpa/build.gradle @@ -21,9 +21,7 @@ plugins { description = "Starter for using Spring Data JPA with Hibernate" dependencies { + api(project(":spring-boot-project:spring-boot-data-jpa")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc")) - api("org.hibernate.orm:hibernate-core") - api("org.springframework.data:spring-data-jpa") - api("org.springframework:spring-aspects") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-ldap/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-ldap/build.gradle index 2fc303099677..8876a2c007fe 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-ldap/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-ldap/build.gradle @@ -22,5 +22,6 @@ description = "Starter for using Spring Data LDAP" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.data:spring-data-ldap") + api(project(":spring-boot-project:spring-boot-data-ldap")) + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb-reactive/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb-reactive/build.gradle index e6cc33c82481..657a3c44e5d9 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb-reactive/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb-reactive/build.gradle @@ -21,8 +21,9 @@ plugins { description = "Starter for using MongoDB document-oriented database and Spring Data MongoDB Reactive" dependencies { + api(project(":spring-boot-project:spring-boot-data-mongodb")) + api(project(":spring-boot-project:spring-boot-reactor")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("io.projectreactor:reactor-core") + api(project(":spring-boot-project:spring-boot-tx")) api("org.mongodb:mongodb-driver-reactivestreams") - api("org.springframework.data:spring-data-mongodb") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb/build.gradle index 42d448401a0d..bd966a1206bf 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb/build.gradle @@ -21,7 +21,8 @@ plugins { description = "Starter for using MongoDB document-oriented database and Spring Data MongoDB" dependencies { + api(project(":spring-boot-project:spring-boot-data-mongodb")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) + api(project(":spring-boot-project:spring-boot-tx")) api("org.mongodb:mongodb-driver-sync") - api("org.springframework.data:spring-data-mongodb") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-neo4j/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-neo4j/build.gradle index c2063a4cb6ea..85c251f6852c 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-neo4j/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-neo4j/build.gradle @@ -22,5 +22,5 @@ description = "Starter for using Neo4j graph database and Spring Data Neo4j" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.data:spring-data-neo4j") + api(project(":spring-boot-project:spring-boot-data-neo4j")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-r2dbc/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-r2dbc/build.gradle index eba2a91f0d69..c71edf0a7765 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-r2dbc/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-r2dbc/build.gradle @@ -22,7 +22,6 @@ description = "Starter for using Spring Data R2DBC" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.data:spring-data-r2dbc") - api("io.r2dbc:r2dbc-spi") - api("io.r2dbc:r2dbc-pool") + api(project(":spring-boot-project:spring-boot-data-r2dbc")) + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-redis-reactive/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-redis-reactive/build.gradle index 7993806ca79a..fd0fd7460616 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-redis-reactive/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-redis-reactive/build.gradle @@ -21,8 +21,8 @@ plugins { description = "Starter for using Redis key-value data store with Spring Data Redis reactive and the Lettuce client" dependencies { + api(project(":spring-boot-project:spring-boot-data-redis")) + api(project(":spring-boot-project:spring-boot-reactor")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("io.lettuce:lettuce-core") - api("io.projectreactor:reactor-core") - api("org.springframework.data:spring-data-redis") + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-redis/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-redis/build.gradle index d6c31bfc0032..9a6a3e78f56f 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-redis/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-redis/build.gradle @@ -21,7 +21,7 @@ plugins { description = "Starter for using Redis key-value data store with Spring Data Redis and the Lettuce client" dependencies { + api(project(":spring-boot-project:spring-boot-data-redis")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("io.lettuce:lettuce-core") - api("org.springframework.data:spring-data-redis") + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-rest/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-rest/build.gradle index 81a62270bde7..49d103dc68ce 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-rest/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-rest/build.gradle @@ -22,5 +22,7 @@ description = "Starter for exposing Spring Data repositories over REST using Spr dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - api("org.springframework.data:spring-data-rest-webmvc") + api(project(":spring-boot-project:spring-boot-data-commons")) + api(project(":spring-boot-project:spring-boot-data-rest")) + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-freemarker/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-freemarker/build.gradle index cc07a85cfe6d..ede70f9480f8 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-freemarker/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-freemarker/build.gradle @@ -22,6 +22,5 @@ description = "Starter for building MVC web applications using FreeMarker views" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.freemarker:freemarker") - api("org.springframework:spring-context-support") + api(project(":spring-boot-project:spring-boot-freemarker")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-graphql/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-graphql/build.gradle index 04bfb9e37a80..f37809b2ce03 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-graphql/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-graphql/build.gradle @@ -21,7 +21,7 @@ plugins { description = "Starter for building GraphQL applications with Spring GraphQL" dependencies { + api(project(":spring-boot-project:spring-boot-graphql")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json")) - api("org.springframework.graphql:spring-graphql") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-groovy-templates/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-groovy-templates/build.gradle index f85008f79f3d..6dea3799ba71 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-groovy-templates/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-groovy-templates/build.gradle @@ -21,6 +21,6 @@ plugins { description = "Starter for building MVC web applications using Groovy Templates views" dependencies { + api(project(":spring-boot-project:spring-boot-groovy-templates")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - api("org.apache.groovy:groovy-templates") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-hateoas/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-hateoas/build.gradle index e6216f117977..5436cf118342 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-hateoas/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-hateoas/build.gradle @@ -21,6 +21,6 @@ plugins { description = "Starter for building hypermedia-based RESTful web application with Spring MVC and Spring HATEOAS" dependencies { + api(project(":spring-boot-project:spring-boot-hateoas")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - api("org.springframework.hateoas:spring-hateoas") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-integration/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-integration/build.gradle index 67e6e085bb60..72ad16d440fe 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-integration/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-integration/build.gradle @@ -21,6 +21,7 @@ plugins { description = "Starter for using Spring Integration" dependencies { + api(project(":spring-boot-project:spring-boot-integration")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.integration:spring-integration-core") + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-jdbc/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-jdbc/build.gradle index af767d6c1a9e..169cdf968363 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-jdbc/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-jdbc/build.gradle @@ -22,6 +22,7 @@ description = "Starter for using JDBC with the HikariCP connection pool" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) + api(project(":spring-boot-project:spring-boot-jdbc")) + api(project(":spring-boot-project:spring-boot-tx")) api("com.zaxxer:HikariCP") - api("org.springframework:spring-jdbc") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-jersey/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-jersey/build.gradle index aabbb364f759..2f10ec8d597b 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-jersey/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-jersey/build.gradle @@ -21,18 +21,13 @@ plugins { description = "Starter for building RESTful web applications using JAX-RS and Jersey. An alternative to spring-boot-starter-web" dependencies { + api(project(":spring-boot-project:spring-boot-jersey")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-validation")) - api("org.springframework:spring-web") - api("org.glassfish.jersey.containers:jersey-container-servlet-core") - api("org.glassfish.jersey.containers:jersey-container-servlet") - api("org.glassfish.jersey.core:jersey-server") api("org.glassfish.jersey.ext:jersey-bean-validation") { exclude group: "jakarta.el", module: "jakarta.el-api" } - api("org.glassfish.jersey.ext:jersey-spring6") - api("org.glassfish.jersey.media:jersey-media-json-jackson") } checkRuntimeClasspathForConflicts { diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-jetty/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-jetty/build.gradle index c4470c94ca74..26c846f9c79d 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-jetty/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-jetty/build.gradle @@ -21,12 +21,11 @@ plugins { description = "Starter for using Jetty as the embedded servlet container. An alternative to spring-boot-starter-tomcat" dependencies { + api(project(":spring-boot-project:spring-boot-jetty")) api("jakarta.servlet:jakarta.servlet-api") api("jakarta.websocket:jakarta.websocket-api") api("jakarta.websocket:jakarta.websocket-client-api") api("org.apache.tomcat.embed:tomcat-embed-el") - api("org.eclipse.jetty.ee10:jetty-ee10-servlets") - api("org.eclipse.jetty.ee10:jetty-ee10-webapp") api("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server") { exclude group: "jakarta.el", module: "jakarta.el-api" exclude group: "org.eclipse.jetty", module: "jetty-jndi" diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-jooq/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-jooq/build.gradle index 868b2c739035..0659bc74e09a 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-jooq/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-jooq/build.gradle @@ -22,6 +22,5 @@ description = "Starter for using jOOQ to access SQL databases with JDBC. An alte dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc")) - api("org.springframework:spring-tx") - api("org.jooq:jooq") + api(project(":spring-boot-project:spring-boot-jooq")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-json/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-json/build.gradle index 077f33f77853..84fd2ca62b36 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-json/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-json/build.gradle @@ -22,6 +22,7 @@ description = "Starter for reading and writing json" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) + api(project(":spring-boot-project:spring-boot-jackson")) api("org.springframework:spring-web") api("com.fasterxml.jackson.core:jackson-databind") api("com.fasterxml.jackson.datatype:jackson-datatype-jdk8") diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-mail/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-mail/build.gradle index 330958ec5641..e076e961f7bf 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-mail/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-mail/build.gradle @@ -22,6 +22,5 @@ description = "Starter for using Java Mail and Spring Framework's email sending dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework:spring-context-support") - api("org.eclipse.angus:jakarta.mail") + api(project(":spring-boot-project:spring-boot-mail")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-mustache/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-mustache/build.gradle index d09f2f9838f9..ceaf24ca6b8b 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-mustache/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-mustache/build.gradle @@ -22,5 +22,5 @@ description = "Starter for building web applications using Mustache views" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("com.samskivert:jmustache") + api(project(":spring-boot-project:spring-boot-mustache")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-authorization-server/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-authorization-server/build.gradle index e3083cfb5f7a..a5177602b3f1 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-authorization-server/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-authorization-server/build.gradle @@ -21,6 +21,7 @@ plugins { description = "Starter for using Spring Authorization Server features" dependencies { + api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - api("org.springframework.security:spring-security-oauth2-authorization-server") + api(project(":spring-boot-project:spring-boot-security-oauth2-authorization-server")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-client/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-client/build.gradle index fdb07e7dc9be..71800142d1f1 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-client/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-client/build.gradle @@ -21,9 +21,7 @@ plugins { description = "Starter for using Spring Security's OAuth2/OpenID Connect client features" dependencies { - api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.security:spring-security-config") - api("org.springframework.security:spring-security-core") - api("org.springframework.security:spring-security-oauth2-client") + api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) + api(project(":spring-boot-project:spring-boot-security-oauth2-client")) api("org.springframework.security:spring-security-oauth2-jose") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-resource-server/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-resource-server/build.gradle index 4ad53bb1443e..bd6d7a1e2897 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-resource-server/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-oauth2-resource-server/build.gradle @@ -21,9 +21,6 @@ plugins { description = "Starter for using Spring Security's OAuth2 resource server features" dependencies { - api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.security:spring-security-config") - api("org.springframework.security:spring-security-core") - api("org.springframework.security:spring-security-oauth2-resource-server") - api("org.springframework.security:spring-security-oauth2-jose") + api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) + api(project(":spring-boot-project:spring-boot-security-oauth2-resource-server")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-pulsar-reactive/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-pulsar-reactive/build.gradle index 672670780c8f..5eb5f9388aff 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-pulsar-reactive/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-pulsar-reactive/build.gradle @@ -22,6 +22,8 @@ description = "Starter for using Spring for Apache Pulsar Reactive" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) + api(project(":spring-boot-project:spring-boot-pulsar")) + api(project(":spring-boot-project:spring-boot-tx")) api("org.springframework.pulsar:spring-pulsar-reactive") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-pulsar/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-pulsar/build.gradle index f9e8a8952764..4c32618ecc81 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-pulsar/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-pulsar/build.gradle @@ -22,7 +22,8 @@ description = "Starter for using Spring for Apache Pulsar" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework.pulsar:spring-pulsar") + api(project(":spring-boot-project:spring-boot-pulsar")) + api(project(":spring-boot-project:spring-boot-tx")) } checkRuntimeClasspathForConflicts { diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-quartz/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-quartz/build.gradle index 936267776f2b..89816a745b38 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-quartz/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-quartz/build.gradle @@ -22,7 +22,6 @@ description = "Starter for using the Quartz scheduler" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.springframework:spring-context-support") - api("org.springframework:spring-tx") - api("org.quartz-scheduler:quartz") + api(project(":spring-boot-project:spring-boot-quartz")) + api(project(":spring-boot-project:spring-boot-tx")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-reactor-netty/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-reactor-netty/build.gradle index f014dd1c7bd2..9dcde144970f 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-reactor-netty/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-reactor-netty/build.gradle @@ -21,5 +21,5 @@ plugins { description = "Starter for using Reactor Netty as the embedded reactive HTTP server." dependencies { - api("io.projectreactor.netty:reactor-netty-http") + api(project(":spring-boot-project:spring-boot-reactor-netty")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-rsocket/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-rsocket/build.gradle index 2bad20b0a842..87af942cb2d7 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-rsocket/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-rsocket/build.gradle @@ -21,11 +21,10 @@ plugins { description = "Starter for building RSocket clients and servers" dependencies { + api(project(":spring-boot-project:spring-boot-rsocket")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-reactor-netty")) api("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor") - api("io.rsocket:rsocket-core") api("io.rsocket:rsocket-transport-netty") - api("org.springframework:spring-messaging") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-security/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-security/build.gradle index 4de34b71c857..4fd273bee2fd 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-security/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-security/build.gradle @@ -21,8 +21,7 @@ plugins { description = "Starter for using Spring Security" dependencies { + api(project(":spring-boot-project:spring-boot-security")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api("org.springframework:spring-aop") - api("org.springframework.security:spring-security-config") - api("org.springframework.security:spring-security-web") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-test/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-test/build.gradle index 1520572d39ec..28cfcb082247 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-test/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-test/build.gradle @@ -21,9 +21,13 @@ plugins { description = "Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito" dependencies { + api(project(":spring-boot-project:spring-boot-restclient")) + api(project(":spring-boot-project:spring-boot-restclient-test")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-test")) api(project(":spring-boot-project:spring-boot-test-autoconfigure")) + api(project(":spring-boot-project:spring-boot-web-server-test")) + api(project(":spring-boot-project:spring-boot-webclient")) api("com.jayway.jsonpath:json-path") api("jakarta.xml.bind:jakarta.xml.bind-api") api("net.minidev:json-smart") diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-thymeleaf/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-thymeleaf/build.gradle index cc2333c242b3..a3d544393791 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-thymeleaf/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-thymeleaf/build.gradle @@ -22,5 +22,5 @@ description = "Starter for building MVC web applications using Thymeleaf views" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.thymeleaf:thymeleaf-spring6") + api(project(":spring-boot-project:spring-boot-thymeleaf")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-tomcat/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-tomcat/build.gradle index 4b6e1d332c92..7b74047bed23 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-tomcat/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-tomcat/build.gradle @@ -21,10 +21,8 @@ plugins { description = "Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by spring-boot-starter-web" dependencies { + api(project(":spring-boot-project:spring-boot-tomcat")) api("jakarta.annotation:jakarta.annotation-api") - api("org.apache.tomcat.embed:tomcat-embed-core") { - exclude group: "org.apache.tomcat", module: "tomcat-annotations-api" - } api("org.apache.tomcat.embed:tomcat-embed-el") api("org.apache.tomcat.embed:tomcat-embed-websocket") { exclude group: "org.apache.tomcat", module: "tomcat-annotations-api" diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-undertow/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-undertow/build.gradle index e1fb6e5ca89e..05b0610de9b7 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-undertow/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-undertow/build.gradle @@ -21,7 +21,7 @@ plugins { description = "Starter for using Undertow as the embedded servlet container. An alternative to spring-boot-starter-tomcat" dependencies { - api("io.undertow:undertow-core") + api(project(":spring-boot-project:spring-boot-undertow")) api("io.undertow:undertow-servlet") api("io.undertow:undertow-websockets-jsr") api("org.apache.tomcat.embed:tomcat-embed-el") diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-validation/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-validation/build.gradle index b6ee7cf65f7a..d6d8ccc69d84 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-validation/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-validation/build.gradle @@ -22,6 +22,5 @@ description = "Starter for using Java Bean Validation with Hibernate Validator" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.apache.tomcat.embed:tomcat-embed-el") - api("org.hibernate.validator:hibernate-validator") + api(project(":spring-boot-project:spring-boot-validation")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-web-services/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-web-services/build.gradle index f3dbb8dc7b1e..29b5eaa39e66 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-web-services/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-web-services/build.gradle @@ -22,8 +22,7 @@ description = "Starter for using Spring Web Services" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) + api(project(":spring-boot-project:spring-boot-webservices")) api("com.sun.xml.messaging.saaj:saaj-impl") api("jakarta.xml.ws:jakarta.xml.ws-api") - api("org.springframework:spring-oxm") - api("org.springframework.ws:spring-ws-core") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-web/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-web/build.gradle index 90fe05a3aaf6..fdf2721b0926 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-web/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-web/build.gradle @@ -21,9 +21,9 @@ plugins { description = "Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container" dependencies { + api(project(":spring-boot-project:spring-boot-http-converter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat")) - api("org.springframework:spring-web") - api("org.springframework:spring-webmvc") + api(project(":spring-boot-project:spring-boot-webmvc")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-webflux/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-webflux/build.gradle index 1389f0175139..717ac57bec8a 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-webflux/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-webflux/build.gradle @@ -24,6 +24,5 @@ dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-reactor-netty")) - api("org.springframework:spring-web") - api("org.springframework:spring-webflux") + api(project(":spring-boot-project:spring-boot-webflux")) } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-websocket/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-websocket/build.gradle index 6b3af5e60684..63aaba4aa3a8 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-websocket/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-websocket/build.gradle @@ -22,6 +22,5 @@ description = "Starter for building WebSocket applications using Spring Framewor dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - api("org.springframework:spring-messaging") - api("org.springframework:spring-websocket") + api(project(":spring-boot-project:spring-boot-websocket")) } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle index 4078d23a6935..f456bbd6b22f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle @@ -23,14 +23,26 @@ plugins { description = "Spring Boot Test AutoConfigure" +configurations.all { + resolutionStrategy.eachDependency { + if (it.requested.group == 'org.opensaml') { + it.useVersion '4.0.1' + } + } +} + dependencies { api(project(":spring-boot-project:spring-boot")) - api(project(":spring-boot-project:spring-boot-test")) api(project(":spring-boot-project:spring-boot-autoconfigure")) + api(project(":spring-boot-project:spring-boot-test")) + + compileOnly("org.mockito:mockito-core") + dockerTestImplementation(project(":spring-boot-project:spring-boot-data-mongodb")) dockerTestImplementation(project(":spring-boot-project:spring-boot-docker-compose")) dockerTestImplementation(project(":spring-boot-project:spring-boot-testcontainers")) dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tx")) dockerTestImplementation("com.zaxxer:HikariCP") dockerTestImplementation("io.projectreactor:reactor-test") dockerTestImplementation("com.redis:testcontainers-redis") @@ -50,6 +62,50 @@ dependencies { dockerTestRuntimeOnly("io.lettuce:lettuce-core") dockerTestRuntimeOnly("org.springframework.data:spring-data-redis") + optional(project(":spring-boot-project:spring-boot-cache")) + optional(project(":spring-boot-project:spring-boot-data-cassandra")) + optional(project(":spring-boot-project:spring-boot-data-commons")) + optional(project(":spring-boot-project:spring-boot-data-couchbase")) + optional(project(":spring-boot-project:spring-boot-data-elasticsearch")) + optional(project(":spring-boot-project:spring-boot-data-jdbc")) + optional(project(":spring-boot-project:spring-boot-data-jpa")) + optional(project(":spring-boot-project:spring-boot-data-ldap")) + optional(project(":spring-boot-project:spring-boot-data-mongodb")) + optional(project(":spring-boot-project:spring-boot-data-neo4j")) + optional(project(":spring-boot-project:spring-boot-data-r2dbc")) + optional(project(":spring-boot-project:spring-boot-data-redis")) + optional(project(":spring-boot-project:spring-boot-flyway")) + optional(project(":spring-boot-project:spring-boot-graphql")) + optional(project(":spring-boot-project:spring-boot-groovy-templates")) + optional(project(":spring-boot-project:spring-boot-hateoas")) + optional(project(":spring-boot-project:spring-boot-http-converter")) + optional(project(":spring-boot-project:spring-boot-http-codec")) + optional(project(":spring-boot-project:spring-boot-jackson")) + optional(project(":spring-boot-project:spring-boot-jdbc")) + optional(project(":spring-boot-project:spring-boot-jooq")) + optional(project(":spring-boot-project:spring-boot-jsonb")) + optional(project(":spring-boot-project:spring-boot-liquibase")) { + exclude(group: "org.liquibase") + } + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-mongodb")) + optional(project(":spring-boot-project:spring-boot-observation")) + optional(project(":spring-boot-project:spring-boot-r2dbc")) + optional(project(":spring-boot-project:spring-boot-reactor-netty")) + optional(project(":spring-boot-project:spring-boot-restclient")) + optional(project(":spring-boot-project:spring-boot-restclient-test")) + optional(project(":spring-boot-project:spring-boot-security")) + optional(project(":spring-boot-project:spring-boot-security-oauth2-client")) + optional(project(":spring-boot-project:spring-boot-security-oauth2-resource-server")) + optional(project(":spring-boot-project:spring-boot-security-saml2")) + optional(project(":spring-boot-project:spring-boot-tracing")) + optional(project(":spring-boot-project:spring-boot-tx")) + optional(project(":spring-boot-project:spring-boot-validation")) + optional(project(":spring-boot-project:spring-boot-web-server-test")) + optional(project(":spring-boot-project:spring-boot-webclient")) + optional(project(":spring-boot-project:spring-boot-webflux")) + optional(project(":spring-boot-project:spring-boot-webmvc")) + optional(project(":spring-boot-project:spring-boot-webservices")) optional("jakarta.json.bind:jakarta.json.bind-api") optional("jakarta.persistence:jakarta.persistence-api") optional("jakarta.servlet:jakarta.servlet-api") @@ -68,18 +124,12 @@ dependencies { optional("org.springframework:spring-orm") optional("org.springframework:spring-test") optional("org.springframework:spring-web") - optional("org.springframework:spring-webmvc") optional("org.springframework:spring-webflux") - optional("org.springframework.data:spring-data-cassandra") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } optional("org.springframework.data:spring-data-couchbase") - optional("org.springframework.data:spring-data-elasticsearch") optional("org.springframework.data:spring-data-jdbc") optional("org.springframework.data:spring-data-jpa") optional("org.springframework.data:spring-data-ldap") optional("org.springframework.data:spring-data-mongodb") - optional("org.springframework.data:spring-data-neo4j") optional("org.springframework.data:spring-data-r2dbc") optional("org.springframework.data:spring-data-redis") optional("org.springframework.graphql:spring-graphql-test") @@ -97,7 +147,12 @@ dependencies { testImplementation(project(":spring-boot-project:spring-boot-actuator")) testImplementation(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + testImplementation(project(":spring-boot-project:spring-boot-freemarker")) + testImplementation(project(":spring-boot-project:spring-boot-gson")) + testImplementation(project(":spring-boot-project:spring-boot-mustache")) + testImplementation(project(":spring-boot-project:spring-boot-reactor")) testImplementation(project(":spring-boot-project:spring-boot-testcontainers")) + testImplementation(project(":spring-boot-project:spring-boot-thymeleaf")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation("ch.qos.logback:logback-classic") testImplementation("com.fasterxml.jackson.module:jackson-module-parameter-names") @@ -106,7 +161,6 @@ dependencies { testImplementation("io.lettuce:lettuce-core") testImplementation("io.micrometer:micrometer-registry-prometheus") testImplementation("io.projectreactor.netty:reactor-netty-http") - testImplementation("io.projectreactor:reactor-core") testImplementation("io.projectreactor:reactor-test") testImplementation("io.r2dbc:r2dbc-h2") testImplementation("jakarta.json:jakarta.json-api") @@ -114,31 +168,19 @@ dependencies { testImplementation("org.apache.tomcat.embed:tomcat-embed-el") testImplementation("org.aspectj:aspectjrt") testImplementation("org.aspectj:aspectjweaver") - testImplementation("org.assertj:assertj-core") - testImplementation("org.awaitility:awaitility") testImplementation("org.eclipse:yasson") testImplementation("org.hibernate.validator:hibernate-validator") testImplementation("org.hsqldb:hsqldb") testImplementation("org.jooq:jooq") - testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.junit.platform:junit-platform-engine") testImplementation("org.junit.platform:junit-platform-launcher") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.opensaml:opensaml-core:4.0.1") - testImplementation("org.opensaml:opensaml-saml-api:4.0.1") - testImplementation("org.opensaml:opensaml-saml-impl:4.0.1") - testImplementation("org.skyscreamer:jsonassert") - testImplementation("org.springframework:spring-core-test") testImplementation("org.springframework.hateoas:spring-hateoas") testImplementation("org.springframework.plugin:spring-plugin-core") testImplementation("org.springframework.security:spring-security-oauth2-client") - testImplementation("org.springframework.security:spring-security-saml2-service-provider") { - exclude group: "org.opensaml", module: "opensaml-core" - exclude group: "org.opensaml", module: "opensaml-saml-api" - exclude group: "org.opensaml", module: "opensaml-saml-impl" - } testImplementation("org.thymeleaf:thymeleaf") + + testRuntimeOnly(project(":spring-boot-project:spring-boot-tomcat")) + testRuntimeOnly("org.flywaydb:flyway-database-hsqldb") } configurations { diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseDockerComposeIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseDockerComposeIntegrationTests.java index 6f1e6594c138..9938863dade2 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseDockerComposeIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseDockerComposeIntegrationTests.java @@ -29,7 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabaseDockerComposeIntegrationTests.SetupDockerCompose; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseDynamicPropertySourceIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseDynamicPropertySourceIntegrationTests.java index c49db7c3568f..9aafdb25e6c3 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseDynamicPropertySourceIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseDynamicPropertySourceIntegrationTests.java @@ -26,7 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.testsupport.container.TestImage; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseNonTestDatabaseIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseNonTestDatabaseIntegrationTests.java index 7e9f7fe30530..94982c1940c6 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseNonTestDatabaseIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseNonTestDatabaseIntegrationTests.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabaseNonTestDatabaseIntegrationTests.SetupDatabase; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseServiceConnectionIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseServiceConnectionIntegrationTests.java index 7e26b21f71ff..0b7a1d37c073 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseServiceConnectionIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseServiceConnectionIntegrationTests.java @@ -26,7 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseTestcontainersJdbcUrlIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseTestcontainersJdbcUrlIntegrationTests.java index ad55cd70e465..3870569d6452 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseTestcontainersJdbcUrlIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/dockerTest/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabaseTestcontainersJdbcUrlIntegrationTests.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabaseTestcontainersJdbcUrlIntegrationTests.InitializeDatasourceUrl; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/ConditionReportApplicationContextFailureProcessor.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/ConditionReportApplicationContextFailureProcessor.java deleted file mode 100644 index 88d8b00b3491..000000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/ConditionReportApplicationContextFailureProcessor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.autoconfigure; - -import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport; -import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportMessage; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.context.ApplicationContextFailureProcessor; - -/** - * An {@link ApplicationContextFailureProcessor} that prints the - * {@link ConditionEvaluationReport} when the context cannot be prepared. - * - * @author Phillip Webb - * @author Scott Frederick - * @since 3.0.0 - * @deprecated in 3.2.11 for removal in 4.0.0 - */ -@Deprecated(since = "3.2.11", forRemoval = true) -public class ConditionReportApplicationContextFailureProcessor implements ApplicationContextFailureProcessor { - - @Override - public void processLoadFailure(ApplicationContext context, Throwable exception) { - if (context instanceof ConfigurableApplicationContext configurableContext) { - ConditionEvaluationReport report = ConditionEvaluationReport.get(configurableContext.getBeanFactory()); - System.err.println(new ConditionEvaluationReportMessage(report)); - } - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/AutoConfigureGraphQl.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/AutoConfigureGraphQl.java index a39914dfda3e..153cfb5a9fc5 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/AutoConfigureGraphQl.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/AutoConfigureGraphQl.java @@ -33,9 +33,9 @@ * @author Brian Clozel * @since 2.7.0 * @see GraphQlTest - * @see org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration - * @see org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration - * @see org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration + * @see org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration + * @see org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration + * @see org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilter.java index 8f9bdbd01829..4a8b0a412b34 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilter.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilter.java @@ -23,8 +23,8 @@ import graphql.execution.instrumentation.Instrumentation; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; import org.springframework.boot.context.TypeExcludeFilter; +import org.springframework.boot.graphql.autoconfigure.GraphQlSourceBuilderCustomizer; import org.springframework.boot.jackson.JsonComponent; import org.springframework.boot.test.autoconfigure.filter.StandardAnnotationCustomizableTypeExcludeFilter; import org.springframework.core.convert.converter.Converter; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfiguration.java index 86b3e54a9b66..692e6cdb3c1d 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfiguration.java @@ -24,8 +24,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.graphql.ExecutionGraphQlService; import org.springframework.graphql.test.tester.ExecutionGraphQlServiceTester; @@ -38,7 +37,7 @@ * @author Brian Clozel * @since 2.7.0 */ -@AutoConfiguration(after = { JacksonAutoConfiguration.class, GraphQlAutoConfiguration.class }) +@AutoConfiguration(after = GraphQlAutoConfiguration.class) @ConditionalOnClass({ GraphQL.class, GraphQlTester.class }) public class GraphQlTesterAutoConfiguration { diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/HttpGraphQlTesterAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/HttpGraphQlTesterAutoConfiguration.java index b69ef723ed98..e66c6bee210f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/HttpGraphQlTesterAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/HttpGraphQlTesterAutoConfiguration.java @@ -20,7 +20,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.graphql.GraphQlProperties; +import org.springframework.boot.graphql.autoconfigure.GraphQlProperties; import org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfiguration.java index 93663edf5ee0..54241d421ea2 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfiguration.java @@ -42,14 +42,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.container.ContainerImageMetadata; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.bind.BoundPropertiesTrackingBindHandler; import org.springframework.boot.context.properties.source.ConfigurationProperty; import org.springframework.boot.context.properties.source.ConfigurationPropertyName; import org.springframework.boot.jdbc.EmbeddedDatabaseConnection; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails; import org.springframework.boot.origin.PropertySourceOrigin; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; import org.springframework.context.EnvironmentAware; @@ -185,7 +185,7 @@ private boolean isAutoConfigured(BeanDefinitionHolder holder) { if (holder.getBeanDefinition() instanceof AnnotatedBeanDefinition annotatedBeanDefinition) { MethodMetadata factoryMethodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata(); return (factoryMethodMetadata != null) && (factoryMethodMetadata.getDeclaringClassName() - .startsWith("org.springframework.boot.autoconfigure.")); + .startsWith("org.springframework.boot.jdbc.autoconfigure.")); } return false; } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTestersAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTestersAutoConfiguration.java index 5d6546128def..5b9678e4a7d9 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTestersAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTestersAutoConfiguration.java @@ -38,9 +38,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration; import org.springframework.boot.test.json.AbstractJsonMarshalTester; import org.springframework.boot.test.json.BasicJsonTester; import org.springframework.boot.test.json.GsonTester; @@ -62,8 +59,9 @@ * @since 1.4.0 * @see AutoConfigureJsonTesters */ -@AutoConfiguration( - after = { JacksonAutoConfiguration.class, GsonAutoConfiguration.class, JsonbAutoConfiguration.class }) +@AutoConfiguration(afterName = { "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration", + "org.springframework.boot.jsonb.autoconfigure.JsonbAutoConfiguration", + "org.springframework.boot.gson.autoconfigure.GsonAutoConfiguration" }) @ConditionalOnClass(name = "org.assertj.core.api.Assert") @ConditionalOnBooleanProperty("spring.test.jsontesters.enabled") public class JsonTestersAutoConfiguration { diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestEntityManagerAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestEntityManagerAutoConfiguration.java index 2c61d3343c4e..a161ad1b87f9 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestEntityManagerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestEntityManagerAutoConfiguration.java @@ -21,7 +21,6 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.Bean; /** @@ -31,7 +30,7 @@ * @since 1.4.0 * @see AutoConfigureTestEntityManager */ -@AutoConfiguration(after = HibernateJpaAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration") @ConditionalOnClass({ EntityManagerFactory.class }) public class TestEntityManagerAutoConfiguration { diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsWebTestClientBuilderCustomizer.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsWebTestClientBuilderCustomizer.java index 08f8a2f33264..5058a289e466 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsWebTestClientBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsWebTestClientBuilderCustomizer.java @@ -16,7 +16,7 @@ package org.springframework.boot.test.autoconfigure.restdocs; -import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer; +import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.StringUtils; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServer.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServer.java index 949dfc4b27d3..9ae0f3e278c4 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServer.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServer.java @@ -24,10 +24,10 @@ import java.lang.annotation.Target; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.test.MockServerRestClientCustomizer; +import org.springframework.boot.restclient.test.MockServerRestTemplateCustomizer; import org.springframework.boot.test.autoconfigure.properties.PropertyMapping; -import org.springframework.boot.test.web.client.MockServerRestClientCustomizer; -import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestClient.Builder; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureWebClient.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureWebClient.java index 30c96f82956e..bd9971b2c510 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureWebClient.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureWebClient.java @@ -24,9 +24,9 @@ import java.lang.annotation.Target; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.autoconfigure.json.AutoConfigureJson; import org.springframework.boot.test.autoconfigure.properties.PropertyMapping; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.web.client.RestTemplate; /** diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/MockRestServiceServerAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/MockRestServiceServerAutoConfiguration.java index 227ff3fc494f..53142384e67e 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/MockRestServiceServerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/MockRestServiceServerAutoConfiguration.java @@ -24,8 +24,9 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.test.web.client.MockServerRestClientCustomizer; -import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.restclient.test.MockServerRestClientCustomizer; +import org.springframework.boot.restclient.test.MockServerRestTemplateCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpResponse; @@ -47,6 +48,7 @@ * @see AutoConfigureMockRestServiceServer */ @AutoConfiguration +@ConditionalOnClass(MockServerRestTemplateCustomizer.class) @ConditionalOnBooleanProperty("spring.test.webclient.mockrestserviceserver.enabled") public class MockRestServiceServerAutoConfiguration { diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTest.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTest.java index a9a02a5af6c3..0262d519ca01 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTest.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTest.java @@ -27,10 +27,10 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache; import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.ComponentScan; import org.springframework.core.annotation.AliasFor; import org.springframework.core.env.Environment; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/WebClientRestTemplateAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/WebClientRestTemplateAutoConfiguration.java index 7ba14a5e7c51..79d43195a676 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/WebClientRestTemplateAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/WebClientRestTemplateAutoConfiguration.java @@ -18,8 +18,8 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @@ -31,8 +31,9 @@ * @since 1.4.0 * @see AutoConfigureMockRestServiceServer */ -@AutoConfiguration(after = RestTemplateAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.restclient.autoconfigure.RestTemplateAutoConfiguration") @ConditionalOnBooleanProperty("spring.test.webclient.register-rest-template") +@ConditionalOnClass(RestTemplateBuilder.class) public class WebClientRestTemplateAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/SpringBootWebTestClientBuilderCustomizer.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/SpringBootWebTestClientBuilderCustomizer.java index 44e64d364669..0f9bbc4f1cf3 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/SpringBootWebTestClientBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/SpringBootWebTestClientBuilderCustomizer.java @@ -20,8 +20,8 @@ import java.util.Collection; import java.util.function.Consumer; -import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer; -import org.springframework.boot.web.codec.CodecCustomizer; +import org.springframework.boot.http.codec.CodecCustomizer; +import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient.Builder; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java index e10b74590866..bff5a96b89b0 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java @@ -23,12 +23,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer; -import org.springframework.boot.web.codec.CodecCustomizer; +import org.springframework.boot.http.codec.CodecCustomizer; +import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -44,7 +42,8 @@ * @author Andy Wilkinson * @since 2.0.0 */ -@AutoConfiguration(after = { CodecsAutoConfiguration.class, WebFluxAutoConfiguration.class }) +@AutoConfiguration(afterName = { "org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration", + "org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration" }) @ConditionalOnClass({ WebClient.class, WebTestClient.class }) @Import(WebTestClientSecurityConfiguration.class) @EnableConfigurationProperties diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcAutoConfiguration.java index 294a12288995..7183b02f412e 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcAutoConfiguration.java @@ -23,13 +23,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration; -import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcConfiguration.java index 629de161d84e..d34ea6779ede 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcConfiguration.java @@ -19,8 +19,8 @@ import java.util.List; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.webmvc.autoconfigure.WebMvcProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.web.servlet.DispatcherServletCustomizer; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcTesterConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcTesterConfiguration.java index 3c5ac39484e0..90e22d188055 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcTesterConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcTesterConfiguration.java @@ -19,7 +19,7 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.web.servlet.MockMvc; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcWebClientAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcWebClientAutoConfiguration.java index 683d4f5fa573..a149f24c9032 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcWebClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcWebClientAutoConfiguration.java @@ -23,7 +23,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.test.web.htmlunit.LocalHostWebClient; +import org.springframework.boot.web.server.test.htmlunit.LocalHostWebClient; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.test.web.servlet.MockMvc; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcWebDriverAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcWebDriverAutoConfiguration.java index 06a9a6d24685..b66e03714667 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcWebDriverAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcWebDriverAutoConfiguration.java @@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.test.web.htmlunit.webdriver.LocalHostWebConnectionHtmlUnitDriver; +import org.springframework.boot.web.server.test.htmlunit.webdriver.LocalHostWebConnectionHtmlUnitDriver; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.security.concurrent.DelegatingSecurityContextExecutor; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilter.java index 10fe1ec4ebf8..189fad867aeb 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilter.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilter.java @@ -21,13 +21,13 @@ import java.util.LinkedHashSet; import java.util.Set; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; import org.springframework.boot.context.TypeExcludeFilter; import org.springframework.boot.jackson.JsonComponent; import org.springframework.boot.test.autoconfigure.filter.StandardAnnotationCustomizableTypeExcludeFilter; import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.autoconfigure.WebMvcRegistrations; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.GenericConverter; import org.springframework.http.converter.HttpMessageConverter; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTemplateAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTemplateAutoConfiguration.java index bc2cf59adc5a..0d0b23a4de45 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTemplateAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTemplateAutoConfiguration.java @@ -20,7 +20,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration; +import org.springframework.boot.webservices.autoconfigure.client.WebServiceTemplateAutoConfiguration; import org.springframework.boot.webservices.client.WebServiceTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.ws.client.core.WebServiceTemplate; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability.imports index af374669f52f..9324b74a808f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability.imports @@ -1,13 +1,13 @@ # AutoConfigureObservability auto-configuration imports # Observation -org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration +org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration # Metrics -org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration -org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration +optional:org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration +optional:org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration +optional:org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration # Tracing -org.springframework.boot.actuate.autoconfigure.tracing.NoopTracerAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration +optional:org.springframework.boot.tracing.autoconfigure.NoopTracerAutoConfiguration +optional:org.springframework.boot.tracing.autoconfigure.MicrometerTracingAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache.imports index 4cd7501b5a5a..25dc15614b0c 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache.imports @@ -1,2 +1,2 @@ # AutoConfigureCache auto-configuration imports -org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration +optional:org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra.imports index 980f52b5ad41..108562156ead 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra.imports @@ -1,8 +1,8 @@ # AutoConfigureDataCassandra auto-configuration imports -org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration -org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration -org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration -org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration +org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration +org.springframework.boot.data.cassandra.autoconfigure.CassandraDataAutoConfiguration +org.springframework.boot.data.cassandra.autoconfigure.CassandraReactiveDataAutoConfiguration +org.springframework.boot.data.cassandra.autoconfigure.CassandraReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.cassandra.autoconfigure.CassandraRepositoriesAutoConfiguration org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.couchbase.AutoConfigureDataCouchbase.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.couchbase.AutoConfigureDataCouchbase.imports index bd6a6cc5c81c..3248ffc4a4bb 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.couchbase.AutoConfigureDataCouchbase.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.couchbase.AutoConfigureDataCouchbase.imports @@ -1,9 +1,9 @@ # AutoConfigureDataCouchbase auto-configuration imports -org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration -org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration -org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration -org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration +org.springframework.boot.couchbase.autoconfigure.CouchbaseAutoConfiguration +org.springframework.boot.data.couchbase.autoconfigure.CouchbaseDataAutoConfiguration +org.springframework.boot.data.couchbase.autoconfigure.CouchbaseReactiveDataAutoConfiguration +org.springframework.boot.data.couchbase.autoconfigure.CouchbaseReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.couchbase.autoconfigure.CouchbaseRepositoriesAutoConfiguration org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.elasticsearch.AutoConfigureDataElasticsearch.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.elasticsearch.AutoConfigureDataElasticsearch.imports index cebaf196db72..fdf9a3cfd60d 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.elasticsearch.AutoConfigureDataElasticsearch.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.elasticsearch.AutoConfigureDataElasticsearch.imports @@ -1,11 +1,11 @@ # AutoConfigureDataElasticsearch auto-configuration imports -org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration -org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration -org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration -org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration -org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration -org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration +org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchRepositoriesAutoConfiguration +org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchDataAutoConfiguration +org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchReactiveRepositoriesAutoConfiguration +org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration +org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration +org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchReactiveClientAutoConfiguration org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration +org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration +optional:org.springframework.boot.jsonb.autoconfigure.JsonbAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc.imports index eb4b3faada1b..fa0f7f3ee9ff 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc.imports @@ -1,11 +1,11 @@ # AutoConfigureDataJdbc auto-configuration imports -org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JdbcClientAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration -org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration -org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration +org.springframework.boot.data.jdbc.autoconfigure.JdbcRepositoriesAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JdbcClientAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration +optional:org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration +optional:org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap.imports index 508c529b5101..940387e7d100 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap.imports @@ -1,5 +1,5 @@ # AutoConfigureDataLdap auto-configuration imports -org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration -org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration +org.springframework.boot.data.ldap.autoconfigure.LdapRepositoriesAutoConfiguration +org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration +org.springframework.boot.ldap.autoconfigure.embedded.EmbeddedLdapAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports index cd75eda62b4a..6b03f9a6e94b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports @@ -1,10 +1,10 @@ # AutoConfigureDataMongo auto-configuration imports -org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration -org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration -org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration -org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveDataAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.mongodb.autoconfigure.MongoRepositoriesAutoConfiguration +org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration +org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j.imports index 96aef94577bd..53828c04f746 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j.imports @@ -1,8 +1,8 @@ # AutoConfigureDataNeo4j auto-configuration imports -org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration -org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration -org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration -org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration +org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration +org.springframework.boot.data.neo4j.autoconfigure.Neo4jDataAutoConfiguration +org.springframework.boot.data.neo4j.autoconfigure.Neo4jReactiveDataAutoConfiguration +org.springframework.boot.data.neo4j.autoconfigure.Neo4jReactiveRepositoriesAutoConfiguration +org.springframework.boot.data.neo4j.autoconfigure.Neo4jRepositoriesAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc.imports index 678494ab914a..7e81d4dce184 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc.imports @@ -1,10 +1,10 @@ # AutoConfigureDataR2dbc auto-configuration imports -org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration -org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration -org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration -org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration -org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration -org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration +org.springframework.boot.data.r2dbc.autoconfigure.R2dbcRepositoriesAutoConfiguration +org.springframework.boot.data.r2dbc.autoconfigure.R2dbcDataAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.R2dbcAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.R2dbcInitializationAutoConfiguration +org.springframework.boot.r2dbc.autoconfigure.R2dbcTransactionManagerAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration +optional:org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration +optional:org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis.imports index 2db18c955ff0..e7f14895517b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis.imports @@ -1,6 +1,6 @@ # AutoConfigureDataRedis auto-configuration imports -org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration -org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration -org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration +org.springframework.boot.data.redis.autoconfigure.RedisAutoConfiguration +org.springframework.boot.data.redis.autoconfigure.RedisReactiveAutoConfiguration +org.springframework.boot.data.redis.autoconfigure.RedisRepositoriesAutoConfiguration org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl.imports index c6f0c3e4e024..55d33aaff518 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl.imports @@ -1,4 +1,4 @@ # AutoConfigureGraphQl auto-configuration imports -org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration -org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration -org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration +optional:org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration +optional:org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration +org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc.imports index 480dcff0e7c1..5defb55be5d7 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc.imports @@ -1,10 +1,10 @@ # AutoConfigureJdbc auto-configuration imports -org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JdbcClientAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration -org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration -org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JdbcClientAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration +optional:org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration +optional:org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.imports index 53caeea39c35..d7148586622f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.imports @@ -1,4 +1,4 @@ # AutoConfigureTestDatabase auto-configuration imports +org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq.imports index 1e042e2c0858..853130bd8c34 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq.imports @@ -1,9 +1,9 @@ # AutoConfigureJooq auto-configuration imports -org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration -org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration -org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration -org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration +org.springframework.boot.jooq.autoconfigure.JooqAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration +optional:org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration +optional:org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson.imports index 13de5a9cc869..266fa78b1ace 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson.imports @@ -1,4 +1,4 @@ # AutoConfigureJson auto-configuration imports -org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration -org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration -org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration \ No newline at end of file +optional:org.springframework.boot.gson.autoconfigure.GsonAutoConfiguration +org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration +optional:org.springframework.boot.jsonb.autoconfigure.JsonbAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa.imports index 83465fdeba7e..833fac5056d5 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa.imports @@ -1,12 +1,12 @@ # AutoConfigureDataJpa auto-configuration imports -org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration -org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JdbcClientAutoConfiguration -org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration -org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration -org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration -org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration -org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration +org.springframework.boot.data.jpa.autoconfigure.JpaRepositoriesAutoConfiguration +org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JdbcClientAutoConfiguration +org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration +optional:org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration +optional:org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration optional:org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient.imports index c781adda6d14..5ae9ead0a859 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient.imports @@ -1,7 +1,7 @@ # AutoConfigureWebClient auto-configuration imports +optional:org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration +optional:org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration +optional:org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration +optional:org.springframework.boot.restclient.autoconfigure.RestTemplateAutoConfiguration +optional:org.springframework.boot.webclient.WebClientAutoConfiguration org.springframework.boot.test.autoconfigure.web.client.WebClientRestTemplateAutoConfiguration -org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration -org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration -org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration -org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports index 382c7a5e06e1..8f8cfbd395ac 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports @@ -1,9 +1,9 @@ # AutoConfigureWebFlux auto-configuration imports org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration -org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration -org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration -org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration -org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration -org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration -org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration \ No newline at end of file +optional:org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration +optional:org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration +optional:org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration +optional:org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration +optional:org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration +org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration +org.springframework.boot.webflux.autoconfigure.error.ErrorWebFluxAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient.imports index 593e8e6bdcfb..0c619da2da9b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient.imports @@ -1,7 +1,7 @@ # AutoConfigureWebClient auto-configuration imports -org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientWebSecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration -org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration +optional:org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration +optional:org.springframework.boot.security.autoconfigure.reactive.ReactiveUserDetailsServiceAutoConfiguration +optional:org.springframework.boot.security.oauth2.client.autoconfigure.reactive.ReactiveOAuth2ClientAutoConfiguration +optional:org.springframework.boot.security.oauth2.client.autoconfigure.reactive.ReactiveOAuth2ClientWebSecurityAutoConfiguration +optional:org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive.ReactiveOAuth2ResourceServerAutoConfiguration org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc.imports index 9aab9afb1180..524269ef0a78 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc.imports @@ -1,13 +1,13 @@ # AutoConfigureMockMvc auto-configuration imports +optional:org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration +optional:org.springframework.boot.security.autoconfigure.servlet.SecurityFilterAutoConfiguration +optional:org.springframework.boot.security.autoconfigure.servlet.UserDetailsServiceAutoConfiguration +optional:org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientAutoConfiguration +optional:org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration +optional:org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet.OAuth2ResourceServerAutoConfiguration +optional:org.springframework.boot.security.saml2.autoconfigure.Saml2RelyingPartyAutoConfiguration org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebDriverAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration -org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientWebSecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration -org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration -org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration -org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration org.springframework.boot.test.autoconfigure.web.servlet.MockMvcSecurityConfiguration org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports index 4d4a8ff4a870..bb75340455bb 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports @@ -1,14 +1,14 @@ # AutoConfigureWebMvc auto-configuration imports +optional:org.springframework.boot.data.autoconfigure.web.SpringDataWebAutoConfiguration +optional:org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration +optional:org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAutoConfiguration +optional:org.springframework.boot.hateoas.autoconfigure.HypermediaAutoConfiguration +optional:org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration +optional:org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration +optional:org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration +optional:org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration -org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration -org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration -org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration -org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration -org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration -org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration -org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration -org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration -org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration \ No newline at end of file +org.springframework.boot.servlet.autoconfigure.HttpEncodingAutoConfiguration +org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration +org.springframework.boot.webmvc.autoconfigure.error.ErrorMvcAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient.imports index 2c83655f0dc1..b3ca63de69a0 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient.imports @@ -1,3 +1,3 @@ # AutoConfigureWebServiceClient org.springframework.boot.test.autoconfigure.webservices.client.WebServiceClientTemplateAutoConfiguration -org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration \ No newline at end of file +org.springframework.boot.webservices.autoconfigure.client.WebServiceTemplateAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer.imports index cc7f617ba2b3..333a6d3c7aac 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer.imports @@ -1,2 +1,2 @@ # AutoConfigureWebServiceServer auto-configuration imports -org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration \ No newline at end of file +org.springframework.boot.webservices.autoconfigure.WebServicesAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ConditionReportApplicationContextFailureProcessorTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ConditionReportApplicationContextFailureProcessorTests.java deleted file mode 100644 index 16a33e5d44fd..000000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ConditionReportApplicationContextFailureProcessorTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.autoconfigure; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ConditionReportApplicationContextFailureProcessor}. - * - * @author Phillip Webb - * @author Scott Frederick - * @deprecated since 3.2.11 for removal in 4.0.0 - */ -@ExtendWith(OutputCaptureExtension.class) -@Deprecated(since = "3.2.11", forRemoval = true) -@SuppressWarnings("removal") -class ConditionReportApplicationContextFailureProcessorTests { - - @Test - void loadFailureShouldPrintReport(CapturedOutput output) { - SpringApplication application = new SpringApplication(TestConfig.class); - application.setWebApplicationType(WebApplicationType.NONE); - ConfigurableApplicationContext applicationContext = application.run(); - ConditionReportApplicationContextFailureProcessor processor = new ConditionReportApplicationContextFailureProcessor(); - processor.processLoadFailure(applicationContext, new IllegalStateException()); - assertThat(output).contains("CONDITIONS EVALUATION REPORT") - .contains("Positive matches") - .contains("Negative matches"); - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration(JacksonAutoConfiguration.class) - static class TestConfig { - - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactoryTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactoryTests.java index 7281a367c6e5..774e39b58f14 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactoryTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactoryTests.java @@ -21,7 +21,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/AutoConfigureObservabilitySpringBootApplication.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/AutoConfigureObservabilitySpringBootApplication.java index 57746ce22e24..dd9f3d3f6e73 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/AutoConfigureObservabilitySpringBootApplication.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/AutoConfigureObservabilitySpringBootApplication.java @@ -19,9 +19,9 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration; +import org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration; /** * Example {@link SpringBootApplication @SpringBootApplication} for use with diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/jdbc/DataJdbcTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/jdbc/DataJdbcTestIntegrationTests.java index b7f449b898d0..926d51296d87 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/jdbc/DataJdbcTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/jdbc/DataJdbcTestIntegrationTests.java @@ -22,8 +22,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilterTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilterTests.java index f5442bc2e91c..8d5a54a4f9d7 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilterTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilterTests.java @@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; +import org.springframework.boot.graphql.autoconfigure.GraphQlSourceBuilderCustomizer; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; import org.springframework.core.type.classreading.MetadataReader; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfigurationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfigurationTests.java index 4eed0c8e54e7..bb7f603c1fab 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfigurationTests.java @@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jdbc/JdbcTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jdbc/JdbcTestIntegrationTests.java index aa692259e3ce..4aed9ef36d01 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jdbc/JdbcTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jdbc/JdbcTestIntegrationTests.java @@ -24,8 +24,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jooq/JooqTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jooq/JooqTestIntegrationTests.java index d23a5bce81eb..0f2f18df1d9e 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jooq/JooqTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jooq/JooqTestIntegrationTests.java @@ -24,9 +24,9 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.cache.autoconfigure.CacheAutoConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.boot.test.autoconfigure.orm.jpa.ExampleComponent; import org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration; import org.springframework.context.ApplicationContext; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestersAutoConfigurationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestersAutoConfigurationTests.java index 9431fafa58c6..66e2a7ea8105 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestersAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestersAutoConfigurationTests.java @@ -24,9 +24,9 @@ import org.springframework.aot.hint.predicate.ReflectionHintsPredicates; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.aot.test.generate.TestGenerationContext; -import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration; +import org.springframework.boot.gson.autoconfigure.GsonAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jsonb.autoconfigure.JsonbAutoConfiguration; import org.springframework.boot.test.json.BasicJsonTester; import org.springframework.boot.test.json.GsonTester; import org.springframework.boot.test.json.JacksonTester; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/app/ExampleJsonApplication.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/app/ExampleJsonApplication.java index 8ea871c8e2a5..3262a4fbc9c1 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/app/ExampleJsonApplication.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/app/ExampleJsonApplication.java @@ -17,7 +17,7 @@ package org.springframework.boot.test.autoconfigure.json.app; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; import org.springframework.boot.test.autoconfigure.json.JsonTest; /** diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTestIntegrationTests.java index 0b94228e0b03..9ac8c052efb0 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/orm/jpa/DataJpaTestIntegrationTests.java @@ -22,8 +22,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnectionAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.data.repository.config.BootstrapMode; @@ -42,7 +42,7 @@ * @author Scott Frederick * @author Yanming Zhou */ -@DataJpaTest +@DataJpaTest(properties = "spring.jpa.hibernate.ddl-auto=create-drop") class DataJpaTestIntegrationTests { @Autowired diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/override/OverrideAutoConfigurationSpringBootApplication.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/override/OverrideAutoConfigurationSpringBootApplication.java index 9a2c3fc2c0c1..948dbaff13a5 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/override/OverrideAutoConfigurationSpringBootApplication.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/override/OverrideAutoConfigurationSpringBootApplication.java @@ -19,7 +19,7 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; /** diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java index 9c29da64e7af..9a0604d1ba3d 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java @@ -26,8 +26,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.BuildOutput; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java index 9840d3975204..c91fc2adf072 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java @@ -25,8 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.BuildOutput; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.util.FileSystemUtils; import static io.restassured.RestAssured.given; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsTestApplication.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsTestApplication.java index 9101dd5524c0..1fae47ae82d0 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsTestApplication.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsTestApplication.java @@ -16,10 +16,10 @@ package org.springframework.boot.test.autoconfigure.restdocs; -import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.security.autoconfigure.actuate.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; /** * Test application used with {@link AutoConfigureRestDocs @AutoConfigureRestDocs} tests. diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AnotherExampleRestTemplateService.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AnotherExampleRestTemplateService.java index a46ed931a325..9eaf059876f2 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AnotherExampleRestTemplateService.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AnotherExampleRestTemplateService.java @@ -16,7 +16,7 @@ package org.springframework.boot.test.autoconfigure.web.client; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerEnabledFalseIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerEnabledFalseIntegrationTests.java index 3e842ba16637..ab9b8f70f4c6 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerEnabledFalseIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerEnabledFalseIntegrationTests.java @@ -20,8 +20,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.client.MockServerRestClientCustomizer; -import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer; +import org.springframework.boot.restclient.test.MockServerRestClientCustomizer; +import org.springframework.boot.restclient.test.MockServerRestTemplateCustomizer; import org.springframework.context.ApplicationContext; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerWithRestClientIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerWithRestClientIntegrationTests.java index d204dbd3e421..66972f95cfd5 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerWithRestClientIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerWithRestClientIntegrationTests.java @@ -20,7 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerWithRestTemplateRootUriIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerWithRestTemplateRootUriIntegrationTests.java index 645e02038132..d322558adb75 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerWithRestTemplateRootUriIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServerWithRestTemplateRootUriIntegrationTests.java @@ -21,9 +21,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureWebClientWithRestTemplateIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureWebClientWithRestTemplateIntegrationTests.java index 1bfc39d26ea1..e9825625256b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureWebClientWithRestTemplateIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureWebClientWithRestTemplateIntegrationTests.java @@ -20,7 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/ExampleRestTemplateService.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/ExampleRestTemplateService.java index ddeaaddbfc04..13a265c30c90 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/ExampleRestTemplateService.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/ExampleRestTemplateService.java @@ -16,7 +16,7 @@ package org.springframework.boot.test.autoconfigure.web.client; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestNoComponentIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestNoComponentIntegrationTests.java index de950db88d88..f175c72385ec 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestNoComponentIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestNoComponentIntegrationTests.java @@ -20,7 +20,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.context.ApplicationContext; import org.springframework.http.MediaType; import org.springframework.test.web.client.MockRestServiceServer; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestClientTwoComponentsIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestClientTwoComponentsIntegrationTests.java index 540399cb28df..a358024bc591 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestClientTwoComponentsIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestClientTwoComponentsIntegrationTests.java @@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.client.MockServerRestClientCustomizer; +import org.springframework.boot.restclient.test.MockServerRestClientCustomizer; import org.springframework.http.MediaType; import org.springframework.test.web.client.MockRestServiceServer; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestTemplateAndRestClientTogetherIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestTemplateAndRestClientTogetherIntegrationTests.java index 4a278a76ea5e..93f8b07f1289 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestTemplateAndRestClientTogetherIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestTemplateAndRestClientTogetherIntegrationTests.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.client.MockServerRestClientCustomizer; -import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer; +import org.springframework.boot.restclient.test.MockServerRestClientCustomizer; +import org.springframework.boot.restclient.test.MockServerRestTemplateCustomizer; import org.springframework.http.MediaType; import org.springframework.test.web.client.MockRestServiceServer; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestTemplateTwoComponentsIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestTemplateTwoComponentsIntegrationTests.java index 9c583fb7a5f7..8cd8883e4f2e 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestTemplateTwoComponentsIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientTestRestTemplateTwoComponentsIntegrationTests.java @@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer; +import org.springframework.boot.restclient.test.MockServerRestTemplateCustomizer; import org.springframework.http.MediaType; import org.springframework.test.web.client.MockRestServiceServer; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientWithRestTemplateBuilderTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientWithRestTemplateBuilderTests.java index cceb838bf7e2..50146e9144f2 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientWithRestTemplateBuilderTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/client/RestClientWithRestTemplateBuilderTests.java @@ -18,7 +18,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestClient; import org.springframework.web.client.RestClient.Builder; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfigurationTests.java index ad68bc587ae6..d8cfed8cff77 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfigurationTests.java @@ -22,9 +22,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.web.codec.CodecCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleWebExceptionHandler.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleWebExceptionHandler.java index 0d14476f80f8..b318da5c0a7d 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleWebExceptionHandler.java @@ -19,7 +19,7 @@ import reactor.core.publisher.Mono; import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; -import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.boot.webflux.error.ErrorWebExceptionHandler; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleWebFluxApplication.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleWebFluxApplication.java index d1d0a3f1f374..2ad35523bfe3 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleWebFluxApplication.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleWebFluxApplication.java @@ -17,7 +17,7 @@ package org.springframework.boot.test.autoconfigure.web.reactive.webclient; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; /** diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestAutoConfigurationIntegrationTests.java index d39faecf309b..1b88bd34a79b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestAutoConfigurationIntegrationTests.java @@ -20,14 +20,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; -import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration; -import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration; -import org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; +import org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration; +import org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration; +import org.springframework.boot.security.oauth2.client.autoconfigure.reactive.ReactiveOAuth2ClientAutoConfiguration; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive.ReactiveOAuth2ResourceServerAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration; +import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.error.ErrorWebFluxAutoConfiguration; import org.springframework.context.ApplicationContext; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcAutoConfigurationTests.java index 6a619aee2e2f..f47f814e72ac 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcAutoConfigurationTests.java @@ -21,7 +21,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer; +import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/SpringBootMockMvcBuilderCustomizerTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/SpringBootMockMvcBuilderCustomizerTests.java index 60d56599c103..e361300dafd8 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/SpringBootMockMvcBuilderCustomizerTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/SpringBootMockMvcBuilderCustomizerTests.java @@ -38,8 +38,8 @@ import org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.DeferredLinesWriter; import org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.LinesWriter; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mock.web.MockServletContext; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestAutoConfigurationIntegrationTests.java index d149720fee5a..758e62c2aaed 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestAutoConfigurationIntegrationTests.java @@ -19,14 +19,14 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; -import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration; -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration; -import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; -import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration; +import org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration; +import org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAutoConfiguration; +import org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration; +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientAutoConfiguration; +import org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet.OAuth2ResourceServerAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.HttpEncodingAutoConfiguration; +import org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilterTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilterTests.java index eaabbe39a896..ed05356ed29f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilterTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilterTests.java @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; import org.thymeleaf.dialect.IDialect; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; +import org.springframework.boot.webmvc.autoconfigure.WebMvcRegistrations; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.FilterType; import org.springframework.core.type.classreading.MetadataReader; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/AfterSecurityFilter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/AfterSecurityFilter.java index 5e46fdd3f4c7..20e0f3b1944b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/AfterSecurityFilter.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/AfterSecurityFilter.java @@ -26,7 +26,7 @@ import jakarta.servlet.ServletResponse; import jakarta.servlet.http.HttpServletRequest; -import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.core.Ordered; /** diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleFilter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleFilter.java index e8655c95f47a..7fc4608a241d 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleFilter.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleFilter.java @@ -26,7 +26,7 @@ import jakarta.servlet.ServletResponse; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.security.autoconfigure.SecurityProperties; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleWebMvcApplication.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleWebMvcApplication.java index 62589f3eadec..91a2335297f4 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleWebMvcApplication.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleWebMvcApplication.java @@ -17,7 +17,7 @@ package org.springframework.boot.test.autoconfigure.web.servlet.mockmvc; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.cassandra.autoconfigure.CassandraAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; /** diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestAllControllersIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestAllControllersIntegrationTests.java index f31237a7e455..762bbd19c24b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestAllControllersIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestAllControllersIntegrationTests.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.assertj.MockMvcTester; import org.springframework.test.web.servlet.assertj.MvcTestResult; diff --git a/spring-boot-project/spring-boot-test/build.gradle b/spring-boot-project/spring-boot-test/build.gradle index e1124685279d..5900d9166927 100644 --- a/spring-boot-project/spring-boot-test/build.gradle +++ b/spring-boot-project/spring-boot-test/build.gradle @@ -15,7 +15,6 @@ */ plugins { - id "dev.adamko.dokkatoo-html" id "java-library" id "org.jetbrains.kotlin.jvm" id "org.springframework.boot.deployed" @@ -39,35 +38,25 @@ dependencies { optional("org.assertj:assertj-core") optional("org.hamcrest:hamcrest-core") optional("org.hamcrest:hamcrest-library") - optional("org.htmlunit:htmlunit") - optional("org.jetbrains.kotlin:kotlin-stdlib") - optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.junit.jupiter:junit-jupiter-api") optional("org.mockito:mockito-core") optional("org.skyscreamer:jsonassert") - optional("org.seleniumhq.selenium:htmlunit3-driver") { - exclude(group: "com.sun.activation", module: "jakarta.activation") - } - optional("org.seleniumhq.selenium:selenium-api") optional("org.springframework:spring-web") optional("org.springframework:spring-webflux") optional("org.springframework.graphql:spring-graphql-test") testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("ch.qos.logback:logback-classic") testImplementation("io.mockk:mockk") testImplementation("jakarta.json:jakarta.json-api") - testImplementation("ch.qos.logback:logback-classic") - testImplementation("org.apache.tomcat.embed:tomcat-embed-core") testImplementation("org.apache.groovy:groovy") testImplementation("org.apache.groovy:groovy-xml") testImplementation("org.eclipse:yasson") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-junit-jupiter") + testImplementation("org.jetbrains.kotlin:kotlin-reflect") + testImplementation("org.jetbrains.kotlin:kotlin-stdlib") testImplementation("org.slf4j:slf4j-api") testImplementation("org.spockframework:spock-core") testImplementation("org.springframework:spring-webmvc") - testImplementation("org.springframework:spring-core-test") - testImplementation("org.springframework:spring-test") testImplementation("org.testng:testng") testRuntimeOnly("org.junit.vintage:junit-vintage-engine") diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java index 14c706b75ba7..cf2d1abc62da 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java @@ -40,7 +40,7 @@ import org.springframework.boot.test.mock.web.SpringBootMockServletContext; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.test.util.TestPropertyValues.Type; -import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.GenericReactiveWebApplicationContext; import org.springframework.boot.web.servlet.support.ServletContextApplicationContextInitializer; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java index d3be00ee9253..9c20acadb700 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java @@ -29,9 +29,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.WebApplicationType; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.AliasFor; @@ -61,11 +59,7 @@ *

  • Provides support for different {@link #webEnvironment() webEnvironment} modes, * including the ability to start a fully running web server listening on a * {@link WebEnvironment#DEFINED_PORT defined} or {@link WebEnvironment#RANDOM_PORT - * random} port.
  • - *
  • Registers a {@link org.springframework.boot.test.web.client.TestRestTemplate - * TestRestTemplate} and/or - * {@link org.springframework.test.web.reactive.server.WebTestClient WebTestClient} bean - * for use in web tests that are using a fully running web server.
  • + * random} port when {@code spring-boot-web-server-test} is on the classpath. * * * @author Phillip Webb @@ -149,14 +143,16 @@ enum WebEnvironment { /** * Creates a web application context (reactive or servlet based) and sets a * {@code server.port=0} {@link Environment} property (which usually triggers - * listening on a random port). Often used in conjunction with a - * {@link LocalServerPort @LocalServerPort} injected field on the test. + * listening on a random port). Requires a dependency on + * {@code spring-boot-web-server-test}. Often used in conjunction with a + * {@code @LocalServerPort} injected field on the test. */ RANDOM_PORT(true), /** - * Creates a (reactive) web application context without defining any - * {@code server.port=0} {@link Environment} property. + * Creates a web application context (reactive or servlet based) without defining + * any {@code server.port=0} {@link Environment} property. Requires a dependency + * on {@code spring-boot-web-server-test}. */ DEFINED_PORT(true), @@ -174,8 +170,8 @@ enum WebEnvironment { } /** - * Return if the environment uses an {@link ServletWebServerApplicationContext}. - * @return if an {@link ServletWebServerApplicationContext} is used. + * Return if the environment uses an embedded web server. + * @return if an embedded web server is used */ public boolean isEmbedded() { return this.embedded; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/assertj/AssertableReactiveWebApplicationContext.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/assertj/AssertableReactiveWebApplicationContext.java index 4f200d6a691e..78a349d0ff86 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/assertj/AssertableReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/assertj/AssertableReactiveWebApplicationContext.java @@ -18,8 +18,8 @@ import java.util.function.Supplier; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; /** * A {@link ReactiveWebApplicationContext} that additionally supports AssertJ style diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java index 83002781eaed..aa1d621c2534 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java @@ -110,26 +110,10 @@ */ public abstract class AbstractApplicationContextRunner, C extends ConfigurableApplicationContext, A extends ApplicationContextAssertProvider> { - private static final Class[] NO_ADDITIONAL_CONTEXT_INTERFACES = {}; - private final RunnerConfiguration runnerConfiguration; private final Function, SELF> instanceFactory; - /** - * Create a new {@link AbstractApplicationContextRunner} instance. - * @param contextFactory the factory used to create the actual context - * @param instanceFactory the factory used to create new instance of the runner - * @since 2.6.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #AbstractApplicationContextRunner(Function, Supplier, Class...)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - protected AbstractApplicationContextRunner(Supplier contextFactory, - Function, SELF> instanceFactory) { - this(instanceFactory, contextFactory, NO_ADDITIONAL_CONTEXT_INTERFACES); - } - /** * Create a new {@link AbstractApplicationContextRunner} instance. * @param instanceFactory the factory used to create new instance of the runner diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java index 0c4c1227bd49..31ac625fb9bf 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java @@ -19,8 +19,8 @@ import java.util.function.Supplier; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.AnnotationConfigReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebApplicationContext; /** * An {@link AbstractApplicationContextRunner ApplicationContext runner} for a diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java index 13350107fe4f..79cf0ebf4a14 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java @@ -19,7 +19,7 @@ import java.util.function.Supplier; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.mock.web.MockServletContext; import org.springframework.web.context.ConfigurableWebApplicationContext; import org.springframework.web.context.WebApplicationContext; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/Definition.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/Definition.java deleted file mode 100644 index 5233676f998c..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/Definition.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.springframework.util.ObjectUtils; - -/** - * Base class for {@link MockDefinition} and {@link SpyDefinition}. - * - * @author Phillip Webb - * @see DefinitionsParser - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -abstract class Definition { - - private static final int MULTIPLIER = 31; - - private final String name; - - private final MockReset reset; - - private final boolean proxyTargetAware; - - private final QualifierDefinition qualifier; - - Definition(String name, MockReset reset, boolean proxyTargetAware, QualifierDefinition qualifier) { - this.name = name; - this.reset = (reset != null) ? reset : MockReset.AFTER; - this.proxyTargetAware = proxyTargetAware; - this.qualifier = qualifier; - } - - /** - * Return the name for bean. - * @return the name or {@code null} - */ - String getName() { - return this.name; - } - - /** - * Return the mock reset mode. - * @return the reset mode - */ - MockReset getReset() { - return this.reset; - } - - /** - * Return if AOP advised beans should be proxy target aware. - * @return if proxy target aware - */ - boolean isProxyTargetAware() { - return this.proxyTargetAware; - } - - /** - * Return the qualifier or {@code null}. - * @return the qualifier - */ - QualifierDefinition getQualifier() { - return this.qualifier; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || !getClass().isAssignableFrom(obj.getClass())) { - return false; - } - Definition other = (Definition) obj; - boolean result = true; - result = result && ObjectUtils.nullSafeEquals(this.name, other.name); - result = result && ObjectUtils.nullSafeEquals(this.reset, other.reset); - result = result && ObjectUtils.nullSafeEquals(this.proxyTargetAware, other.proxyTargetAware); - result = result && ObjectUtils.nullSafeEquals(this.qualifier, other.qualifier); - return result; - } - - @Override - public int hashCode() { - int result = 1; - result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.name); - result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.reset); - result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.proxyTargetAware); - result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.qualifier); - return result; - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/DefinitionsParser.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/DefinitionsParser.java deleted file mode 100644 index c004e4cbdf57..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/DefinitionsParser.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Field; -import java.lang.reflect.TypeVariable; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.springframework.core.ResolvableType; -import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - * Parser to create {@link MockDefinition} and {@link SpyDefinition} instances from - * {@link MockBean @MockBean} and {@link SpyBean @SpyBean} annotations declared on or in a - * class. - * - * @author Phillip Webb - * @author Stephane Nicoll - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class DefinitionsParser { - - private final Set definitions; - - private final Map definitionFields; - - DefinitionsParser() { - this(Collections.emptySet()); - } - - DefinitionsParser(Collection existing) { - this.definitions = new LinkedHashSet<>(); - this.definitionFields = new LinkedHashMap<>(); - if (existing != null) { - this.definitions.addAll(existing); - } - } - - void parse(Class source) { - parseElement(source, null); - ReflectionUtils.doWithFields(source, (element) -> parseElement(element, source)); - } - - private void parseElement(AnnotatedElement element, Class source) { - MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.SUPERCLASS); - annotations.stream(MockBean.class) - .map(MergedAnnotation::synthesize) - .forEach((annotation) -> parseMockBeanAnnotation(annotation, element, source)); - annotations.stream(SpyBean.class) - .map(MergedAnnotation::synthesize) - .forEach((annotation) -> parseSpyBeanAnnotation(annotation, element, source)); - } - - private void parseMockBeanAnnotation(MockBean annotation, AnnotatedElement element, Class source) { - Set typesToMock = getOrDeduceTypes(element, annotation.value(), source); - Assert.state(!typesToMock.isEmpty(), () -> "Unable to deduce type to mock from " + element); - if (StringUtils.hasLength(annotation.name())) { - Assert.state(typesToMock.size() == 1, "The name attribute can only be used when mocking a single class"); - } - for (ResolvableType typeToMock : typesToMock) { - MockDefinition definition = new MockDefinition(annotation.name(), typeToMock, annotation.extraInterfaces(), - annotation.answer(), annotation.serializable(), annotation.reset(), - QualifierDefinition.forElement(element)); - addDefinition(element, definition, "mock"); - } - } - - private void parseSpyBeanAnnotation(SpyBean annotation, AnnotatedElement element, Class source) { - Set typesToSpy = getOrDeduceTypes(element, annotation.value(), source); - Assert.state(!typesToSpy.isEmpty(), () -> "Unable to deduce type to spy from " + element); - if (StringUtils.hasLength(annotation.name())) { - Assert.state(typesToSpy.size() == 1, "The name attribute can only be used when spying a single class"); - } - for (ResolvableType typeToSpy : typesToSpy) { - SpyDefinition definition = new SpyDefinition(annotation.name(), typeToSpy, annotation.reset(), - annotation.proxyTargetAware(), QualifierDefinition.forElement(element)); - addDefinition(element, definition, "spy"); - } - } - - private void addDefinition(AnnotatedElement element, Definition definition, String type) { - boolean isNewDefinition = this.definitions.add(definition); - Assert.state(isNewDefinition, () -> "Duplicate " + type + " definition " + definition); - if (element instanceof Field field) { - this.definitionFields.put(definition, field); - } - } - - private Set getOrDeduceTypes(AnnotatedElement element, Class[] value, Class source) { - Set types = new LinkedHashSet<>(); - for (Class type : value) { - types.add(ResolvableType.forClass(type)); - } - if (types.isEmpty() && element instanceof Field field) { - types.add((field.getGenericType() instanceof TypeVariable) ? ResolvableType.forField(field, source) - : ResolvableType.forField(field)); - } - return types; - } - - Set getDefinitions() { - return Collections.unmodifiableSet(this.definitions); - } - - Field getField(Definition definition) { - return this.definitionFields.get(definition); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockBean.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockBean.java deleted file mode 100644 index 8bcd0edbefe5..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockBean.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.MockSettings; - -import org.springframework.context.ApplicationContext; -import org.springframework.core.annotation.AliasFor; -import org.springframework.test.context.junit4.SpringRunner; - -/** - * Annotation that can be used to add mocks to a Spring {@link ApplicationContext}. Can be - * used as a class level annotation or on fields in either {@code @Configuration} classes, - * or test classes that are {@link RunWith @RunWith} the {@link SpringRunner}. - *

    - * Mocks can be registered by type or by {@link #name() bean name}. When registered by - * type, any existing single bean of a matching type (including subclasses) in the context - * will be replaced by the mock. When registered by name, an existing bean can be - * specifically targeted for replacement by a mock. In either case, if no existing bean is - * defined a new one will be added. Dependencies that are known to the application context - * but are not beans (such as those - * {@link org.springframework.beans.factory.config.ConfigurableListableBeanFactory#registerResolvableDependency(Class, Object) - * registered directly}) will not be found and a mocked bean will be added to the context - * alongside the existing dependency. - *

    - * When {@code @MockBean} is used on a field, as well as being registered in the - * application context, the mock will also be injected into the field. Typical usage might - * be:

    - * @RunWith(SpringRunner.class)
    - * public class ExampleTests {
    - *
    - *     @MockBean
    - *     private ExampleService service;
    - *
    - *     @Autowired
    - *     private UserOfService userOfService;
    - *
    - *     @Test
    - *     public void testUserOfService() {
    - *         given(this.service.greet()).willReturn("Hello");
    - *         String actual = this.userOfService.makeUse();
    - *         assertEquals("Was: Hello", actual);
    - *     }
    - *
    - *     @Configuration
    - *     @Import(UserOfService.class) // A @Component injected with ExampleService
    - *     static class Config {
    - *     }
    - *
    - *
    - * }
    - * 
    If there is more than one bean of the requested type, qualifier metadata must be - * specified at field level:
    - * @RunWith(SpringRunner.class)
    - * public class ExampleTests {
    - *
    - *     @MockBean
    - *     @Qualifier("example")
    - *     private ExampleService service;
    - *
    - *     ...
    - * }
    - * 
    - *

    - * This annotation is {@code @Repeatable} and may be specified multiple times when working - * with Java 8 or contained within an {@link MockBeans @MockBeans} annotation. - * - * @author Phillip Webb - * @since 1.4.0 - * @see MockitoPostProcessor - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link org.springframework.test.context.bean.override.mockito.MockitoBean} - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@Target({ ElementType.TYPE, ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Repeatable(MockBeans.class) -public @interface MockBean { - - /** - * The name of the bean to register or replace. If not specified the name will either - * be generated or, if the mock replaces an existing bean, the existing name will be - * used. - * @return the name of the bean - */ - String name() default ""; - - /** - * The classes to mock. This is an alias of {@link #classes()} which can be used for - * brevity if no other attributes are defined. See {@link #classes()} for details. - * @return the classes to mock - */ - @AliasFor("classes") - Class[] value() default {}; - - /** - * The classes to mock. Each class specified here will result in a mock being created - * and registered with the application context. Classes can be omitted when the - * annotation is used on a field. - *

    - * When {@code @MockBean} also defines a {@code name} this attribute can only contain - * a single value. - *

    - * If this is the only specified attribute consider using the {@code value} alias - * instead. - * @return the classes to mock - */ - @AliasFor("value") - Class[] classes() default {}; - - /** - * Any extra interfaces that should also be declared on the mock. See - * {@link MockSettings#extraInterfaces(Class...)} for details. - * @return any extra interfaces - */ - Class[] extraInterfaces() default {}; - - /** - * The {@link Answers} type to use on the mock. - * @return the answer type - */ - Answers answer() default Answers.RETURNS_DEFAULTS; - - /** - * If the generated mock is serializable. See {@link MockSettings#serializable()} for - * details. - * @return if the mock is serializable - */ - boolean serializable() default false; - - /** - * The reset mode to apply to the mock bean. The default is {@link MockReset#AFTER} - * meaning that mocks are automatically reset after each test method is invoked. - * @return the reset mode - */ - MockReset reset() default MockReset.AFTER; - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockBeans.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockBeans.java deleted file mode 100644 index 95844a89c305..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockBeans.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Container annotation that aggregates several {@link MockBean @MockBean} annotations. - *

    - * Can be used natively, declaring several nested {@link MockBean @MockBean} annotations. - * Can also be used in conjunction with Java 8's support for repeatable - * annotations, where {@link MockBean @MockBean} can simply be declared several times - * on the same {@linkplain ElementType#TYPE type}, implicitly generating this container - * annotation. - * - * @author Phillip Webb - * @since 1.4.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link org.springframework.test.context.bean.override.mockito.MockitoBean} - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Documented -public @interface MockBeans { - - /** - * Return the contained {@link MockBean @MockBean} annotations. - * @return the mock beans - */ - MockBean[] value(); - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockDefinition.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockDefinition.java deleted file mode 100644 index 7a26511b4979..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockDefinition.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.mockito.Answers; -import org.mockito.MockSettings; - -import org.springframework.core.ResolvableType; -import org.springframework.core.style.ToStringCreator; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -import static org.mockito.Mockito.mock; - -/** - * A complete definition that can be used to create a Mockito mock. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockDefinition extends Definition { - - private static final int MULTIPLIER = 31; - - private final ResolvableType typeToMock; - - private final Set> extraInterfaces; - - private final Answers answer; - - private final boolean serializable; - - MockDefinition(String name, ResolvableType typeToMock, Class[] extraInterfaces, Answers answer, - boolean serializable, MockReset reset, QualifierDefinition qualifier) { - super(name, reset, false, qualifier); - Assert.notNull(typeToMock, "'typeToMock' must not be null"); - this.typeToMock = typeToMock; - this.extraInterfaces = asClassSet(extraInterfaces); - this.answer = (answer != null) ? answer : Answers.RETURNS_DEFAULTS; - this.serializable = serializable; - } - - private Set> asClassSet(Class[] classes) { - Set> classSet = new LinkedHashSet<>(); - if (classes != null) { - classSet.addAll(Arrays.asList(classes)); - } - return Collections.unmodifiableSet(classSet); - } - - /** - * Return the type that should be mocked. - * @return the type to mock; never {@code null} - */ - ResolvableType getTypeToMock() { - return this.typeToMock; - } - - /** - * Return the extra interfaces. - * @return the extra interfaces or an empty set - */ - Set> getExtraInterfaces() { - return this.extraInterfaces; - } - - /** - * Return the answers mode. - * @return the answers mode; never {@code null} - */ - Answers getAnswer() { - return this.answer; - } - - /** - * Return if the mock is serializable. - * @return if the mock is serializable - */ - boolean isSerializable() { - return this.serializable; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - MockDefinition other = (MockDefinition) obj; - boolean result = super.equals(obj); - result = result && ObjectUtils.nullSafeEquals(this.typeToMock, other.typeToMock); - result = result && ObjectUtils.nullSafeEquals(this.extraInterfaces, other.extraInterfaces); - result = result && ObjectUtils.nullSafeEquals(this.answer, other.answer); - result = result && this.serializable == other.serializable; - return result; - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.typeToMock); - result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.extraInterfaces); - result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.answer); - result = MULTIPLIER * result + Boolean.hashCode(this.serializable); - return result; - } - - @Override - public String toString() { - return new ToStringCreator(this).append("name", getName()) - .append("typeToMock", this.typeToMock) - .append("extraInterfaces", this.extraInterfaces) - .append("answer", this.answer) - .append("serializable", this.serializable) - .append("reset", getReset()) - .toString(); - } - - T createMock() { - return createMock(getName()); - } - - @SuppressWarnings("unchecked") - T createMock(String name) { - MockSettings settings = MockReset.withSettings(getReset()); - if (StringUtils.hasLength(name)) { - settings.name(name); - } - if (!this.extraInterfaces.isEmpty()) { - settings.extraInterfaces(ClassUtils.toClassArray(this.extraInterfaces)); - } - settings.defaultAnswer(this.answer); - if (this.serializable) { - settings.serializable(); - } - return (T) mock(this.typeToMock.resolve(), settings); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockReset.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockReset.java deleted file mode 100644 index e49f694e8568..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockReset.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.List; - -import org.mockito.MockSettings; -import org.mockito.MockingDetails; -import org.mockito.Mockito; -import org.mockito.listeners.InvocationListener; -import org.mockito.listeners.MethodInvocationReport; -import org.mockito.mock.MockCreationSettings; - -import org.springframework.util.Assert; - -/** - * Reset strategy used on a mock bean. Usually applied to a mock through the - * {@link MockBean @MockBean} annotation but can also be directly applied to any mock in - * the {@code ApplicationContext} using the static methods. - * - * @author Phillip Webb - * @since 1.4.0 - * @see ResetMocksTestExecutionListener - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link org.springframework.test.context.bean.override.mockito.MockReset} - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public enum MockReset { - - /** - * Reset the mock before the test method runs. - */ - BEFORE, - - /** - * Reset the mock after the test method runs. - */ - AFTER, - - /** - * Don't reset the mock. - */ - NONE; - - /** - * Create {@link MockSettings settings} to be used with mocks where reset should occur - * before each test method runs. - * @return mock settings - */ - public static MockSettings before() { - return withSettings(BEFORE); - } - - /** - * Create {@link MockSettings settings} to be used with mocks where reset should occur - * after each test method runs. - * @return mock settings - */ - public static MockSettings after() { - return withSettings(AFTER); - } - - /** - * Create {@link MockSettings settings} to be used with mocks where a specific reset - * should occur. - * @param reset the reset type - * @return mock settings - */ - public static MockSettings withSettings(MockReset reset) { - return apply(reset, Mockito.withSettings()); - } - - /** - * Apply {@link MockReset} to existing {@link MockSettings settings}. - * @param reset the reset type - * @param settings the settings - * @return the configured settings - */ - public static MockSettings apply(MockReset reset, MockSettings settings) { - Assert.notNull(settings, "'settings' must not be null"); - if (reset != null && reset != NONE) { - settings.invocationListeners(new ResetInvocationListener(reset)); - } - return settings; - } - - /** - * Get the {@link MockReset} associated with the given mock. - * @param mock the source mock - * @return the reset type (never {@code null}) - */ - static MockReset get(Object mock) { - MockReset reset = MockReset.NONE; - MockingDetails mockingDetails = Mockito.mockingDetails(mock); - if (mockingDetails.isMock()) { - MockCreationSettings settings = mockingDetails.getMockCreationSettings(); - List listeners = settings.getInvocationListeners(); - for (Object listener : listeners) { - if (listener instanceof ResetInvocationListener resetInvocationListener) { - reset = resetInvocationListener.getReset(); - } - } - } - return reset; - } - - /** - * Dummy {@link InvocationListener} used to hold the {@link MockReset} value. - */ - private static class ResetInvocationListener implements InvocationListener { - - private final MockReset reset; - - ResetInvocationListener(MockReset reset) { - this.reset = reset; - } - - MockReset getReset() { - return this.reset; - } - - @Override - public void reportInvocation(MethodInvocationReport methodInvocationReport) { - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoBeans.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoBeans.java deleted file mode 100644 index e7c51d000f82..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoBeans.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Beans created using Mockito. - * - * @author Andy Wilkinson - */ -class MockitoBeans implements Iterable { - - private final List beans = new ArrayList<>(); - - void add(Object bean) { - this.beans.add(bean); - } - - @Override - public Iterator iterator() { - return this.beans.iterator(); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizer.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizer.java deleted file mode 100644 index 4e71f0f2346a..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.LinkedHashSet; -import java.util.Set; - -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.context.ContextCustomizer; -import org.springframework.test.context.MergedContextConfiguration; - -/** - * A {@link ContextCustomizer} to add Mockito support. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockitoContextCustomizer implements ContextCustomizer { - - private final Set definitions; - - MockitoContextCustomizer(Set definitions) { - this.definitions = new LinkedHashSet<>(definitions); - } - - @Override - public void customizeContext(ConfigurableApplicationContext context, - MergedContextConfiguration mergedContextConfiguration) { - if (context instanceof BeanDefinitionRegistry registry) { - MockitoPostProcessor.register(registry, this.definitions); - } - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - MockitoContextCustomizer other = (MockitoContextCustomizer) obj; - return this.definitions.equals(other.definitions); - } - - @Override - public int hashCode() { - return this.definitions.hashCode(); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerFactory.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerFactory.java deleted file mode 100644 index a062800e6fa0..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerFactory.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.List; - -import org.springframework.test.context.ContextConfigurationAttributes; -import org.springframework.test.context.ContextCustomizer; -import org.springframework.test.context.ContextCustomizerFactory; -import org.springframework.test.context.TestContextAnnotationUtils; - -/** - * A {@link ContextCustomizerFactory} to add Mockito support. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockitoContextCustomizerFactory implements ContextCustomizerFactory { - - @Override - public ContextCustomizer createContextCustomizer(Class testClass, - List configAttributes) { - // We gather the explicit mock definitions here since they form part of the - // MergedContextConfiguration key. Different mocks need to have a different key. - DefinitionsParser parser = new DefinitionsParser(); - parseDefinitions(testClass, parser); - return new MockitoContextCustomizer(parser.getDefinitions()); - } - - private void parseDefinitions(Class testClass, DefinitionsParser parser) { - parser.parse(testClass); - if (TestContextAnnotationUtils.searchEnclosingClass(testClass)) { - parseDefinitions(testClass.getEnclosingClass(), parser); - } - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoPostProcessor.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoPostProcessor.java deleted file mode 100644 index a3bc5edbc86d..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoPostProcessor.java +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.PropertyValues; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.NoUniqueBeanDefinitionException; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; -import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanNameGenerator; -import org.springframework.beans.factory.support.DefaultBeanNameGenerator; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.ConfigurationClassPostProcessor; -import org.springframework.core.Conventions; -import org.springframework.core.Ordered; -import org.springframework.core.PriorityOrdered; -import org.springframework.core.ResolvableType; -import org.springframework.test.context.bean.override.mockito.MockitoBean; -import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - * A {@link BeanFactoryPostProcessor} used to register and inject - * {@link MockBean @MockBeans} with the {@link ApplicationContext}. An initial set of - * definitions can be passed to the processor with additional definitions being - * automatically created from {@code @Configuration} classes that use - * {@link MockBean @MockBean}. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @author Stephane Nicoll - * @author Andreas Neiser - * @since 1.4.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of Spring Framework's - * {@link MockitoBean} and {@link MockitoSpyBean} support - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0") -public class MockitoPostProcessor implements InstantiationAwareBeanPostProcessor, BeanClassLoaderAware, - BeanFactoryAware, BeanFactoryPostProcessor, Ordered { - - private static final String BEAN_NAME = MockitoPostProcessor.class.getName(); - - private static final String CONFIGURATION_CLASS_ATTRIBUTE = Conventions - .getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass"); - - private static final BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator(); - - private final Set definitions; - - private ClassLoader classLoader; - - private BeanFactory beanFactory; - - private final MockitoBeans mockitoBeans = new MockitoBeans(); - - private final Map beanNameRegistry = new HashMap<>(); - - private final Map fieldRegistry = new HashMap<>(); - - private final Map spies = new HashMap<>(); - - /** - * Create a new {@link MockitoPostProcessor} instance with the given initial - * definitions. - * @param definitions the initial definitions - */ - public MockitoPostProcessor(Set definitions) { - this.definitions = definitions; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - Assert.isTrue(beanFactory instanceof ConfigurableListableBeanFactory, - "'beanFactory' must be a ConfigurableListableBeanFactory"); - this.beanFactory = beanFactory; - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - Assert.isTrue(beanFactory instanceof BeanDefinitionRegistry, "'beanFactory' must be a BeanDefinitionRegistry"); - postProcessBeanFactory(beanFactory, (BeanDefinitionRegistry) beanFactory); - } - - private void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry) { - beanFactory.registerSingleton(MockitoBeans.class.getName(), this.mockitoBeans); - DefinitionsParser parser = new DefinitionsParser(this.definitions); - for (Class configurationClass : getConfigurationClasses(beanFactory)) { - parser.parse(configurationClass); - } - Set definitions = parser.getDefinitions(); - for (Definition definition : definitions) { - Field field = parser.getField(definition); - register(beanFactory, registry, definition, field); - } - } - - private Set> getConfigurationClasses(ConfigurableListableBeanFactory beanFactory) { - Set> configurationClasses = new LinkedHashSet<>(); - for (BeanDefinition beanDefinition : getConfigurationBeanDefinitions(beanFactory).values()) { - configurationClasses.add(ClassUtils.resolveClassName(beanDefinition.getBeanClassName(), this.classLoader)); - } - return configurationClasses; - } - - private Map getConfigurationBeanDefinitions(ConfigurableListableBeanFactory beanFactory) { - Map definitions = new LinkedHashMap<>(); - for (String beanName : beanFactory.getBeanDefinitionNames()) { - BeanDefinition definition = beanFactory.getBeanDefinition(beanName); - if (definition.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE) != null) { - definitions.put(beanName, definition); - } - } - return definitions; - } - - private void register(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry, - Definition definition, Field field) { - if (definition instanceof MockDefinition mockDefinition) { - registerMock(beanFactory, registry, mockDefinition, field); - } - else if (definition instanceof SpyDefinition spyDefinition) { - registerSpy(beanFactory, registry, spyDefinition, field); - } - } - - private void registerMock(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry, - MockDefinition definition, Field field) { - RootBeanDefinition beanDefinition = createBeanDefinition(definition); - String beanName = getBeanName(beanFactory, registry, definition, beanDefinition); - String transformedBeanName = BeanFactoryUtils.transformedBeanName(beanName); - if (registry.containsBeanDefinition(transformedBeanName)) { - BeanDefinition existing = registry.getBeanDefinition(transformedBeanName); - copyBeanDefinitionDetails(existing, beanDefinition); - registry.removeBeanDefinition(transformedBeanName); - } - registry.registerBeanDefinition(transformedBeanName, beanDefinition); - Object mock = definition.createMock(beanName + " bean"); - beanFactory.registerSingleton(transformedBeanName, mock); - this.mockitoBeans.add(mock); - this.beanNameRegistry.put(definition, beanName); - if (field != null) { - this.fieldRegistry.put(field, beanName); - } - } - - private RootBeanDefinition createBeanDefinition(MockDefinition mockDefinition) { - RootBeanDefinition definition = new RootBeanDefinition(mockDefinition.getTypeToMock().resolve()); - definition.setTargetType(mockDefinition.getTypeToMock()); - if (mockDefinition.getQualifier() != null) { - mockDefinition.getQualifier().applyTo(definition); - } - return definition; - } - - private String getBeanName(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry, - MockDefinition mockDefinition, RootBeanDefinition beanDefinition) { - if (StringUtils.hasLength(mockDefinition.getName())) { - return mockDefinition.getName(); - } - Set existingBeans = getExistingBeans(beanFactory, mockDefinition.getTypeToMock(), - mockDefinition.getQualifier()); - if (existingBeans.isEmpty()) { - return MockitoPostProcessor.beanNameGenerator.generateBeanName(beanDefinition, registry); - } - if (existingBeans.size() == 1) { - return existingBeans.iterator().next(); - } - String primaryCandidate = determinePrimaryCandidate(registry, existingBeans, mockDefinition.getTypeToMock()); - if (primaryCandidate != null) { - return primaryCandidate; - } - throw new IllegalStateException("Unable to register mock bean " + mockDefinition.getTypeToMock() - + " expected a single matching bean to replace but found " + existingBeans); - } - - private void copyBeanDefinitionDetails(BeanDefinition from, RootBeanDefinition to) { - to.setPrimary(from.isPrimary()); - } - - private void registerSpy(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry, - SpyDefinition spyDefinition, Field field) { - Set existingBeans = getExistingBeans(beanFactory, spyDefinition.getTypeToSpy(), - spyDefinition.getQualifier()); - if (ObjectUtils.isEmpty(existingBeans)) { - createSpy(registry, spyDefinition, field); - } - else { - registerSpies(registry, spyDefinition, field, existingBeans); - } - } - - private Set getExistingBeans(ConfigurableListableBeanFactory beanFactory, ResolvableType type, - QualifierDefinition qualifier) { - Set candidates = new TreeSet<>(); - for (String candidate : getExistingBeans(beanFactory, type)) { - if (qualifier == null || qualifier.matches(beanFactory, candidate)) { - candidates.add(candidate); - } - } - return candidates; - } - - private Set getExistingBeans(ConfigurableListableBeanFactory beanFactory, ResolvableType resolvableType) { - Set beans = new LinkedHashSet<>( - Arrays.asList(beanFactory.getBeanNamesForType(resolvableType, true, false))); - Class type = resolvableType.resolve(Object.class); - for (String beanName : beanFactory.getBeanNamesForType(FactoryBean.class, true, false)) { - beanName = BeanFactoryUtils.transformedBeanName(beanName); - Class producedType = beanFactory.getType(beanName, false); - if (type.equals(producedType)) { - beans.add(beanName); - } - } - beans.removeIf(this::isScopedTarget); - return beans; - } - - private boolean isScopedTarget(String beanName) { - try { - return ScopedProxyUtils.isScopedTarget(beanName); - } - catch (Throwable ex) { - return false; - } - } - - private void createSpy(BeanDefinitionRegistry registry, SpyDefinition spyDefinition, Field field) { - RootBeanDefinition beanDefinition = new RootBeanDefinition(spyDefinition.getTypeToSpy().resolve()); - String beanName = MockitoPostProcessor.beanNameGenerator.generateBeanName(beanDefinition, registry); - registry.registerBeanDefinition(beanName, beanDefinition); - registerSpy(spyDefinition, field, beanName); - } - - private void registerSpies(BeanDefinitionRegistry registry, SpyDefinition spyDefinition, Field field, - Collection existingBeans) { - try { - String beanName = determineBeanName(existingBeans, spyDefinition, registry); - registerSpy(spyDefinition, field, beanName); - } - catch (RuntimeException ex) { - throw new IllegalStateException("Unable to register spy bean " + spyDefinition.getTypeToSpy(), ex); - } - } - - private String determineBeanName(Collection existingBeans, SpyDefinition definition, - BeanDefinitionRegistry registry) { - if (StringUtils.hasText(definition.getName())) { - return definition.getName(); - } - if (existingBeans.size() == 1) { - return existingBeans.iterator().next(); - } - return determinePrimaryCandidate(registry, existingBeans, definition.getTypeToSpy()); - } - - private String determinePrimaryCandidate(BeanDefinitionRegistry registry, Collection candidateBeanNames, - ResolvableType type) { - String primaryBeanName = null; - for (String candidateBeanName : candidateBeanNames) { - BeanDefinition beanDefinition = registry.getBeanDefinition(candidateBeanName); - if (beanDefinition.isPrimary()) { - if (primaryBeanName != null) { - throw new NoUniqueBeanDefinitionException(type.resolve(), candidateBeanNames.size(), - "more than one 'primary' bean found among candidates: " - + Collections.singletonList(candidateBeanNames)); - } - primaryBeanName = candidateBeanName; - } - } - return primaryBeanName; - } - - private void registerSpy(SpyDefinition definition, Field field, String beanName) { - this.spies.put(beanName, definition); - this.beanNameRegistry.put(definition, beanName); - if (field != null) { - this.fieldRegistry.put(field, beanName); - } - } - - protected final Object createSpyIfNecessary(Object bean, String beanName) throws BeansException { - SpyDefinition definition = this.spies.get(beanName); - if (definition != null) { - bean = definition.createSpy(beanName, bean); - this.mockitoBeans.add(bean); - } - return bean; - } - - @Override - public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) - throws BeansException { - ReflectionUtils.doWithFields(bean.getClass(), (field) -> postProcessField(bean, field)); - return pvs; - } - - private void postProcessField(Object bean, Field field) { - String beanName = this.fieldRegistry.get(field); - if (StringUtils.hasText(beanName)) { - inject(field, bean, beanName); - } - } - - void inject(Field field, Object target, Definition definition) { - String beanName = this.beanNameRegistry.get(definition); - Assert.state(StringUtils.hasLength(beanName), () -> "No bean found for definition " + definition); - inject(field, target, beanName); - } - - private void inject(Field field, Object target, String beanName) { - try { - field.setAccessible(true); - Object existingValue = ReflectionUtils.getField(field, target); - Object bean = this.beanFactory.getBean(beanName, field.getType()); - if (existingValue == bean) { - return; - } - Assert.state(existingValue == null, () -> "The existing value '" + existingValue + "' of field '" + field - + "' is not the same as the new value '" + bean + "'"); - ReflectionUtils.setField(field, target, bean); - } - catch (Throwable ex) { - throw new BeanCreationException("Could not inject field: " + field, ex); - } - } - - @Override - public int getOrder() { - return Ordered.LOWEST_PRECEDENCE - 10; - } - - /** - * Register the processor with a {@link BeanDefinitionRegistry}. Not required when - * using the {@link SpringRunner} as registration is automatic. - * @param registry the bean definition registry - */ - public static void register(BeanDefinitionRegistry registry) { - register(registry, null); - } - - /** - * Register the processor with a {@link BeanDefinitionRegistry}. Not required when - * using the {@link SpringRunner} as registration is automatic. - * @param registry the bean definition registry - * @param definitions the initial mock/spy definitions - */ - public static void register(BeanDefinitionRegistry registry, Set definitions) { - register(registry, MockitoPostProcessor.class, definitions); - } - - /** - * Register the processor with a {@link BeanDefinitionRegistry}. Not required when - * using the {@link SpringRunner} as registration is automatic. - * @param registry the bean definition registry - * @param postProcessor the post processor class to register - * @param definitions the initial mock/spy definitions - */ - @SuppressWarnings("unchecked") - public static void register(BeanDefinitionRegistry registry, Class postProcessor, - Set definitions) { - SpyPostProcessor.register(registry); - BeanDefinition definition = getOrAddBeanDefinition(registry, postProcessor); - ValueHolder constructorArg = definition.getConstructorArgumentValues().getIndexedArgumentValue(0, Set.class); - Set existing = (Set) constructorArg.getValue(); - if (definitions != null) { - existing.addAll(definitions); - } - } - - private static BeanDefinition getOrAddBeanDefinition(BeanDefinitionRegistry registry, - Class postProcessor) { - if (!registry.containsBeanDefinition(BEAN_NAME)) { - RootBeanDefinition definition = new RootBeanDefinition(postProcessor); - definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues(); - constructorArguments.addIndexedArgumentValue(0, new LinkedHashSet<>()); - registry.registerBeanDefinition(BEAN_NAME, definition); - return definition; - } - return registry.getBeanDefinition(BEAN_NAME); - } - - /** - * {@link BeanPostProcessor} to handle {@link SpyBean} definitions. Registered as a - * separate processor so that it can be ordered above AOP post processors. - */ - static class SpyPostProcessor implements SmartInstantiationAwareBeanPostProcessor, PriorityOrdered { - - private static final String BEAN_NAME = SpyPostProcessor.class.getName(); - - private final Map earlySpyReferences = new ConcurrentHashMap<>(16); - - private final MockitoPostProcessor mockitoPostProcessor; - - SpyPostProcessor(MockitoPostProcessor mockitoPostProcessor) { - this.mockitoPostProcessor = mockitoPostProcessor; - } - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } - - @Override - public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { - if (bean instanceof FactoryBean) { - return bean; - } - this.earlySpyReferences.put(getCacheKey(bean, beanName), bean); - return this.mockitoPostProcessor.createSpyIfNecessary(bean, beanName); - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof FactoryBean) { - return bean; - } - if (this.earlySpyReferences.remove(getCacheKey(bean, beanName)) != bean) { - return this.mockitoPostProcessor.createSpyIfNecessary(bean, beanName); - } - return bean; - } - - private String getCacheKey(Object bean, String beanName) { - return StringUtils.hasLength(beanName) ? beanName : bean.getClass().getName(); - } - - static void register(BeanDefinitionRegistry registry) { - if (!registry.containsBeanDefinition(BEAN_NAME)) { - RootBeanDefinition definition = new RootBeanDefinition(SpyPostProcessor.class); - definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues(); - constructorArguments.addIndexedArgumentValue(0, - new RuntimeBeanReference(MockitoPostProcessor.BEAN_NAME)); - registry.registerBeanDefinition(BEAN_NAME, definition); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListener.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListener.java deleted file mode 100644 index 66396f76a821..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListener.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.function.BiConsumer; - -import org.mockito.Captor; -import org.mockito.MockitoAnnotations; - -import org.springframework.test.context.TestContext; -import org.springframework.test.context.TestExecutionListener; -import org.springframework.test.context.bean.override.mockito.MockitoBean; -import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; -import org.springframework.test.context.support.AbstractTestExecutionListener; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.ReflectionUtils.FieldCallback; - -/** - * {@link TestExecutionListener} to enable {@link MockBean @MockBean} and - * {@link SpyBean @SpyBean} support. Also triggers - * {@link MockitoAnnotations#openMocks(Object)} when any Mockito annotations used, - * primarily to allow {@link Captor @Captor} annotations. - *

    - * To use the automatic reset support of {@code @MockBean} and {@code @SpyBean}, configure - * {@link ResetMocksTestExecutionListener} as well. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @author Moritz Halbritter - * @since 1.4.2 - * @see ResetMocksTestExecutionListener - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of Spring Framework's support for - * {@link MockitoBean} and {@link MockitoSpyBean}. - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class MockitoTestExecutionListener extends AbstractTestExecutionListener { - - private static final String MOCKS_ATTRIBUTE_NAME = MockitoTestExecutionListener.class.getName() + ".mocks"; - - @Override - public final int getOrder() { - return 1950; - } - - @Override - public void prepareTestInstance(TestContext testContext) throws Exception { - closeMocks(testContext); - initMocks(testContext); - injectFields(testContext); - } - - @Override - public void beforeTestMethod(TestContext testContext) throws Exception { - if (Boolean.TRUE.equals( - testContext.getAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE))) { - closeMocks(testContext); - initMocks(testContext); - reinjectFields(testContext); - } - } - - @Override - public void afterTestMethod(TestContext testContext) throws Exception { - closeMocks(testContext); - } - - @Override - public void afterTestClass(TestContext testContext) throws Exception { - closeMocks(testContext); - } - - private void initMocks(TestContext testContext) { - if (hasMockitoAnnotations(testContext)) { - testContext.setAttribute(MOCKS_ATTRIBUTE_NAME, MockitoAnnotations.openMocks(testContext.getTestInstance())); - } - } - - private void closeMocks(TestContext testContext) throws Exception { - Object mocks = testContext.getAttribute(MOCKS_ATTRIBUTE_NAME); - if (mocks instanceof AutoCloseable closeable) { - closeable.close(); - } - } - - private boolean hasMockitoAnnotations(TestContext testContext) { - MockitoAnnotationCollection collector = new MockitoAnnotationCollection(); - ReflectionUtils.doWithFields(testContext.getTestClass(), collector); - return collector.hasAnnotations(); - } - - private void injectFields(TestContext testContext) { - postProcessFields(testContext, (mockitoField, postProcessor) -> postProcessor.inject(mockitoField.field, - mockitoField.target, mockitoField.definition)); - } - - private void reinjectFields(final TestContext testContext) { - postProcessFields(testContext, (mockitoField, postProcessor) -> { - ReflectionUtils.makeAccessible(mockitoField.field); - ReflectionUtils.setField(mockitoField.field, testContext.getTestInstance(), null); - postProcessor.inject(mockitoField.field, mockitoField.target, mockitoField.definition); - }); - } - - private void postProcessFields(TestContext testContext, BiConsumer consumer) { - DefinitionsParser parser = new DefinitionsParser(); - parser.parse(testContext.getTestClass()); - if (!parser.getDefinitions().isEmpty()) { - MockitoPostProcessor postProcessor = testContext.getApplicationContext() - .getBean(MockitoPostProcessor.class); - for (Definition definition : parser.getDefinitions()) { - Field field = parser.getField(definition); - if (field != null) { - consumer.accept(new MockitoField(field, testContext.getTestInstance(), definition), postProcessor); - } - } - } - } - - /** - * {@link FieldCallback} to collect Mockito annotations. - */ - private static final class MockitoAnnotationCollection implements FieldCallback { - - private final Set annotations = new LinkedHashSet<>(); - - @Override - public void doWith(Field field) throws IllegalArgumentException { - for (Annotation annotation : field.getDeclaredAnnotations()) { - if (annotation.annotationType().getName().startsWith("org.mockito")) { - this.annotations.add(annotation); - } - } - } - - boolean hasAnnotations() { - return !this.annotations.isEmpty(); - } - - } - - private static final class MockitoField { - - private final Field field; - - private final Object target; - - private final Definition definition; - - private MockitoField(Field field, Object instance, Definition definition) { - this.field = field; - this.target = instance; - this.definition = definition; - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/QualifierDefinition.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/QualifierDefinition.java deleted file mode 100644 index e61830f7aa9e..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/QualifierDefinition.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.Set; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.DependencyDescriptor; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.core.annotation.MergedAnnotations; - -/** - * Definition of a Spring {@link Qualifier @Qualifier}. - * - * @author Phillip Webb - * @author Stephane Nicoll - * @see Definition - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class QualifierDefinition { - - private final Field field; - - private final DependencyDescriptor descriptor; - - private final Set annotations; - - QualifierDefinition(Field field, Set annotations) { - // We can't use the field or descriptor as part of the context key - // but we can assume that if two fields have the same qualifiers then - // it's safe for Spring to use either for qualifier logic - this.field = field; - this.descriptor = new DependencyDescriptor(field, true); - this.annotations = annotations; - } - - boolean matches(ConfigurableListableBeanFactory beanFactory, String beanName) { - return beanFactory.isAutowireCandidate(beanName, this.descriptor); - } - - void applyTo(RootBeanDefinition definition) { - definition.setQualifiedElement(this.field); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || !getClass().isAssignableFrom(obj.getClass())) { - return false; - } - QualifierDefinition other = (QualifierDefinition) obj; - return this.annotations.equals(other.annotations); - } - - @Override - public int hashCode() { - return this.annotations.hashCode(); - } - - static QualifierDefinition forElement(AnnotatedElement element) { - if (element instanceof Field field) { - Set annotations = getQualifierAnnotations(field); - if (!annotations.isEmpty()) { - return new QualifierDefinition(field, annotations); - } - } - return null; - } - - private static Set getQualifierAnnotations(Field field) { - // Assume that any annotations other than @MockBean/@SpyBean are qualifiers - Annotation[] candidates = field.getDeclaredAnnotations(); - Set annotations = new HashSet<>(candidates.length); - for (Annotation candidate : candidates) { - if (!isMockOrSpyAnnotation(candidate.annotationType())) { - annotations.add(candidate); - } - } - return annotations; - } - - private static boolean isMockOrSpyAnnotation(Class type) { - if (type.equals(MockBean.class) || type.equals(SpyBean.class)) { - return true; - } - MergedAnnotations metaAnnotations = MergedAnnotations.from(type); - return metaAnnotations.isPresent(MockBean.class) || metaAnnotations.isPresent(SpyBean.class); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java deleted file mode 100644 index 852feb879607..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.mockito.Mockito; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.NativeDetector; -import org.springframework.core.Ordered; -import org.springframework.test.context.TestContext; -import org.springframework.test.context.TestExecutionListener; -import org.springframework.test.context.support.AbstractTestExecutionListener; -import org.springframework.util.ClassUtils; - -/** - * {@link TestExecutionListener} to reset any mock beans that have been marked with a - * {@link MockReset}. Typically used alongside {@link MockitoTestExecutionListener}. - * - * @author Phillip Webb - * @since 1.4.0 - * @see MockitoTestExecutionListener - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link org.springframework.test.context.bean.override.mockito.MockitoResetTestExecutionListener} - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class ResetMocksTestExecutionListener extends AbstractTestExecutionListener { - - private static final boolean MOCKITO_IS_PRESENT = ClassUtils.isPresent("org.mockito.MockSettings", - ResetMocksTestExecutionListener.class.getClassLoader()); - - @Override - public int getOrder() { - return Ordered.LOWEST_PRECEDENCE - 100; - } - - @Override - public void beforeTestMethod(TestContext testContext) throws Exception { - if (MOCKITO_IS_PRESENT && !NativeDetector.inNativeImage()) { - resetMocks(testContext.getApplicationContext(), MockReset.BEFORE); - } - } - - @Override - public void afterTestMethod(TestContext testContext) throws Exception { - if (MOCKITO_IS_PRESENT && !NativeDetector.inNativeImage()) { - resetMocks(testContext.getApplicationContext(), MockReset.AFTER); - } - } - - private void resetMocks(ApplicationContext applicationContext, MockReset reset) { - if (applicationContext instanceof ConfigurableApplicationContext configurableContext) { - resetMocks(configurableContext, reset); - } - } - - private void resetMocks(ConfigurableApplicationContext applicationContext, MockReset reset) { - ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory(); - String[] names = beanFactory.getBeanDefinitionNames(); - Set instantiatedSingletons = new HashSet<>(Arrays.asList(beanFactory.getSingletonNames())); - for (String name : names) { - BeanDefinition definition = beanFactory.getBeanDefinition(name); - if (definition.isSingleton() && instantiatedSingletons.contains(name)) { - Object bean = getBean(beanFactory, name); - if (bean != null && reset.equals(MockReset.get(bean))) { - Mockito.reset(bean); - } - } - } - try { - MockitoBeans mockedBeans = beanFactory.getBean(MockitoBeans.class); - for (Object mockedBean : mockedBeans) { - if (reset.equals(MockReset.get(mockedBean))) { - Mockito.reset(mockedBean); - } - } - } - catch (NoSuchBeanDefinitionException ex) { - // Continue - } - if (applicationContext.getParent() != null) { - resetMocks(applicationContext.getParent(), reset); - } - } - - private Object getBean(ConfigurableListableBeanFactory beanFactory, String name) { - try { - if (isStandardBeanOrSingletonFactoryBean(beanFactory, name)) { - return beanFactory.getBean(name); - } - } - catch (Exception ex) { - // Continue - } - return beanFactory.getSingleton(name); - } - - private boolean isStandardBeanOrSingletonFactoryBean(ConfigurableListableBeanFactory beanFactory, String name) { - String factoryBeanName = BeanFactory.FACTORY_BEAN_PREFIX + name; - if (beanFactory.containsBean(factoryBeanName)) { - FactoryBean factoryBean = (FactoryBean) beanFactory.getBean(factoryBeanName); - return factoryBean.isSingleton(); - } - return true; - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpringBootMockResolver.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpringBootMockResolver.java deleted file mode 100644 index fbc27d25aa28..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpringBootMockResolver.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.mockito.plugins.MockResolver; - -import org.springframework.aop.TargetSource; -import org.springframework.aop.framework.Advised; -import org.springframework.aop.support.AopUtils; -import org.springframework.test.context.bean.override.mockito.MockitoBean; -import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; -import org.springframework.util.Assert; - -/** - * A {@link MockResolver} for testing Spring Boot applications with Mockito. It resolves - * mocks by walking the proxy chain until the target or a non-static proxy is found. - * - * @author Andy Wilkinson - * @since 2.4.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of Spring Framework's - * {@link MockitoBean} and {@link MockitoSpyBean} - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public class SpringBootMockResolver implements MockResolver { - - @Override - public Object resolve(Object instance) { - return getUltimateTargetObject(instance); - } - - @SuppressWarnings("unchecked") - private static T getUltimateTargetObject(Object candidate) { - Assert.notNull(candidate, "'candidate' must not be null"); - try { - if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised advised) { - TargetSource targetSource = advised.getTargetSource(); - if (targetSource.isStatic()) { - Object target = targetSource.getTarget(); - if (target != null) { - return getUltimateTargetObject(target); - } - } - } - } - catch (Throwable ex) { - throw new IllegalStateException("Failed to unwrap proxied object", ex); - } - return (T) candidate; - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyBean.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyBean.java deleted file mode 100644 index 6b0d94136d32..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyBean.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.junit.runner.RunWith; -import org.mockito.Mockito; - -import org.springframework.context.ApplicationContext; -import org.springframework.core.annotation.AliasFor; -import org.springframework.test.context.junit4.SpringRunner; - -/** - * Annotation that can be used to apply Mockito spies to a Spring - * {@link ApplicationContext}. Can be used as a class level annotation or on fields in - * either {@code @Configuration} classes, or test classes that are - * {@link RunWith @RunWith} the {@link SpringRunner}. - *

    - * Spies can be applied by type or by {@link #name() bean name}. All beans in the context - * of a matching type (including subclasses) will be wrapped with the spy. If no existing - * bean is defined a new one will be added. Dependencies that are known to the application - * context but are not beans (such as those - * {@link org.springframework.beans.factory.config.ConfigurableListableBeanFactory#registerResolvableDependency(Class, Object) - * registered directly}) will not be found and a spied bean will be added to the context - * alongside the existing dependency. - *

    - * When {@code @SpyBean} is used on a field, as well as being registered in the - * application context, the spy will also be injected into the field. Typical usage might - * be:

    - * @RunWith(SpringRunner.class)
    - * public class ExampleTests {
    - *
    - *     @SpyBean
    - *     private ExampleService service;
    - *
    - *     @Autowired
    - *     private UserOfService userOfService;
    - *
    - *     @Test
    - *     public void testUserOfService() {
    - *         String actual = this.userOfService.makeUse();
    - *         assertEquals("Was: Hello", actual);
    - *         verify(this.service).greet();
    - *     }
    - *
    - *     @Configuration
    - *     @Import(UserOfService.class) // A @Component injected with ExampleService
    - *     static class Config {
    - *     }
    - *
    - *
    - * }
    - * 
    If there is more than one bean of the requested type, qualifier metadata must be - * specified at field level:
    - * @RunWith(SpringRunner.class)
    - * public class ExampleTests {
    - *
    - *     @SpyBean
    - *     @Qualifier("example")
    - *     private ExampleService service;
    - *
    - *     ...
    - * }
    - * 
    - *

    - * This annotation is {@code @Repeatable} and may be specified multiple times when working - * with Java 8 or contained within a {@link SpyBeans @SpyBeans} annotation. - * - * @author Phillip Webb - * @since 1.4.0 - * @see MockitoPostProcessor - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link org.springframework.test.context.bean.override.mockito.MockitoSpyBean} - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@Target({ ElementType.TYPE, ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Repeatable(SpyBeans.class) -public @interface SpyBean { - - /** - * The name of the bean to spy. If not specified the name will either be generated or, - * if the spy is for an existing bean, the existing name will be used. - * @return the name of the bean - */ - String name() default ""; - - /** - * The classes to spy. This is an alias of {@link #classes()} which can be used for - * brevity if no other attributes are defined. See {@link #classes()} for details. - * @return the classes to spy - */ - @AliasFor("classes") - Class[] value() default {}; - - /** - * The classes to spy. Each class specified here will result in a spy being applied. - * Classes can be omitted when the annotation is used on a field. - *

    - * When {@code @SpyBean} also defines a {@code name} this attribute can only contain a - * single value. - *

    - * If this is the only specified attribute consider using the {@code value} alias - * instead. - * @return the classes to spy - */ - @AliasFor("value") - Class[] classes() default {}; - - /** - * The reset mode to apply to the spied bean. The default is {@link MockReset#AFTER} - * meaning that spies are automatically reset after each test method is invoked. - * @return the reset mode - */ - MockReset reset() default MockReset.AFTER; - - /** - * Indicates that Mockito methods such as {@link Mockito#verify(Object) verify(mock)} - * should use the {@code target} of AOP advised beans, rather than the proxy itself. - * If set to {@code false} you may need to use the result of - * {@link org.springframework.test.util.AopTestUtils#getUltimateTargetObject(Object) - * AopTestUtils.getUltimateTargetObject(...)} when calling Mockito methods. - * @return {@code true} if the target of AOP advised beans is used or {@code false} if - * the proxy is used directly - */ - boolean proxyTargetAware() default true; - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyBeans.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyBeans.java deleted file mode 100644 index 1e924b422ffd..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyBeans.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Container annotation that aggregates several {@link SpyBean @SpyBean} annotations. - *

    - * Can be used natively, declaring several nested {@link SpyBean @SpyBean} annotations. - * Can also be used in conjunction with Java 8's support for repeatable - * annotations, where {@link SpyBean @SpyBean} can simply be declared several times - * on the same {@linkplain ElementType#TYPE type}, implicitly generating this container - * annotation. - * - * @author Phillip Webb - * @since 1.4.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link org.springframework.test.context.bean.override.mockito.MockitoSpyBean} - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Documented -public @interface SpyBeans { - - /** - * Return the contained {@link SpyBean @SpyBean} annotations. - * @return the spy beans - */ - SpyBean[] value(); - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyDefinition.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyDefinition.java deleted file mode 100644 index 70d7e854ec06..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/SpyDefinition.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.reflect.Proxy; - -import org.mockito.AdditionalAnswers; -import org.mockito.MockSettings; -import org.mockito.Mockito; -import org.mockito.listeners.VerificationStartedEvent; -import org.mockito.listeners.VerificationStartedListener; - -import org.springframework.core.ResolvableType; -import org.springframework.core.style.ToStringCreator; -import org.springframework.test.util.AopTestUtils; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -import static org.mockito.Mockito.mock; - -/** - * A complete definition that can be used to create a Mockito spy. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class SpyDefinition extends Definition { - - private static final int MULTIPLIER = 31; - - private final ResolvableType typeToSpy; - - SpyDefinition(String name, ResolvableType typeToSpy, MockReset reset, boolean proxyTargetAware, - QualifierDefinition qualifier) { - super(name, reset, proxyTargetAware, qualifier); - Assert.notNull(typeToSpy, "'typeToSpy' must not be null"); - this.typeToSpy = typeToSpy; - - } - - ResolvableType getTypeToSpy() { - return this.typeToSpy; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - SpyDefinition other = (SpyDefinition) obj; - boolean result = super.equals(obj); - result = result && ObjectUtils.nullSafeEquals(this.typeToSpy, other.typeToSpy); - return result; - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.typeToSpy); - return result; - } - - @Override - public String toString() { - return new ToStringCreator(this).append("name", getName()) - .append("typeToSpy", this.typeToSpy) - .append("reset", getReset()) - .toString(); - } - - T createSpy(Object instance) { - return createSpy(getName(), instance); - } - - @SuppressWarnings("unchecked") - T createSpy(String name, Object instance) { - Assert.notNull(instance, "'instance' must not be null"); - Assert.isInstanceOf(this.typeToSpy.resolve(), instance); - if (Mockito.mockingDetails(instance).isSpy()) { - return (T) instance; - } - MockSettings settings = MockReset.withSettings(getReset()); - if (StringUtils.hasLength(name)) { - settings.name(name); - } - if (isProxyTargetAware()) { - settings.verificationStartedListeners(new SpringAopBypassingVerificationStartedListener()); - } - Class toSpy; - if (Proxy.isProxyClass(instance.getClass())) { - settings.defaultAnswer(AdditionalAnswers.delegatesTo(instance)); - toSpy = this.typeToSpy.toClass(); - } - else { - settings.defaultAnswer(Mockito.CALLS_REAL_METHODS); - settings.spiedInstance(instance); - toSpy = instance.getClass(); - } - return (T) mock(toSpy, settings); - } - - /** - * A {@link VerificationStartedListener} that bypasses any proxy created by Spring AOP - * when the verification of a spy starts. - */ - private static final class SpringAopBypassingVerificationStartedListener implements VerificationStartedListener { - - @Override - public void onVerificationStarted(VerificationStartedEvent event) { - event.setMock(AopTestUtils.getUltimateTargetObject(event.getMock())); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/package-info.java deleted file mode 100644 index d40dab670150..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Mockito integration for Spring Boot tests. - *

    - * Deprecated since 3.4.0 for removal in 4.0.0 in favor of Spring Framework's - * {@link org.springframework.test.context.bean.override.mockito.MockitoBean} and - * {@link org.springframework.test.context.bean.override.mockito.MockitoSpyBean} - */ -package org.springframework.boot.test.mock.mockito; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/package-info.java deleted file mode 100644 index 2a4f9c35cca0..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Web client test utilities. - */ -package org.springframework.boot.test.web.client; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/package-info.java deleted file mode 100644 index f4a29e93f361..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * HtmlUnit support classes. - */ -package org.springframework.boot.test.web.htmlunit; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/package-info.java deleted file mode 100644 index 39fb25b81563..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Selenium support classes. - */ -package org.springframework.boot.test.web.htmlunit.webdriver; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/package-info.java deleted file mode 100644 index 1415ee4f6cbd..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Web test utilities and support classes. - */ -package org.springframework.boot.test.web; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/package-info.java deleted file mode 100644 index 57de384d1073..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring Boot support for testing Spring WebFlux server endpoints via - * {@link org.springframework.test.web.reactive.server.WebTestClient}. - */ -package org.springframework.boot.test.web.reactive.server; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/package-info.java deleted file mode 100644 index 6c2c9ae7d5ab..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring Boot support for testing Reactor Netty. - */ -package org.springframework.boot.test.web.reactor.netty; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java deleted file mode 100644 index ac78e1ffada2..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Web server test utilities and support classes. - */ -package org.springframework.boot.test.web.server; diff --git a/spring-boot-project/spring-boot-test/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-test/src/main/resources/META-INF/spring.factories index 24e84e5c8c84..80760225f6ff 100644 --- a/spring-boot-project/spring-boot-test/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-test/src/main/resources/META-INF/spring.factories @@ -2,22 +2,8 @@ org.springframework.test.context.ContextCustomizerFactory=\ org.springframework.boot.test.context.ImportsContextCustomizerFactory,\ org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory,\ -org.springframework.boot.test.graphql.tester.HttpGraphQlTesterContextCustomizerFactory,\ -org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory,\ -org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory,\ -org.springframework.boot.test.web.client.TestRestTemplateContextCustomizerFactory,\ -org.springframework.boot.test.web.reactive.server.WebTestClientContextCustomizerFactory,\ -org.springframework.boot.test.web.reactor.netty.DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory - -# Test Execution Listeners -org.springframework.test.context.TestExecutionListener=\ -org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener,\ -org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener - -# Environment Post Processors -org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.boot.test.web.SpringBootTestRandomPortEnvironmentPostProcessor +org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory # Application Context Initializers org.springframework.context.ApplicationContextInitializer=\ -org.springframework.boot.test.context.filter.ExcludeFilterApplicationContextInitializer \ No newline at end of file +org.springframework.boot.test.context.filter.ExcludeFilterApplicationContextInitializer diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java index 484f858c5a51..bdb8379a5d6d 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java @@ -33,7 +33,7 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.test.context.SpringBootTest.UseMainMethod; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.GenericReactiveWebApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -163,8 +163,7 @@ void propertySourceOrdering() { .collect(Collectors.toCollection(ArrayList::new)); String configResource = names.remove(names.size() - 2); assertThat(names).containsExactly("configurationProperties", "Inlined Test Properties", "commandLineArgs", - "servletConfigInitParams", "servletContextInitParams", "systemProperties", "systemEnvironment", - "random", "applicationInfo"); + "systemProperties", "systemEnvironment", "random", "applicationInfo"); assertThat(configResource).startsWith("Config resource"); } diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/assertj/AssertableReactiveWebApplicationContextTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/assertj/AssertableReactiveWebApplicationContextTests.java index 26b5b218d1e4..0ec2bc51a0ce 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/assertj/AssertableReactiveWebApplicationContextTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/assertj/AssertableReactiveWebApplicationContextTests.java @@ -18,7 +18,7 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebApplicationContext; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunnerTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunnerTests.java index ddd453e013a8..d199fb1a97b1 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunnerTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunnerTests.java @@ -17,8 +17,8 @@ package org.springframework.boot.test.context.runner; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.AnnotationConfigReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebApplicationContext; /** * Tests for {@link ReactiveWebApplicationContextRunner}. diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/runner/WebApplicationContextRunnerTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/runner/WebApplicationContextRunnerTests.java index 09e5b0037769..0365c789a1a0 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/runner/WebApplicationContextRunnerTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/runner/WebApplicationContextRunnerTests.java @@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; import org.springframework.mock.web.MockServletContext; import org.springframework.web.context.ConfigurableWebApplicationContext; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/AbstractMockBeanOnGenericExtensionTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/AbstractMockBeanOnGenericExtensionTests.java deleted file mode 100644 index e4378afd8030..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/AbstractMockBeanOnGenericExtensionTests.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -/** - * Concrete implementation of {@link AbstractMockBeanOnGenericTests}. - * - * @author Madhura Bhave - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class AbstractMockBeanOnGenericExtensionTests extends - AbstractMockBeanOnGenericTests { - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/AbstractMockBeanOnGenericTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/AbstractMockBeanOnGenericTests.java deleted file mode 100644 index 3c84f24119f0..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/AbstractMockBeanOnGenericTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MockBean} with abstract class and generics. - * - * @param type of thing - * @param type of something - * @author Madhura Bhave - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@SpringBootTest(classes = AbstractMockBeanOnGenericTests.TestConfiguration.class) -abstract class AbstractMockBeanOnGenericTests, U extends AbstractMockBeanOnGenericTests.Something> { - - @Autowired - @SuppressWarnings("unused") - private T thing; - - @MockBean - private U something; - - @Test - void mockBeanShouldResolveConcreteType() { - assertThat(this.something).isInstanceOf(SomethingImpl.class); - } - - abstract static class Thing { - - @Autowired - private T something; - - T getSomething() { - return this.something; - } - - void setSomething(T something) { - this.something = something; - } - - } - - static class SomethingImpl extends Something { - - } - - static class ThingImpl extends Thing { - - } - - static class Something { - - } - - @Configuration - static class TestConfiguration { - - @Bean - ThingImpl thing() { - return new ThingImpl(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/DefinitionsParserTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/DefinitionsParserTests.java deleted file mode 100644 index 55f1b12cbd9d..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/DefinitionsParserTests.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.mockito.Answers; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.test.mock.mockito.example.ExampleExtraInterface; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.RealExampleService; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link DefinitionsParser}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class DefinitionsParserTests { - - private final DefinitionsParser parser = new DefinitionsParser(); - - @Test - void parseSingleMockBean() { - this.parser.parse(SingleMockBean.class); - assertThat(getDefinitions()).hasSize(1); - assertThat(getMockDefinition(0).getTypeToMock().resolve()).isEqualTo(ExampleService.class); - } - - @Test - void parseRepeatMockBean() { - this.parser.parse(RepeatMockBean.class); - assertThat(getDefinitions()).hasSize(2); - assertThat(getMockDefinition(0).getTypeToMock().resolve()).isEqualTo(ExampleService.class); - assertThat(getMockDefinition(1).getTypeToMock().resolve()).isEqualTo(ExampleServiceCaller.class); - } - - @Test - void parseMockBeanAttributes() { - this.parser.parse(MockBeanAttributes.class); - assertThat(getDefinitions()).hasSize(1); - MockDefinition definition = getMockDefinition(0); - assertThat(definition.getName()).isEqualTo("Name"); - assertThat(definition.getTypeToMock().resolve()).isEqualTo(ExampleService.class); - assertThat(definition.getExtraInterfaces()).containsExactly(ExampleExtraInterface.class); - assertThat(definition.getAnswer()).isEqualTo(Answers.RETURNS_SMART_NULLS); - assertThat(definition.isSerializable()).isTrue(); - assertThat(definition.getReset()).isEqualTo(MockReset.NONE); - assertThat(definition.getQualifier()).isNull(); - } - - @Test - void parseMockBeanOnClassAndField() { - this.parser.parse(MockBeanOnClassAndField.class); - assertThat(getDefinitions()).hasSize(2); - MockDefinition classDefinition = getMockDefinition(0); - assertThat(classDefinition.getTypeToMock().resolve()).isEqualTo(ExampleService.class); - assertThat(classDefinition.getQualifier()).isNull(); - MockDefinition fieldDefinition = getMockDefinition(1); - assertThat(fieldDefinition.getTypeToMock().resolve()).isEqualTo(ExampleServiceCaller.class); - QualifierDefinition qualifier = QualifierDefinition - .forElement(ReflectionUtils.findField(MockBeanOnClassAndField.class, "caller")); - assertThat(fieldDefinition.getQualifier()).isNotNull().isEqualTo(qualifier); - } - - @Test - void parseMockBeanInferClassToMock() { - this.parser.parse(MockBeanInferClassToMock.class); - assertThat(getDefinitions()).hasSize(1); - assertThat(getMockDefinition(0).getTypeToMock().resolve()).isEqualTo(ExampleService.class); - } - - @Test - void parseMockBeanMissingClassToMock() { - assertThatIllegalStateException().isThrownBy(() -> this.parser.parse(MockBeanMissingClassToMock.class)) - .withMessageContaining("Unable to deduce type to mock"); - } - - @Test - void parseMockBeanMultipleClasses() { - this.parser.parse(MockBeanMultipleClasses.class); - assertThat(getDefinitions()).hasSize(2); - assertThat(getMockDefinition(0).getTypeToMock().resolve()).isEqualTo(ExampleService.class); - assertThat(getMockDefinition(1).getTypeToMock().resolve()).isEqualTo(ExampleServiceCaller.class); - } - - @Test - void parseMockBeanMultipleClassesWithName() { - assertThatIllegalStateException().isThrownBy(() -> this.parser.parse(MockBeanMultipleClassesWithName.class)) - .withMessageContaining("The name attribute can only be used when mocking a single class"); - } - - @Test - void parseSingleSpyBean() { - this.parser.parse(SingleSpyBean.class); - assertThat(getDefinitions()).hasSize(1); - assertThat(getSpyDefinition(0).getTypeToSpy().resolve()).isEqualTo(RealExampleService.class); - } - - @Test - void parseRepeatSpyBean() { - this.parser.parse(RepeatSpyBean.class); - assertThat(getDefinitions()).hasSize(2); - assertThat(getSpyDefinition(0).getTypeToSpy().resolve()).isEqualTo(RealExampleService.class); - assertThat(getSpyDefinition(1).getTypeToSpy().resolve()).isEqualTo(ExampleServiceCaller.class); - } - - @Test - void parseSpyBeanAttributes() { - this.parser.parse(SpyBeanAttributes.class); - assertThat(getDefinitions()).hasSize(1); - SpyDefinition definition = getSpyDefinition(0); - assertThat(definition.getName()).isEqualTo("Name"); - assertThat(definition.getTypeToSpy().resolve()).isEqualTo(RealExampleService.class); - assertThat(definition.getReset()).isEqualTo(MockReset.NONE); - assertThat(definition.getQualifier()).isNull(); - } - - @Test - void parseSpyBeanOnClassAndField() { - this.parser.parse(SpyBeanOnClassAndField.class); - assertThat(getDefinitions()).hasSize(2); - SpyDefinition classDefinition = getSpyDefinition(0); - assertThat(classDefinition.getQualifier()).isNull(); - assertThat(classDefinition.getTypeToSpy().resolve()).isEqualTo(RealExampleService.class); - SpyDefinition fieldDefinition = getSpyDefinition(1); - QualifierDefinition qualifier = QualifierDefinition - .forElement(ReflectionUtils.findField(SpyBeanOnClassAndField.class, "caller")); - assertThat(fieldDefinition.getQualifier()).isNotNull().isEqualTo(qualifier); - assertThat(fieldDefinition.getTypeToSpy().resolve()).isEqualTo(ExampleServiceCaller.class); - } - - @Test - void parseSpyBeanInferClassToMock() { - this.parser.parse(SpyBeanInferClassToMock.class); - assertThat(getDefinitions()).hasSize(1); - assertThat(getSpyDefinition(0).getTypeToSpy().resolve()).isEqualTo(RealExampleService.class); - } - - @Test - void parseSpyBeanMissingClassToMock() { - assertThatIllegalStateException().isThrownBy(() -> this.parser.parse(SpyBeanMissingClassToMock.class)) - .withMessageContaining("Unable to deduce type to spy"); - } - - @Test - void parseSpyBeanMultipleClasses() { - this.parser.parse(SpyBeanMultipleClasses.class); - assertThat(getDefinitions()).hasSize(2); - assertThat(getSpyDefinition(0).getTypeToSpy().resolve()).isEqualTo(RealExampleService.class); - assertThat(getSpyDefinition(1).getTypeToSpy().resolve()).isEqualTo(ExampleServiceCaller.class); - } - - @Test - void parseSpyBeanMultipleClassesWithName() { - assertThatIllegalStateException().isThrownBy(() -> this.parser.parse(SpyBeanMultipleClassesWithName.class)) - .withMessageContaining("The name attribute can only be used when spying a single class"); - } - - private MockDefinition getMockDefinition(int index) { - return (MockDefinition) getDefinitions().get(index); - } - - private SpyDefinition getSpyDefinition(int index) { - return (SpyDefinition) getDefinitions().get(index); - } - - private List getDefinitions() { - return new ArrayList<>(this.parser.getDefinitions()); - } - - @SuppressWarnings("removal") - @MockBean(ExampleService.class) - static class SingleMockBean { - - } - - @SuppressWarnings("removal") - @MockBeans({ @MockBean(ExampleService.class), @MockBean(ExampleServiceCaller.class) }) - static class RepeatMockBean { - - } - - @SuppressWarnings("removal") - @MockBean(name = "Name", classes = ExampleService.class, extraInterfaces = ExampleExtraInterface.class, - answer = Answers.RETURNS_SMART_NULLS, serializable = true, reset = MockReset.NONE) - static class MockBeanAttributes { - - } - - @SuppressWarnings("removal") - @MockBean(ExampleService.class) - static class MockBeanOnClassAndField { - - @MockBean(ExampleServiceCaller.class) - @Qualifier("test") - private Object caller; - - } - - @SuppressWarnings("removal") - @MockBean({ ExampleService.class, ExampleServiceCaller.class }) - static class MockBeanMultipleClasses { - - } - - @SuppressWarnings("removal") - @MockBean(name = "name", classes = { ExampleService.class, ExampleServiceCaller.class }) - static class MockBeanMultipleClassesWithName { - - } - - static class MockBeanInferClassToMock { - - @MockBean - private ExampleService exampleService; - - } - - @SuppressWarnings("removal") - @MockBean - static class MockBeanMissingClassToMock { - - } - - @SuppressWarnings("removal") - @SpyBean(RealExampleService.class) - static class SingleSpyBean { - - } - - @SuppressWarnings("removal") - @SpyBeans({ @SpyBean(RealExampleService.class), @SpyBean(ExampleServiceCaller.class) }) - static class RepeatSpyBean { - - } - - @SuppressWarnings("removal") - @SpyBean(name = "Name", classes = RealExampleService.class, reset = MockReset.NONE) - static class SpyBeanAttributes { - - } - - @SuppressWarnings("removal") - @SpyBean(RealExampleService.class) - static class SpyBeanOnClassAndField { - - @SpyBean(ExampleServiceCaller.class) - @Qualifier("test") - private Object caller; - - } - - @SuppressWarnings("removal") - @SpyBean({ RealExampleService.class, ExampleServiceCaller.class }) - static class SpyBeanMultipleClasses { - - } - - @SuppressWarnings("removal") - @SpyBean(name = "name", classes = { RealExampleService.class, ExampleServiceCaller.class }) - static class SpyBeanMultipleClassesWithName { - - } - - static class SpyBeanInferClassToMock { - - @SpyBean - private RealExampleService exampleService; - - } - - @SuppressWarnings("removal") - @SpyBean - static class SpyBeanMissingClassToMock { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanContextCachingTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanContextCachingTests.java deleted file mode 100644 index 4717d6962bd6..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanContextCachingTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.Map; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTestContextBootstrapper; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.BootstrapContext; -import org.springframework.test.context.MergedContextConfiguration; -import org.springframework.test.context.TestContext; -import org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate; -import org.springframework.test.context.cache.DefaultContextCache; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for application context caching when using {@link MockBean @MockBean}. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockBeanContextCachingTests { - - private final DefaultContextCache contextCache = new DefaultContextCache(2); - - private final DefaultCacheAwareContextLoaderDelegate delegate = new DefaultCacheAwareContextLoaderDelegate( - this.contextCache); - - @AfterEach - @SuppressWarnings("unchecked") - void clearCache() { - Map contexts = (Map) ReflectionTestUtils - .getField(this.contextCache, "contextMap"); - for (ApplicationContext context : contexts.values()) { - if (context instanceof ConfigurableApplicationContext configurableContext) { - configurableContext.close(); - } - } - this.contextCache.clear(); - } - - @Test - void whenThereIsANormalBeanAndAMockBeanThenTwoContextsAreCreated() { - bootstrapContext(TestClass.class); - assertThat(this.contextCache.size()).isOne(); - bootstrapContext(MockedBeanTestClass.class); - assertThat(this.contextCache.size()).isEqualTo(2); - } - - @Test - void whenThereIsTheSameMockedBeanInEachTestClassThenOneContextIsCreated() { - bootstrapContext(MockedBeanTestClass.class); - assertThat(this.contextCache.size()).isOne(); - bootstrapContext(AnotherMockedBeanTestClass.class); - assertThat(this.contextCache.size()).isOne(); - } - - @SuppressWarnings("rawtypes") - private void bootstrapContext(Class testClass) { - SpringBootTestContextBootstrapper bootstrapper = new SpringBootTestContextBootstrapper(); - BootstrapContext bootstrapContext = mock(BootstrapContext.class); - given((Class) bootstrapContext.getTestClass()).willReturn(testClass); - bootstrapper.setBootstrapContext(bootstrapContext); - given(bootstrapContext.getCacheAwareContextLoaderDelegate()).willReturn(this.delegate); - TestContext testContext = bootstrapper.buildTestContext(); - testContext.getApplicationContext(); - } - - @SpringBootTest(classes = TestConfiguration.class) - static class TestClass { - - } - - @SpringBootTest(classes = TestConfiguration.class) - static class MockedBeanTestClass { - - @MockBean - private TestBean testBean; - - } - - @SpringBootTest(classes = TestConfiguration.class) - static class AnotherMockedBeanTestClass { - - @MockBean - private TestBean testBean; - - } - - @Configuration - static class TestConfiguration { - - @Bean - TestBean testBean() { - return new TestBean(); - } - - } - - static class TestBean { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanForBeanFactoryIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanForBeanFactoryIntegrationTests.java deleted file mode 100644 index 937efef7d33f..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanForBeanFactoryIntegrationTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Test {@link MockBean @MockBean} for a factory bean. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanForBeanFactoryIntegrationTests { - - // gh-7439 - - @MockBean - private TestFactoryBean testFactoryBean; - - @Autowired - private ApplicationContext applicationContext; - - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - void testName() { - TestBean testBean = mock(TestBean.class); - given(testBean.hello()).willReturn("amock"); - given(this.testFactoryBean.getObjectType()).willReturn((Class) TestBean.class); - given(this.testFactoryBean.getObject()).willReturn(testBean); - TestBean bean = this.applicationContext.getBean(TestBean.class); - assertThat(bean.hello()).isEqualTo("amock"); - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - TestFactoryBean testFactoryBean() { - return new TestFactoryBean(); - } - - } - - static class TestFactoryBean implements FactoryBean { - - @Override - public TestBean getObject() { - return () -> "normal"; - } - - @Override - public Class getObjectType() { - return TestBean.class; - } - - @Override - public boolean isSingleton() { - return false; - } - - } - - interface TestBean { - - String hello(); - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationClassForExistingBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationClassForExistingBeanIntegrationTests.java deleted file mode 100644 index f14c4026e66b..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationClassForExistingBeanIntegrationTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.FailingExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a configuration class can be used to replace - * existing beans. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanOnConfigurationClassForExistingBeanIntegrationTests { - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.caller.getService().greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @SuppressWarnings("removal") - @Configuration(proxyBeanMethods = false) - @MockBean(ExampleService.class) - @Import({ ExampleServiceCaller.class, FailingExampleService.class }) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationClassForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationClassForNewBeanIntegrationTests.java deleted file mode 100644 index 3960a68f03b3..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationClassForNewBeanIntegrationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a configuration class can be used to inject new mock - * instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@ExtendWith(SpringExtension.class) -@Deprecated(since = "3.4.0", forRemoval = true) -class MockBeanOnConfigurationClassForNewBeanIntegrationTests { - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.caller.getService().greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @SuppressWarnings("removal") - @Configuration(proxyBeanMethods = false) - @MockBean(ExampleService.class) - @Import(ExampleServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationFieldForExistingBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationFieldForExistingBeanIntegrationTests.java deleted file mode 100644 index 264cfa39cba1..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationFieldForExistingBeanIntegrationTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.FailingExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a field on a {@code @Configuration} class can be - * used to replace existing beans. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@ExtendWith(SpringExtension.class) -@Deprecated(since = "3.4.0", forRemoval = true) -class MockBeanOnConfigurationFieldForExistingBeanIntegrationTests { - - @Autowired - private Config config; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.config.exampleService.greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @Configuration(proxyBeanMethods = false) - @Import({ ExampleServiceCaller.class, FailingExampleService.class }) - static class Config { - - @MockBean - private ExampleService exampleService; - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationFieldForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationFieldForNewBeanIntegrationTests.java deleted file mode 100644 index e61c3d04e1c3..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnConfigurationFieldForNewBeanIntegrationTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a field on a {@code @Configuration} class can be - * used to inject new mock instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@ExtendWith(SpringExtension.class) -@Deprecated(since = "3.4.0", forRemoval = true) -class MockBeanOnConfigurationFieldForNewBeanIntegrationTests { - - @Autowired - private Config config; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.config.exampleService.greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleServiceCaller.class) - static class Config { - - @MockBean - private ExampleService exampleService; - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnContextHierarchyIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnContextHierarchyIntegrationTests.java deleted file mode 100644 index 480e6d69dd1d..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnContextHierarchyIntegrationTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.ContextHierarchy; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Test {@link MockBean @MockBean} can be used with a - * {@link ContextHierarchy @ContextHierarchy}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@ContextHierarchy({ @ContextConfiguration(classes = MockBeanOnContextHierarchyIntegrationTests.ParentConfig.class), - @ContextConfiguration(classes = MockBeanOnContextHierarchyIntegrationTests.ChildConfig.class) }) -class MockBeanOnContextHierarchyIntegrationTests { - - @Autowired - private ChildConfig childConfig; - - @Test - void testMocking() { - ApplicationContext context = this.childConfig.getContext(); - ApplicationContext parentContext = context.getParent(); - assertThat(parentContext - .getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleService.class)).hasSize(1); - assertThat(parentContext - .getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class)) - .isEmpty(); - assertThat(context.getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleService.class)) - .isEmpty(); - assertThat(context - .getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class)) - .hasSize(1); - assertThat(context.getBean(org.springframework.boot.test.mock.mockito.example.ExampleService.class)) - .isNotNull(); - assertThat(context.getBean(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class)) - .isNotNull(); - } - - @Configuration(proxyBeanMethods = false) - @MockBean(org.springframework.boot.test.mock.mockito.example.ExampleService.class) - static class ParentConfig { - - } - - @Configuration(proxyBeanMethods = false) - @MockBean(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class) - static class ChildConfig implements ApplicationContextAware { - - private ApplicationContext context; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) { - this.context = applicationContext; - } - - ApplicationContext getContext() { - return this.context; - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnScopedProxyTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnScopedProxyTests.java deleted file mode 100644 index a1b7aa08602b..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnScopedProxyTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.FailingExampleService; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} when used in combination with scoped proxy targets. - * - * @author Phillip Webb - * @see gh-5724 - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanOnScopedProxyTests { - - @MockBean - private ExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.caller.getService().greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @Configuration(proxyBeanMethods = false) - @Import({ ExampleServiceCaller.class }) - static class Config { - - @Bean - @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) - ExampleService exampleService() { - return new FailingExampleService(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestClassForExistingBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestClassForExistingBeanIntegrationTests.java deleted file mode 100644 index f65bc74b2c29..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestClassForExistingBeanIntegrationTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.FailingExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a test class can be used to replace existing beans. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@MockBean(ExampleService.class) -class MockBeanOnTestClassForExistingBeanIntegrationTests { - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.caller.getService().greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @Configuration(proxyBeanMethods = false) - @Import({ ExampleServiceCaller.class, FailingExampleService.class }) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestClassForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestClassForNewBeanIntegrationTests.java deleted file mode 100644 index 2fd423681328..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestClassForNewBeanIntegrationTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a test class can be used to inject new mock - * instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@MockBean(ExampleService.class) -class MockBeanOnTestClassForNewBeanIntegrationTests { - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.caller.getService().greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanCacheIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanCacheIntegrationTests.java deleted file mode 100644 index 4490dd739d9a..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanCacheIntegrationTests.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a test class field can be used to replace existing - * beans when the context is cached. This test is identical to - * {@link MockBeanOnTestFieldForExistingBeanIntegrationTests} so one of them should - * trigger application context caching. - * - * @author Phillip Webb - * @see MockBeanOnTestFieldForExistingBeanIntegrationTests - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = MockBeanOnTestFieldForExistingBeanConfig.class) -class MockBeanOnTestFieldForExistingBeanCacheIntegrationTests { - - @MockBean - private ExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.exampleService.greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanConfig.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanConfig.java deleted file mode 100644 index 43ada734e178..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.FailingExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Config for {@link MockBeanOnTestFieldForExistingBeanIntegrationTests} and - * {@link MockBeanOnTestFieldForExistingBeanCacheIntegrationTests}. Extracted to a shared - * config to trigger caching. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@Configuration(proxyBeanMethods = false) -@Import({ ExampleServiceCaller.class, FailingExampleService.class }) -public class MockBeanOnTestFieldForExistingBeanConfig { - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanIntegrationTests.java deleted file mode 100644 index 3e0f285d9fb8..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanIntegrationTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a test class field can be used to replace existing - * beans. - * - * @author Phillip Webb - * @see MockBeanOnTestFieldForExistingBeanCacheIntegrationTests - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = MockBeanOnTestFieldForExistingBeanConfig.class) -class MockBeanOnTestFieldForExistingBeanIntegrationTests { - - @MockBean - private ExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.exampleService.greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanWithQualifierIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanWithQualifierIntegrationTests.java deleted file mode 100644 index e7116ab3c26c..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForExistingBeanWithQualifierIntegrationTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.CustomQualifier; -import org.springframework.boot.test.mock.mockito.example.CustomQualifierExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.RealExampleService; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link MockBean @MockBean} on a test class field can be used to replace existing - * bean while preserving qualifiers. - * - * @author Stephane Nicoll - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanOnTestFieldForExistingBeanWithQualifierIntegrationTests { - - @MockBean - @CustomQualifier - private ExampleService service; - - @Autowired - private ExampleServiceCaller caller; - - @Autowired - private ApplicationContext applicationContext; - - @Test - void testMocking() { - this.caller.sayGreeting(); - then(this.service).should().greeting(); - } - - @Test - void onlyQualifiedBeanIsReplaced() { - assertThat(this.applicationContext.getBean("service")).isSameAs(this.service); - ExampleService anotherService = this.applicationContext.getBean("anotherService", ExampleService.class); - assertThat(anotherService.greeting()).isEqualTo("Another"); - } - - @Configuration(proxyBeanMethods = false) - static class TestConfig { - - @Bean - CustomQualifierExampleService service() { - return new CustomQualifierExampleService(); - } - - @Bean - ExampleService anotherService() { - return new RealExampleService("Another"); - } - - @Bean - ExampleServiceCaller controller(@CustomQualifier ExampleService service) { - return new ExampleServiceCaller(service); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForNewBeanIntegrationTests.java deleted file mode 100644 index c417a2c5ad54..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanOnTestFieldForNewBeanIntegrationTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a test class field can be used to inject new mock - * instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanOnTestFieldForNewBeanIntegrationTests { - - @MockBean - private ExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.exampleService.greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithAopProxyTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithAopProxyTests.java deleted file mode 100644 index f4ba6cccc91d..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithAopProxyTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.cache.CacheManager; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.annotation.EnableCaching; -import org.springframework.cache.concurrent.ConcurrentMapCacheManager; -import org.springframework.cache.interceptor.CacheResolver; -import org.springframework.cache.interceptor.SimpleCacheResolver; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Service; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.times; - -/** - * Test {@link MockBean @MockBean} when mixed with Spring AOP. - * - * @author Phillip Webb - * @see 5837 - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanWithAopProxyTests { - - @MockBean - private DateService dateService; - - @Test - void verifyShouldUseProxyTarget() { - given(this.dateService.getDate(false)).willReturn(1L); - Long d1 = this.dateService.getDate(false); - assertThat(d1).isOne(); - given(this.dateService.getDate(false)).willReturn(2L); - Long d2 = this.dateService.getDate(false); - assertThat(d2).isEqualTo(2L); - then(this.dateService).should(times(2)).getDate(false); - then(this.dateService).should(times(2)).getDate(eq(false)); - then(this.dateService).should(times(2)).getDate(anyBoolean()); - } - - @Configuration(proxyBeanMethods = false) - @EnableCaching(proxyTargetClass = true) - @Import(DateService.class) - static class Config { - - @Bean - CacheResolver cacheResolver(CacheManager cacheManager) { - SimpleCacheResolver resolver = new SimpleCacheResolver(); - resolver.setCacheManager(cacheManager); - return resolver; - } - - @Bean - ConcurrentMapCacheManager cacheManager() { - ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); - cacheManager.setCacheNames(Arrays.asList("test")); - return cacheManager; - } - - } - - @Service - static class DateService { - - @Cacheable(cacheNames = "test") - Long getDate(boolean argument) { - return System.nanoTime(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithAsyncInterfaceMethodIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithAsyncInterfaceMethodIntegrationTests.java deleted file mode 100644 index 9d14feecb3c7..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithAsyncInterfaceMethodIntegrationTests.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Tests for a mock bean where the mocked interface has an async method. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanWithAsyncInterfaceMethodIntegrationTests { - - @MockBean - private Transformer transformer; - - @Autowired - private MyService service; - - @Test - void mockedMethodsAreNotAsync() { - given(this.transformer.transform("foo")).willReturn("bar"); - assertThat(this.service.transform("foo")).isEqualTo("bar"); - } - - interface Transformer { - - @Async - String transform(String input); - - } - - static class MyService { - - private final Transformer transformer; - - MyService(Transformer transformer) { - this.transformer = transformer; - } - - String transform(String input) { - return this.transformer.transform(input); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableAsync - static class MyConfiguration { - - @Bean - MyService myService(Transformer transformer) { - return new MyService(transformer); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithDirtiesContextClassModeBeforeMethodIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithDirtiesContextClassModeBeforeMethodIntegrationTests.java deleted file mode 100644 index dee54743dadf..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithDirtiesContextClassModeBeforeMethodIntegrationTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.ClassMode; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Integration tests for using {@link MockBean @MockBean} with - * {@link DirtiesContext @DirtiesContext} and {@link ClassMode#BEFORE_EACH_TEST_METHOD}. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD) -class MockBeanWithDirtiesContextClassModeBeforeMethodIntegrationTests { - - @MockBean - private ExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testMocking() { - given(this.exampleService.greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot"); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithGenericsOnTestFieldForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithGenericsOnTestFieldForNewBeanIntegrationTests.java deleted file mode 100644 index 8d3b6feec055..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithGenericsOnTestFieldForNewBeanIntegrationTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleGenericService; -import org.springframework.boot.test.mock.mockito.example.ExampleGenericServiceCaller; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Test {@link MockBean @MockBean} on a test class field can be used to inject new mock - * instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanWithGenericsOnTestFieldForNewBeanIntegrationTests { - - @MockBean - private ExampleGenericService exampleIntegerService; - - @MockBean - private ExampleGenericService exampleStringService; - - @Autowired - private ExampleGenericServiceCaller caller; - - @Test - void testMocking() { - given(this.exampleIntegerService.greeting()).willReturn(200); - given(this.exampleStringService.greeting()).willReturn("Boot"); - assertThat(this.caller.sayGreeting()).isEqualTo("I say 200 Boot"); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleGenericServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithInjectedFieldIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithInjectedFieldIntegrationTests.java deleted file mode 100644 index b863dddbf379..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithInjectedFieldIntegrationTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Tests for a mock bean where the class being mocked uses field injection. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockBeanWithInjectedFieldIntegrationTests { - - @MockBean - private MyService myService; - - @Test - void fieldInjectionIntoMyServiceMockIsNotAttempted() { - given(this.myService.getCount()).willReturn(5); - assertThat(this.myService.getCount()).isEqualTo(5); - } - - static class MyService { - - @Autowired - private MyRepository repository; - - int getCount() { - return this.repository.findAll().size(); - } - - } - - interface MyRepository { - - List findAll(); - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithSpringMethodRuleRepeatJUnit4IntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithSpringMethodRuleRepeatJUnit4IntegrationTests.java deleted file mode 100644 index 82aabf6f7764..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockBeanWithSpringMethodRuleRepeatJUnit4IntegrationTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.AfterClass; -import org.junit.Rule; -import org.junit.Test; - -import org.springframework.test.annotation.Repeat; -import org.springframework.test.context.junit4.rules.SpringMethodRule; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MockBean} and {@link Repeat}. - * - * @author Andy Wilkinson - * @see gh-27693 - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class MockBeanWithSpringMethodRuleRepeatJUnit4IntegrationTests { - - @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(); - - @MockBean - private FirstService first; - - private static int invocations; - - @AfterClass - public static void afterClass() { - assertThat(invocations).isEqualTo(2); - } - - @Test - @Repeat(2) - public void repeatedTest() { - invocations++; - } - - interface FirstService { - - String greeting(); - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockDefinitionTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockDefinitionTests.java deleted file mode 100644 index 27ce663e30d8..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockDefinitionTests.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.mockito.Answers; -import org.mockito.Mockito; -import org.mockito.mock.MockCreationSettings; - -import org.springframework.boot.test.mock.mockito.example.ExampleExtraInterface; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.core.ResolvableType; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link MockDefinition}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockDefinitionTests { - - private static final ResolvableType EXAMPLE_SERVICE_TYPE = ResolvableType.forClass(ExampleService.class); - - @Test - void classToMockMustNotBeNull() { - assertThatIllegalArgumentException() - .isThrownBy(() -> new MockDefinition(null, null, null, null, false, null, null)) - .withMessageContaining("'typeToMock' must not be null"); - } - - @Test - void createWithDefaults() { - MockDefinition definition = new MockDefinition(null, EXAMPLE_SERVICE_TYPE, null, null, false, null, null); - assertThat(definition.getName()).isNull(); - assertThat(definition.getTypeToMock()).isEqualTo(EXAMPLE_SERVICE_TYPE); - assertThat(definition.getExtraInterfaces()).isEmpty(); - assertThat(definition.getAnswer()).isEqualTo(Answers.RETURNS_DEFAULTS); - assertThat(definition.isSerializable()).isFalse(); - assertThat(definition.getReset()).isEqualTo(MockReset.AFTER); - assertThat(definition.getQualifier()).isNull(); - } - - @Test - void createExplicit() { - QualifierDefinition qualifier = mock(QualifierDefinition.class); - MockDefinition definition = new MockDefinition("name", EXAMPLE_SERVICE_TYPE, - new Class[] { ExampleExtraInterface.class }, Answers.RETURNS_SMART_NULLS, true, MockReset.BEFORE, - qualifier); - assertThat(definition.getName()).isEqualTo("name"); - assertThat(definition.getTypeToMock()).isEqualTo(EXAMPLE_SERVICE_TYPE); - assertThat(definition.getExtraInterfaces()).containsExactly(ExampleExtraInterface.class); - assertThat(definition.getAnswer()).isEqualTo(Answers.RETURNS_SMART_NULLS); - assertThat(definition.isSerializable()).isTrue(); - assertThat(definition.getReset()).isEqualTo(MockReset.BEFORE); - assertThat(definition.isProxyTargetAware()).isFalse(); - assertThat(definition.getQualifier()).isEqualTo(qualifier); - } - - @Test - void createMock() { - MockDefinition definition = new MockDefinition("name", EXAMPLE_SERVICE_TYPE, - new Class[] { ExampleExtraInterface.class }, Answers.RETURNS_SMART_NULLS, true, MockReset.BEFORE, - null); - ExampleService mock = definition.createMock(); - MockCreationSettings settings = Mockito.mockingDetails(mock).getMockCreationSettings(); - assertThat(mock).isInstanceOf(ExampleService.class); - assertThat(mock).isInstanceOf(ExampleExtraInterface.class); - assertThat(settings.getMockName()).hasToString("name"); - assertThat(settings.getDefaultAnswer()).isEqualTo(Answers.RETURNS_SMART_NULLS); - assertThat(settings.isSerializable()).isTrue(); - assertThat(MockReset.get(mock)).isEqualTo(MockReset.BEFORE); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockResetTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockResetTests.java deleted file mode 100644 index 9dd48ebb789f..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockResetTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.test.mock.mockito.example.ExampleService; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.withSettings; - -/** - * Tests for {@link MockReset}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockResetTests { - - @Test - void noneAttachesReset() { - ExampleService mock = mock(ExampleService.class); - assertThat(MockReset.get(mock)).isEqualTo(MockReset.NONE); - } - - @Test - void withSettingsOfNoneAttachesReset() { - ExampleService mock = mock(ExampleService.class, MockReset.withSettings(MockReset.NONE)); - assertThat(MockReset.get(mock)).isEqualTo(MockReset.NONE); - } - - @Test - void beforeAttachesReset() { - ExampleService mock = mock(ExampleService.class, MockReset.before()); - assertThat(MockReset.get(mock)).isEqualTo(MockReset.BEFORE); - } - - @Test - void afterAttachesReset() { - ExampleService mock = mock(ExampleService.class, MockReset.after()); - assertThat(MockReset.get(mock)).isEqualTo(MockReset.AFTER); - } - - @Test - void withSettingsAttachesReset() { - ExampleService mock = mock(ExampleService.class, MockReset.withSettings(MockReset.BEFORE)); - assertThat(MockReset.get(mock)).isEqualTo(MockReset.BEFORE); - } - - @Test - void apply() { - ExampleService mock = mock(ExampleService.class, MockReset.apply(MockReset.AFTER, withSettings())); - assertThat(MockReset.get(mock)).isEqualTo(MockReset.AFTER); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerFactoryTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerFactoryTests.java deleted file mode 100644 index 59bd5717dcca..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerFactoryTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; - -import org.springframework.test.context.ContextCustomizer; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MockitoContextCustomizerFactory}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockitoContextCustomizerFactoryTests { - - private final MockitoContextCustomizerFactory factory = new MockitoContextCustomizerFactory(); - - @Test - void getContextCustomizerWithoutAnnotationReturnsCustomizer() { - ContextCustomizer customizer = this.factory.createContextCustomizer(NoMockBeanAnnotation.class, null); - assertThat(customizer).isNotNull(); - } - - @Test - void getContextCustomizerWithAnnotationReturnsCustomizer() { - ContextCustomizer customizer = this.factory.createContextCustomizer(WithMockBeanAnnotation.class, null); - assertThat(customizer).isNotNull(); - } - - @Test - void getContextCustomizerUsesMocksAsCacheKey() { - ContextCustomizer customizer = this.factory.createContextCustomizer(WithMockBeanAnnotation.class, null); - assertThat(customizer).isNotNull(); - ContextCustomizer same = this.factory.createContextCustomizer(WithSameMockBeanAnnotation.class, null); - assertThat(customizer).isNotNull(); - ContextCustomizer different = this.factory.createContextCustomizer(WithDifferentMockBeanAnnotation.class, null); - assertThat(different).isNotNull(); - assertThat(customizer).hasSameHashCodeAs(same); - assertThat(customizer.hashCode()).isNotEqualTo(different.hashCode()); - assertThat(customizer).isEqualTo(customizer).isEqualTo(same).isNotEqualTo(different); - } - - static class NoMockBeanAnnotation { - - } - - @SuppressWarnings("removal") - @MockBean({ Service1.class, Service2.class }) - static class WithMockBeanAnnotation { - - } - - @SuppressWarnings("removal") - @MockBean({ Service2.class, Service1.class }) - static class WithSameMockBeanAnnotation { - - } - - @SuppressWarnings("removal") - @MockBean({ Service1.class }) - static class WithDifferentMockBeanAnnotation { - - } - - interface Service1 { - - } - - interface Service2 { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerTests.java deleted file mode 100644 index dca0e56ba5ab..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.core.ResolvableType; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MockitoContextCustomizer}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockitoContextCustomizerTests { - - private static final Set NO_DEFINITIONS = Collections.emptySet(); - - @Test - void hashCodeAndEquals() { - MockDefinition d1 = createTestMockDefinition(ExampleService.class); - MockDefinition d2 = createTestMockDefinition(ExampleServiceCaller.class); - MockitoContextCustomizer c1 = new MockitoContextCustomizer(NO_DEFINITIONS); - MockitoContextCustomizer c2 = new MockitoContextCustomizer(new LinkedHashSet<>(Arrays.asList(d1, d2))); - MockitoContextCustomizer c3 = new MockitoContextCustomizer(new LinkedHashSet<>(Arrays.asList(d2, d1))); - assertThat(c2).hasSameHashCodeAs(c3); - assertThat(c1).isEqualTo(c1).isNotEqualTo(c2); - assertThat(c2).isEqualTo(c2).isEqualTo(c3).isNotEqualTo(c1); - } - - private MockDefinition createTestMockDefinition(Class typeToMock) { - return new MockDefinition(null, ResolvableType.forClass(typeToMock), null, null, false, null, null); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoPostProcessorTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoPostProcessorTests.java deleted file mode 100644 index 6235bdd609fb..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoPostProcessorTests.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.beans.BeanWrapper; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.FailingExampleService; -import org.springframework.boot.test.mock.mockito.example.RealExampleService; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.core.Ordered; -import org.springframework.core.ResolvableType; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.Assert; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Test for {@link MockitoPostProcessor}. See also the integration tests. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @author Andreas Neiser - * @author Madhura Bhave - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class MockitoPostProcessorTests { - - @Test - void cannotMockMultipleBeans() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - MockitoPostProcessor.register(context); - context.register(MultipleBeans.class); - assertThatIllegalStateException().isThrownBy(context::refresh) - .withMessageContaining("Unable to register mock bean " + ExampleService.class.getName() - + " expected a single matching bean to replace but found [example1, example2]"); - } - - @Test - void cannotMockMultipleQualifiedBeans() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - MockitoPostProcessor.register(context); - context.register(MultipleQualifiedBeans.class); - assertThatIllegalStateException().isThrownBy(context::refresh) - .withMessageContaining("Unable to register mock bean " + ExampleService.class.getName() - + " expected a single matching bean to replace but found [example1, example3]"); - } - - @Test - void canMockBeanProducedByFactoryBeanWithClassObjectTypeAttribute() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - MockitoPostProcessor.register(context); - RootBeanDefinition factoryBeanDefinition = new RootBeanDefinition(TestFactoryBean.class); - factoryBeanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, SomeInterface.class); - context.registerBeanDefinition("beanToBeMocked", factoryBeanDefinition); - context.register(MockedFactoryBean.class); - context.refresh(); - assertThat(Mockito.mockingDetails(context.getBean("beanToBeMocked")).isMock()).isTrue(); - } - - @Test - void canMockBeanProducedByFactoryBeanWithResolvableTypeObjectTypeAttribute() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - MockitoPostProcessor.register(context); - RootBeanDefinition factoryBeanDefinition = new RootBeanDefinition(TestFactoryBean.class); - ResolvableType objectType = ResolvableType.forClass(SomeInterface.class); - factoryBeanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, objectType); - context.registerBeanDefinition("beanToBeMocked", factoryBeanDefinition); - context.register(MockedFactoryBean.class); - context.refresh(); - assertThat(Mockito.mockingDetails(context.getBean("beanToBeMocked")).isMock()).isTrue(); - } - - @Test - void canMockPrimaryBean() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - MockitoPostProcessor.register(context); - context.register(MockPrimaryBean.class); - context.refresh(); - assertThat(Mockito.mockingDetails(context.getBean(MockPrimaryBean.class).mock).isMock()).isTrue(); - assertThat(Mockito.mockingDetails(context.getBean(ExampleService.class)).isMock()).isTrue(); - assertThat(Mockito.mockingDetails(context.getBean("examplePrimary", ExampleService.class)).isMock()).isTrue(); - assertThat(Mockito.mockingDetails(context.getBean("exampleQualified", ExampleService.class)).isMock()) - .isFalse(); - } - - @Test - void canMockQualifiedBeanWithPrimaryBeanPresent() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - MockitoPostProcessor.register(context); - context.register(MockQualifiedBean.class); - context.refresh(); - assertThat(Mockito.mockingDetails(context.getBean(MockQualifiedBean.class).mock).isMock()).isTrue(); - assertThat(Mockito.mockingDetails(context.getBean(ExampleService.class)).isMock()).isFalse(); - assertThat(Mockito.mockingDetails(context.getBean("examplePrimary", ExampleService.class)).isMock()).isFalse(); - assertThat(Mockito.mockingDetails(context.getBean("exampleQualified", ExampleService.class)).isMock()).isTrue(); - } - - @Test - void canSpyPrimaryBean() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - MockitoPostProcessor.register(context); - context.register(SpyPrimaryBean.class); - context.refresh(); - assertThat(Mockito.mockingDetails(context.getBean(SpyPrimaryBean.class).spy).isSpy()).isTrue(); - assertThat(Mockito.mockingDetails(context.getBean(ExampleService.class)).isSpy()).isTrue(); - assertThat(Mockito.mockingDetails(context.getBean("examplePrimary", ExampleService.class)).isSpy()).isTrue(); - assertThat(Mockito.mockingDetails(context.getBean("exampleQualified", ExampleService.class)).isSpy()).isFalse(); - } - - @Test - void canSpyQualifiedBeanWithPrimaryBeanPresent() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - MockitoPostProcessor.register(context); - context.register(SpyQualifiedBean.class); - context.refresh(); - assertThat(Mockito.mockingDetails(context.getBean(SpyQualifiedBean.class).spy).isSpy()).isTrue(); - assertThat(Mockito.mockingDetails(context.getBean(ExampleService.class)).isSpy()).isFalse(); - assertThat(Mockito.mockingDetails(context.getBean("examplePrimary", ExampleService.class)).isSpy()).isFalse(); - assertThat(Mockito.mockingDetails(context.getBean("exampleQualified", ExampleService.class)).isSpy()).isTrue(); - } - - @Test - void postProcessorShouldNotTriggerEarlyInitialization() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(FactoryBeanRegisteringPostProcessor.class); - MockitoPostProcessor.register(context); - context.register(TestBeanFactoryPostProcessor.class); - context.register(EagerInitBean.class); - context.refresh(); - } - - @Configuration(proxyBeanMethods = false) - @MockBean(SomeInterface.class) - static class MockedFactoryBean { - - @Bean - TestFactoryBean testFactoryBean() { - return new TestFactoryBean(); - } - - } - - @Configuration(proxyBeanMethods = false) - @MockBean(ExampleService.class) - static class MultipleBeans { - - @Bean - ExampleService example1() { - return new FailingExampleService(); - } - - @Bean - ExampleService example2() { - return new FailingExampleService(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MultipleQualifiedBeans { - - @MockBean - @Qualifier("test") - private ExampleService mock; - - @Bean - @Qualifier("test") - ExampleService example1() { - return new FailingExampleService(); - } - - @Bean - ExampleService example2() { - return new FailingExampleService(); - } - - @Bean - @Qualifier("test") - ExampleService example3() { - return new FailingExampleService(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MockPrimaryBean { - - @MockBean - private ExampleService mock; - - @Bean - @Qualifier("test") - ExampleService exampleQualified() { - return new RealExampleService("qualified"); - } - - @Bean - @Primary - ExampleService examplePrimary() { - return new RealExampleService("primary"); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MockQualifiedBean { - - @MockBean - @Qualifier("test") - private ExampleService mock; - - @Bean - @Qualifier("test") - ExampleService exampleQualified() { - return new RealExampleService("qualified"); - } - - @Bean - @Primary - ExampleService examplePrimary() { - return new RealExampleService("primary"); - } - - } - - @Configuration(proxyBeanMethods = false) - static class SpyPrimaryBean { - - @SpyBean - private ExampleService spy; - - @Bean - @Qualifier("test") - ExampleService exampleQualified() { - return new RealExampleService("qualified"); - } - - @Bean - @Primary - ExampleService examplePrimary() { - return new RealExampleService("primary"); - } - - } - - @Configuration(proxyBeanMethods = false) - static class SpyQualifiedBean { - - @SpyBean - @Qualifier("test") - private ExampleService spy; - - @Bean - @Qualifier("test") - ExampleService exampleQualified() { - return new RealExampleService("qualified"); - } - - @Bean - @Primary - ExampleService examplePrimary() { - return new RealExampleService("primary"); - } - - } - - @Configuration(proxyBeanMethods = false) - static class EagerInitBean { - - @MockBean - private ExampleService service; - - } - - static class TestFactoryBean implements FactoryBean { - - @Override - public Object getObject() { - return new TestBean(); - } - - @Override - public Class getObjectType() { - return null; - } - - @Override - public boolean isSingleton() { - return true; - } - - } - - static class FactoryBeanRegisteringPostProcessor implements BeanFactoryPostProcessor, Ordered { - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { - RootBeanDefinition beanDefinition = new RootBeanDefinition(TestFactoryBean.class); - ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition("test", beanDefinition); - } - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } - - } - - static class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor { - - @Override - @SuppressWarnings("unchecked") - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { - Map cache = (Map) ReflectionTestUtils.getField(beanFactory, - "factoryBeanInstanceCache"); - Assert.isTrue(cache.isEmpty(), "Early initialization of factory bean triggered."); - } - - } - - interface SomeInterface { - - } - - static class TestBean implements SomeInterface { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerIntegrationTests.java deleted file mode 100644 index caa06a16a85d..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerIntegrationTests.java +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.List; -import java.util.UUID; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.ClassOrderer; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestClassOrder; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.TestInstance.Lifecycle; -import org.junit.jupiter.api.TestMethodOrder; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.MockedStatic; - -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.ClassMode; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Integration tests for {@link MockitoTestExecutionListener}. - * - * @author Moritz Halbritter - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class MockitoTestExecutionListenerIntegrationTests { - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - class MockedStaticTests { - - private static final UUID uuid = UUID.randomUUID(); - - @Mock - private MockedStatic mockedStatic; - - @Test - @Order(1) - @Disabled - void shouldReturnConstantValueDisabled() { - this.mockedStatic.when(UUID::randomUUID).thenReturn(uuid); - UUID result = UUID.randomUUID(); - assertThat(result).isEqualTo(uuid); - } - - @Test - @Order(2) - void shouldNotFailBecauseOfMockedStaticNotBeingClosed() { - this.mockedStatic.when(UUID::randomUUID).thenReturn(uuid); - UUID result = UUID.randomUUID(); - assertThat(result).isEqualTo(uuid); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD) - class MockedStaticTestsDirtiesContext { - - private static final UUID uuid = UUID.randomUUID(); - - @Mock - private MockedStatic mockedStatic; - - @Test - @Order(1) - @Disabled - void shouldReturnConstantValueDisabled() { - this.mockedStatic.when(UUID::randomUUID).thenReturn(uuid); - UUID result = UUID.randomUUID(); - assertThat(result).isEqualTo(uuid); - } - - @Test - @Order(2) - void shouldNotFailBecauseOfMockedStaticNotBeingClosed() { - this.mockedStatic.when(UUID::randomUUID).thenReturn(uuid); - UUID result = UUID.randomUUID(); - assertThat(result).isEqualTo(uuid); - } - - @Test - @Order(3) - void shouldNotFailBecauseOfMockedStaticNotBeingClosedWhenMocksAreReinjected() { - this.mockedStatic.when(UUID::randomUUID).thenReturn(uuid); - UUID result = UUID.randomUUID(); - assertThat(result).isEqualTo(uuid); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @TestClassOrder(ClassOrderer.OrderAnnotation.class) - class MockedStaticTestsIfClassContainsOnlyDisabledTests { - - @Nested - @Order(1) - class TestClass1 { - - private static final UUID uuid = UUID.randomUUID(); - - @Mock - private MockedStatic mockedStatic; - - @Test - @Order(1) - @Disabled - void disabledTest() { - this.mockedStatic.when(UUID::randomUUID).thenReturn(uuid); - } - - } - - @Nested - @Order(2) - class TestClass2 { - - private static final UUID uuid = UUID.randomUUID(); - - @Mock - private MockedStatic mockedStatic; - - @Test - @Order(1) - void shouldNotFailBecauseMockedStaticHasNotBeenClosed() { - this.mockedStatic.when(UUID::randomUUID).thenReturn(uuid); - UUID result = UUID.randomUUID(); - assertThat(result).isEqualTo(uuid); - } - - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @TestClassOrder(ClassOrderer.OrderAnnotation.class) - class MockedStaticTestsIfClassContainsNoTests { - - @Nested - @Order(1) - class TestClass1 { - - @Mock - private MockedStatic mockedStatic; - - } - - @Nested - @Order(2) - class TestClass2 { - - private static final UUID uuid = UUID.randomUUID(); - - @Mock - private MockedStatic mockedStatic; - - @Test - @Order(1) - void shouldNotFailBecauseMockedStaticHasNotBeenClosed() { - this.mockedStatic.when(UUID::randomUUID).thenReturn(uuid); - UUID result = UUID.randomUUID(); - assertThat(result).isEqualTo(uuid); - } - - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - class ConfigureMockInBeforeEach { - - @Mock - private List mock; - - @BeforeEach - void setUp() { - given(this.mock.size()).willReturn(1); - } - - @Test - @Order(1) - void shouldUseSetUpConfiguration() { - assertThat(this.mock.size()).isEqualTo(1); - } - - @Test - @Order(2) - void shouldBeAbleToReconfigureMock() { - given(this.mock.size()).willReturn(2); - assertThat(this.mock.size()).isEqualTo(2); - } - - @Test - @Order(3) - void shouldNotBeAffectedByOtherTests() { - assertThat(this.mock.size()).isEqualTo(1); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @TestInstance(Lifecycle.PER_CLASS) - @Disabled("https://github.com/spring-projects/spring-framework/issues/33690") - class ConfigureMockInBeforeAll { - - @Mock - private List mock; - - @BeforeAll - void setUp() { - given(this.mock.size()).willReturn(1); - } - - @Test - @Order(1) - void shouldUseSetUpConfiguration() { - assertThat(this.mock.size()).isEqualTo(1); - } - - @Test - @Order(2) - void shouldBeAbleToReconfigureMock() { - given(this.mock.size()).willReturn(2); - assertThat(this.mock.size()).isEqualTo(2); - } - - @Test - @Order(3) - void shouldNotBeAffectedByOtherTest() { - assertThat(this.mock.size()).isEqualTo(2); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @Import(MyBeanConfiguration.class) - class ConfigureMockBeanWithResetAfterInBeforeEach { - - @MockBean(reset = MockReset.AFTER) - private MyBean mock; - - @BeforeEach - void setUp() { - given(this.mock.call()).willReturn(1); - } - - @Test - @Order(1) - void shouldUseSetUpConfiguration() { - assertThat(this.mock.call()).isEqualTo(1); - } - - @Test - @Order(2) - void shouldBeAbleToReconfigureMock() { - given(this.mock.call()).willReturn(2); - assertThat(this.mock.call()).isEqualTo(2); - } - - @Test - @Order(3) - void shouldNotBeAffectedByOtherTests() { - assertThat(this.mock.call()).isEqualTo(1); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @Import(MyBeanConfiguration.class) - class ConfigureMockBeanWithResetBeforeInBeforeEach { - - @MockBean(reset = MockReset.BEFORE) - private MyBean mock; - - @BeforeEach - void setUp() { - given(this.mock.call()).willReturn(1); - } - - @Test - @Order(1) - void shouldUseSetUpConfiguration() { - assertThat(this.mock.call()).isEqualTo(1); - } - - @Test - @Order(2) - void shouldBeAbleToReconfigureMock() { - given(this.mock.call()).willReturn(2); - assertThat(this.mock.call()).isEqualTo(2); - } - - @Test - @Order(3) - void shouldNotBeAffectedByOtherTests() { - assertThat(this.mock.call()).isEqualTo(1); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @Import(MyBeanConfiguration.class) - class ConfigureMockBeanWithResetNoneInBeforeEach { - - @MockBean(reset = MockReset.NONE) - private MyBean mock; - - @BeforeEach - void setUp() { - given(this.mock.call()).willReturn(1); - } - - @Test - @Order(1) - void shouldUseSetUpConfiguration() { - assertThat(this.mock.call()).isEqualTo(1); - } - - @Test - @Order(2) - void shouldBeAbleToReconfigureMock() { - given(this.mock.call()).willReturn(2); - assertThat(this.mock.call()).isEqualTo(2); - } - - @Test - @Order(3) - void shouldNotBeAffectedByOtherTests() { - assertThat(this.mock.call()).isEqualTo(1); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @TestInstance(Lifecycle.PER_CLASS) - @Import(MyBeanConfiguration.class) - class ConfigureMockBeanWithResetAfterInBeforeAll { - - @MockBean(reset = MockReset.AFTER) - private MyBean mock; - - @BeforeAll - void setUp() { - given(this.mock.call()).willReturn(1); - } - - @Test - @Order(1) - void shouldUseSetUpConfiguration() { - assertThat(this.mock.call()).isEqualTo(1); - } - - @Test - @Order(2) - void shouldBeAbleToReconfigureMock() { - given(this.mock.call()).willReturn(2); - assertThat(this.mock.call()).isEqualTo(2); - } - - @Test - @Order(3) - void shouldResetMockAfterReconfiguration() { - assertThat(this.mock.call()).isEqualTo(0); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @TestInstance(Lifecycle.PER_CLASS) - @Import(MyBeanConfiguration.class) - class ConfigureMockBeanWithResetBeforeInBeforeAll { - - @MockBean(reset = MockReset.BEFORE) - private MyBean mock; - - @BeforeAll - void setUp() { - given(this.mock.call()).willReturn(1); - } - - @Test - @Order(1) - void shouldResetMockBeforeThisMethod() { - assertThat(this.mock.call()).isEqualTo(0); - } - - @Test - @Order(2) - void shouldBeAbleToReconfigureMock() { - given(this.mock.call()).willReturn(2); - assertThat(this.mock.call()).isEqualTo(2); - } - - @Test - @Order(3) - void shouldResetMockAfterReconfiguration() { - assertThat(this.mock.call()).isEqualTo(0); - } - - } - - @Nested - @TestMethodOrder(MethodOrderer.OrderAnnotation.class) - @TestInstance(Lifecycle.PER_CLASS) - @Import(MyBeanConfiguration.class) - class ConfigureMockBeanWithResetNoneInBeforeAll { - - @MockBean(reset = MockReset.NONE) - private MyBean mock; - - @BeforeAll - void setUp() { - given(this.mock.call()).willReturn(1); - } - - @Test - @Order(1) - void shouldUseSetUpConfiguration() { - assertThat(this.mock.call()).isEqualTo(1); - } - - @Test - @Order(2) - void shouldBeAbleToReconfigureMock() { - given(this.mock.call()).willReturn(2); - assertThat(this.mock.call()).isEqualTo(2); - } - - @Test - @Order(3) - void shouldNotResetMock() { - assertThat(this.mock.call()).isEqualTo(2); - } - - } - - interface MyBean { - - int call(); - - } - - private static final class DefaultMyBean implements MyBean { - - @Override - public int call() { - return -1; - } - - } - - @TestConfiguration(proxyBeanMethods = false) - private static final class MyBeanConfiguration { - - @Bean - MyBean myBean() { - return new DefaultMyBean(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerTests.java deleted file mode 100644 index 0065f0b238d4..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/MockitoTestExecutionListenerTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.io.InputStream; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.context.ApplicationContext; -import org.springframework.test.context.TestContext; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.assertArg; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link MockitoTestExecutionListener}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(MockitoExtension.class) -class MockitoTestExecutionListenerTests { - - private final MockitoTestExecutionListener listener = new MockitoTestExecutionListener(); - - @Mock - private ApplicationContext applicationContext; - - @Mock - private MockitoPostProcessor postProcessor; - - @Test - void prepareTestInstanceShouldInitMockitoAnnotations() throws Exception { - WithMockitoAnnotations instance = new WithMockitoAnnotations(); - this.listener.prepareTestInstance(mockTestContext(instance)); - assertThat(instance.mock).isNotNull(); - assertThat(instance.captor).isNotNull(); - } - - @Test - void prepareTestInstanceShouldInjectMockBean() throws Exception { - given(this.applicationContext.getBean(MockitoPostProcessor.class)).willReturn(this.postProcessor); - WithMockBean instance = new WithMockBean(); - TestContext testContext = mockTestContext(instance); - given(testContext.getApplicationContext()).willReturn(this.applicationContext); - this.listener.prepareTestInstance(testContext); - then(this.postProcessor).should() - .inject(assertArg((field) -> assertThat(field.getName()).isEqualTo("mockBean")), eq(instance), - any(MockDefinition.class)); - } - - @Test - void beforeTestMethodShouldDoNothingWhenDirtiesContextAttributeIsNotSet() throws Exception { - this.listener.beforeTestMethod(mock(TestContext.class)); - then(this.postProcessor).shouldHaveNoMoreInteractions(); - } - - @Test - void beforeTestMethodShouldInjectMockBeanWhenDirtiesContextAttributeIsSet() throws Exception { - given(this.applicationContext.getBean(MockitoPostProcessor.class)).willReturn(this.postProcessor); - WithMockBean instance = new WithMockBean(); - TestContext mockTestContext = mockTestContext(instance); - given(mockTestContext.getApplicationContext()).willReturn(this.applicationContext); - given(mockTestContext.getAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE)) - .willReturn(Boolean.TRUE); - this.listener.beforeTestMethod(mockTestContext); - then(this.postProcessor).should() - .inject(assertArg((field) -> assertThat(field.getName()).isEqualTo("mockBean")), eq(instance), - any(MockDefinition.class)); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private TestContext mockTestContext(Object instance) { - TestContext testContext = mock(TestContext.class); - given(testContext.getTestInstance()).willReturn(instance); - given(testContext.getTestClass()).willReturn((Class) instance.getClass()); - return testContext; - } - - static class WithMockitoAnnotations { - - @Mock - InputStream mock; - - @Captor - ArgumentCaptor captor; - - } - - static class WithMockBean { - - @MockBean - InputStream mockBean; - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/QualifierDefinitionTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/QualifierDefinitionTests.java deleted file mode 100644 index 44baa1dc9d9c..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/QualifierDefinitionTests.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.reflect.Field; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.assertArg; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.then; - -/** - * Tests for {@link QualifierDefinition}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(MockitoExtension.class) -class QualifierDefinitionTests { - - @Mock - private ConfigurableListableBeanFactory beanFactory; - - @Test - void forElementFieldIsNullShouldReturnNull() { - assertThat(QualifierDefinition.forElement((Field) null)).isNull(); - } - - @Test - void forElementWhenElementIsNotFieldShouldReturnNull() { - assertThat(QualifierDefinition.forElement(getClass())).isNull(); - } - - @Test - void forElementWhenElementIsFieldWithNoQualifiersShouldReturnNull() { - QualifierDefinition definition = QualifierDefinition - .forElement(ReflectionUtils.findField(ConfigA.class, "noQualifier")); - assertThat(definition).isNull(); - } - - @Test - void forElementWhenElementIsFieldWithQualifierShouldReturnDefinition() { - QualifierDefinition definition = QualifierDefinition - .forElement(ReflectionUtils.findField(ConfigA.class, "directQualifier")); - assertThat(definition).isNotNull(); - } - - @Test - void matchesShouldCallBeanFactory() { - Field field = ReflectionUtils.findField(ConfigA.class, "directQualifier"); - QualifierDefinition qualifierDefinition = QualifierDefinition.forElement(field); - qualifierDefinition.matches(this.beanFactory, "bean"); - then(this.beanFactory).should() - .isAutowireCandidate(eq("bean"), assertArg( - (dependencyDescriptor) -> assertThat(dependencyDescriptor.getAnnotatedElement()).isEqualTo(field))); - } - - @Test - void applyToShouldSetQualifierElement() { - Field field = ReflectionUtils.findField(ConfigA.class, "directQualifier"); - QualifierDefinition qualifierDefinition = QualifierDefinition.forElement(field); - RootBeanDefinition definition = new RootBeanDefinition(); - qualifierDefinition.applyTo(definition); - assertThat(definition.getQualifiedElement()).isEqualTo(field); - } - - @Test - void hashCodeAndEqualsShouldWorkOnDifferentClasses() { - QualifierDefinition directQualifier1 = QualifierDefinition - .forElement(ReflectionUtils.findField(ConfigA.class, "directQualifier")); - QualifierDefinition directQualifier2 = QualifierDefinition - .forElement(ReflectionUtils.findField(ConfigB.class, "directQualifier")); - QualifierDefinition differentDirectQualifier1 = QualifierDefinition - .forElement(ReflectionUtils.findField(ConfigA.class, "differentDirectQualifier")); - QualifierDefinition differentDirectQualifier2 = QualifierDefinition - .forElement(ReflectionUtils.findField(ConfigB.class, "differentDirectQualifier")); - QualifierDefinition customQualifier1 = QualifierDefinition - .forElement(ReflectionUtils.findField(ConfigA.class, "customQualifier")); - QualifierDefinition customQualifier2 = QualifierDefinition - .forElement(ReflectionUtils.findField(ConfigB.class, "customQualifier")); - assertThat(directQualifier1).hasSameHashCodeAs(directQualifier2); - assertThat(differentDirectQualifier1).hasSameHashCodeAs(differentDirectQualifier2); - assertThat(customQualifier1).hasSameHashCodeAs(customQualifier2); - assertThat(differentDirectQualifier1).isEqualTo(differentDirectQualifier1) - .isEqualTo(differentDirectQualifier2) - .isNotEqualTo(directQualifier2); - assertThat(directQualifier1).isEqualTo(directQualifier1) - .isEqualTo(directQualifier2) - .isNotEqualTo(differentDirectQualifier1); - assertThat(customQualifier1).isEqualTo(customQualifier1) - .isEqualTo(customQualifier2) - .isNotEqualTo(differentDirectQualifier1); - } - - @Configuration(proxyBeanMethods = false) - static class ConfigA { - - @MockBean - private Object noQualifier; - - @MockBean - @Qualifier("test") - private Object directQualifier; - - @MockBean - @Qualifier("different") - private Object differentDirectQualifier; - - @MockBean - @CustomQualifier - private Object customQualifier; - - } - - static class ConfigB { - - @MockBean - @Qualifier("test") - private Object directQualifier; - - @MockBean - @Qualifier("different") - private Object differentDirectQualifier; - - @MockBean - @CustomQualifier - private Object customQualifier; - - } - - @Qualifier - @Retention(RetentionPolicy.RUNTIME) - public @interface CustomQualifier { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java deleted file mode 100644 index 5563f2135d56..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ResetMocksTestExecutionListener}. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@TestMethodOrder(MethodOrderer.MethodName.class) -class ResetMocksTestExecutionListenerTests { - - @Autowired - private ApplicationContext context; - - @SpyBean - ToSpy spied; - - @Test - void test001() { - given(getMock("none").greeting()).willReturn("none"); - given(getMock("before").greeting()).willReturn("before"); - given(getMock("after").greeting()).willReturn("after"); - given(getMock("fromFactoryBean").greeting()).willReturn("fromFactoryBean"); - assertThat(this.context.getBean(NonSingletonFactoryBean.class).getObjectInvocations).isEqualTo(0); - given(this.spied.action()).willReturn("spied"); - } - - @Test - void test002() { - assertThat(getMock("none").greeting()).isEqualTo("none"); - assertThat(getMock("before").greeting()).isNull(); - assertThat(getMock("after").greeting()).isNull(); - assertThat(getMock("fromFactoryBean").greeting()).isNull(); - assertThat(this.context.getBean(NonSingletonFactoryBean.class).getObjectInvocations).isEqualTo(0); - assertThat(this.spied.action()).isNull(); - } - - ExampleService getMock(String name) { - return this.context.getBean(name, ExampleService.class); - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - ExampleService before(MockitoBeans mockedBeans) { - ExampleService mock = mock(ExampleService.class, MockReset.before()); - mockedBeans.add(mock); - return mock; - } - - @Bean - ExampleService after(MockitoBeans mockedBeans) { - ExampleService mock = mock(ExampleService.class, MockReset.after()); - mockedBeans.add(mock); - return mock; - } - - @Bean - ExampleService none(MockitoBeans mockedBeans) { - ExampleService mock = mock(ExampleService.class); - mockedBeans.add(mock); - return mock; - } - - @Bean - @Lazy - ExampleService fail() { - // gh-5870 - throw new RuntimeException(); - } - - @Bean - BrokenFactoryBean brokenFactoryBean() { - // gh-7270 - return new BrokenFactoryBean(); - } - - @Bean - WorkingFactoryBean fromFactoryBean() { - return new WorkingFactoryBean(); - } - - @Bean - NonSingletonFactoryBean nonSingletonFactoryBean() { - return new NonSingletonFactoryBean(); - } - - @Bean - ToSpyFactoryBean toSpyFactoryBean() { - return new ToSpyFactoryBean(); - } - - } - - static class BrokenFactoryBean implements FactoryBean { - - @Override - public String getObject() { - throw new IllegalStateException(); - } - - @Override - public Class getObjectType() { - return String.class; - } - - @Override - public boolean isSingleton() { - return true; - } - - } - - static class WorkingFactoryBean implements FactoryBean { - - private final ExampleService service = mock(ExampleService.class, MockReset.before()); - - @Override - public ExampleService getObject() { - return this.service; - } - - @Override - public Class getObjectType() { - return ExampleService.class; - } - - @Override - public boolean isSingleton() { - return true; - } - - } - - static class ToSpy { - - String action() { - return null; - } - - } - - static class NonSingletonFactoryBean implements FactoryBean { - - private int getObjectInvocations = 0; - - @Override - public ExampleService getObject() { - this.getObjectInvocations++; - return mock(ExampleService.class, MockReset.before()); - } - - @Override - public Class getObjectType() { - return ExampleService.class; - } - - @Override - public boolean isSingleton() { - return false; - } - - } - - static class ToSpyFactoryBean implements FactoryBean { - - @Override - public ToSpy getObject() throws Exception { - return new ToSpy(); - } - - @Override - public Class getObjectType() { - return ToSpy.class; - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpringBootMockResolverTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpringBootMockResolverTests.java deleted file mode 100644 index 057ac082456f..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpringBootMockResolverTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; - -import org.springframework.aop.SpringProxy; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.target.HotSwappableTargetSource; -import org.springframework.aop.target.SingletonTargetSource; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SpringBootMockResolver}. - * - * @author Moritz Halbritter - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class SpringBootMockResolverTests { - - @Test - void testStaticTarget() { - MyServiceImpl myService = new MyServiceImpl(); - MyService proxy = ProxyFactory.getProxy(MyService.class, new SingletonTargetSource(myService)); - Object target = new SpringBootMockResolver().resolve(proxy); - assertThat(target).isInstanceOf(MyServiceImpl.class); - } - - @Test - void testNonStaticTarget() { - MyServiceImpl myService = new MyServiceImpl(); - MyService proxy = ProxyFactory.getProxy(MyService.class, new HotSwappableTargetSource(myService)); - Object target = new SpringBootMockResolver().resolve(proxy); - assertThat(target).isInstanceOf(SpringProxy.class); - } - - private interface MyService { - - int a(); - - } - - private static final class MyServiceImpl implements MyService { - - @Override - public int a() { - return 1; - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationClassForExistingBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationClassForExistingBeanIntegrationTests.java deleted file mode 100644 index c17ac5ff6a37..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationClassForExistingBeanIntegrationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a configuration class can be used to spy existing - * beans. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnConfigurationClassForExistingBeanIntegrationTests { - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.caller.getService()).should().greeting(); - } - - @SuppressWarnings("removal") - @Configuration(proxyBeanMethods = false) - @SpyBean(SimpleExampleService.class) - @Import({ ExampleServiceCaller.class, SimpleExampleService.class }) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationClassForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationClassForNewBeanIntegrationTests.java deleted file mode 100644 index 64e2cbd5ca2b..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationClassForNewBeanIntegrationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a configuration class can be used to inject new spy - * instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnConfigurationClassForNewBeanIntegrationTests { - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.caller.getService()).should().greeting(); - } - - @SuppressWarnings("removal") - @Configuration(proxyBeanMethods = false) - @SpyBean(SimpleExampleService.class) - @Import(ExampleServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationFieldForExistingBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationFieldForExistingBeanIntegrationTests.java deleted file mode 100644 index 85ebcfe29545..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationFieldForExistingBeanIntegrationTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a field on a {@code @Configuration} class can be used - * to replace existing beans. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnConfigurationFieldForExistingBeanIntegrationTests { - - @Autowired - private Config config; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.config.exampleService).should().greeting(); - } - - @Configuration(proxyBeanMethods = false) - @Import({ ExampleServiceCaller.class, SimpleExampleService.class }) - static class Config { - - @SpyBean - private ExampleService exampleService; - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationFieldForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationFieldForNewBeanIntegrationTests.java deleted file mode 100644 index 6fc5e6ce3d20..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnConfigurationFieldForNewBeanIntegrationTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a field on a {@code @Configuration} class can be used - * to inject new spy instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnConfigurationFieldForNewBeanIntegrationTests { - - @Autowired - private Config config; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.config.exampleService).should().greeting(); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleServiceCaller.class) - static class Config { - - @SpyBean - private SimpleExampleService exampleService; - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnContextHierarchyIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnContextHierarchyIntegrationTests.java deleted file mode 100644 index ab3a2119b884..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnContextHierarchyIntegrationTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.ContextHierarchy; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Test {@link SpyBean @SpyBean} can be used with a - * {@link ContextHierarchy @ContextHierarchy}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@ContextHierarchy({ @ContextConfiguration(classes = SpyBeanOnContextHierarchyIntegrationTests.ParentConfig.class), - @ContextConfiguration(classes = SpyBeanOnContextHierarchyIntegrationTests.ChildConfig.class) }) -class SpyBeanOnContextHierarchyIntegrationTests { - - @Autowired - private ChildConfig childConfig; - - @Test - void testSpying() { - ApplicationContext context = this.childConfig.getContext(); - ApplicationContext parentContext = context.getParent(); - assertThat(parentContext - .getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleService.class)).hasSize(1); - assertThat(parentContext - .getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class)) - .isEmpty(); - assertThat(context.getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleService.class)) - .isEmpty(); - assertThat(context - .getBeanNamesForType(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class)) - .hasSize(1); - assertThat(context.getBean(org.springframework.boot.test.mock.mockito.example.ExampleService.class)) - .isNotNull(); - assertThat(context.getBean(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class)) - .isNotNull(); - } - - @Configuration(proxyBeanMethods = false) - @SpyBean(org.springframework.boot.test.mock.mockito.example.SimpleExampleService.class) - static class ParentConfig { - - } - - @Configuration(proxyBeanMethods = false) - @SpyBean(org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller.class) - static class ChildConfig implements ApplicationContextAware { - - private ApplicationContext context; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) { - this.context = applicationContext; - } - - ApplicationContext getContext() { - return this.context; - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestClassForExistingBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestClassForExistingBeanIntegrationTests.java deleted file mode 100644 index f10b31c21e5f..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestClassForExistingBeanIntegrationTests.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class can be used to replace existing beans. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@SpyBean(SimpleExampleService.class) -class SpyBeanOnTestClassForExistingBeanIntegrationTests { - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.caller.getService()).should().greeting(); - } - - @Configuration(proxyBeanMethods = false) - @Import({ ExampleServiceCaller.class, SimpleExampleService.class }) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestClassForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestClassForNewBeanIntegrationTests.java deleted file mode 100644 index 7755fad1485c..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestClassForNewBeanIntegrationTests.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class can be used to inject new spy instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@SpyBean(SimpleExampleService.class) -class SpyBeanOnTestClassForNewBeanIntegrationTests { - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.caller.getService()).should().greeting(); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanCacheIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanCacheIntegrationTests.java deleted file mode 100644 index b5f36b797b9c..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanCacheIntegrationTests.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to replace existing - * beans when the context is cached. This test is identical to - * {@link SpyBeanOnTestFieldForExistingBeanIntegrationTests} so one of them should trigger - * application context caching. - * - * @author Phillip Webb - * @see SpyBeanOnTestFieldForExistingBeanIntegrationTests - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = SpyBeanOnTestFieldForExistingBeanConfig.class) -class SpyBeanOnTestFieldForExistingBeanCacheIntegrationTests { - - @SpyBean - private ExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.caller.getService()).should().greeting(); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanConfig.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanConfig.java deleted file mode 100644 index 010438291a0e..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Config for {@link SpyBeanOnTestFieldForExistingBeanIntegrationTests} and - * {@link SpyBeanOnTestFieldForExistingBeanCacheIntegrationTests}. Extracted to a shared - * config to trigger caching. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@Configuration(proxyBeanMethods = false) -@Import({ ExampleServiceCaller.class, SimpleExampleService.class }) -public class SpyBeanOnTestFieldForExistingBeanConfig { - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanIntegrationTests.java deleted file mode 100644 index 843005d5ad8d..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanIntegrationTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to replace existing - * beans. - * - * @author Phillip Webb - * @see SpyBeanOnTestFieldForExistingBeanCacheIntegrationTests - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = SpyBeanOnTestFieldForExistingBeanConfig.class) -class SpyBeanOnTestFieldForExistingBeanIntegrationTests { - - @SpyBean - private ExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.caller.getService()).should().greeting(); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanWithQualifierIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanWithQualifierIntegrationTests.java deleted file mode 100644 index 208115a56f3c..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingBeanWithQualifierIntegrationTests.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.CustomQualifier; -import org.springframework.boot.test.mock.mockito.example.CustomQualifierExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.RealExampleService; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to replace existing - * bean while preserving qualifiers. - * - * @author Andreas Neiser - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnTestFieldForExistingBeanWithQualifierIntegrationTests { - - @SpyBean - @CustomQualifier - private ExampleService service; - - @Autowired - private ExampleServiceCaller caller; - - @Autowired - private ApplicationContext applicationContext; - - @Test - void testMocking() { - this.caller.sayGreeting(); - then(this.service).should().greeting(); - } - - @Test - void onlyQualifiedBeanIsReplaced() { - assertThat(this.applicationContext.getBean("service")).isSameAs(this.service); - ExampleService anotherService = this.applicationContext.getBean("anotherService", ExampleService.class); - assertThat(anotherService.greeting()).isEqualTo("Another"); - } - - @Configuration(proxyBeanMethods = false) - static class TestConfig { - - @Bean - CustomQualifierExampleService service() { - return new CustomQualifierExampleService(); - } - - @Bean - ExampleService anotherService() { - return new RealExampleService("Another"); - } - - @Bean - ExampleServiceCaller controller(@CustomQualifier ExampleService service) { - return new ExampleServiceCaller(service); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingCircularBeansIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingCircularBeansIntegrationTests.java deleted file mode 100644 index 2f36f7ca903d..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingCircularBeansIntegrationTests.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to replace existing - * beans with circular dependencies. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@ContextConfiguration( - classes = SpyBeanOnTestFieldForExistingCircularBeansIntegrationTests.SpyBeanOnTestFieldForExistingCircularBeansConfig.class) -class SpyBeanOnTestFieldForExistingCircularBeansIntegrationTests { - - @SpyBean - private One one; - - @Autowired - private Two two; - - @Test - void beanWithCircularDependenciesCanBeSpied() { - this.two.callOne(); - then(this.one).should().someMethod(); - } - - @Import({ One.class, Two.class }) - static class SpyBeanOnTestFieldForExistingCircularBeansConfig { - - } - - static class One { - - @Autowired - @SuppressWarnings("unused") - private Two two; - - void someMethod() { - - } - - } - - static class Two { - - @Autowired - private One one; - - void callOne() { - this.one.someMethod(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingGenericBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingGenericBeanIntegrationTests.java deleted file mode 100644 index f76f4ce49651..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingGenericBeanIntegrationTests.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleGenericService; -import org.springframework.boot.test.mock.mockito.example.ExampleGenericServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleIntegerGenericService; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleStringGenericService; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to replace existing - * beans. - * - * @author Phillip Webb - * @see SpyBeanOnTestFieldForExistingBeanCacheIntegrationTests - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnTestFieldForExistingGenericBeanIntegrationTests { - - // gh-7625 - - @SpyBean - private ExampleGenericService exampleService; - - @Autowired - private ExampleGenericServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say 123 simple"); - then(this.exampleService).should().greeting(); - } - - @Configuration(proxyBeanMethods = false) - @Import({ ExampleGenericServiceCaller.class, SimpleExampleIntegerGenericService.class }) - static class SpyBeanOnTestFieldForExistingBeanConfig { - - @Bean - ExampleGenericService simpleExampleStringGenericService() { - // In order to trigger issue we need a method signature that returns the - // generic type not the actual implementation class - return new SimpleExampleStringGenericService(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingGenericBeanProducedByFactoryBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingGenericBeanProducedByFactoryBeanIntegrationTests.java deleted file mode 100644 index afd0c50dbdff..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForExistingGenericBeanProducedByFactoryBeanIntegrationTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.test.mock.mockito.example.ExampleGenericService; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleStringGenericService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.ResolvableType; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to replace an existing - * bean with generics that's produced by a factory bean. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnTestFieldForExistingGenericBeanProducedByFactoryBeanIntegrationTests { - - // gh-40234 - - @SpyBean(name = "exampleService") - private ExampleGenericService exampleService; - - @Test - void testSpying() { - assertThat(Mockito.mockingDetails(this.exampleService).isSpy()).isTrue(); - assertThat(Mockito.mockingDetails(this.exampleService).getMockCreationSettings().getSpiedInstance()) - .isInstanceOf(SimpleExampleStringGenericService.class); - } - - @Configuration(proxyBeanMethods = false) - @Import(FactoryBeanRegistrar.class) - static class SpyBeanOnTestFieldForExistingBeanConfig { - - } - - static class FactoryBeanRegistrar implements ImportBeanDefinitionRegistrar { - - @Override - public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, - BeanDefinitionRegistry registry) { - RootBeanDefinition definition = new RootBeanDefinition(ExampleGenericServiceFactoryBean.class); - definition.setTargetType(ResolvableType.forClassWithGenerics(ExampleGenericServiceFactoryBean.class, null, - ExampleGenericService.class)); - registry.registerBeanDefinition("exampleService", definition); - } - - } - - static class ExampleGenericServiceFactoryBean> implements FactoryBean { - - @SuppressWarnings("unchecked") - @Override - public U getObject() throws Exception { - return (U) new SimpleExampleStringGenericService(); - } - - @Override - @SuppressWarnings("rawtypes") - public Class getObjectType() { - return ExampleGenericService.class; - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForMultipleExistingBeansWithOnePrimaryIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForMultipleExistingBeansWithOnePrimaryIntegrationTests.java deleted file mode 100644 index a9fedd8d4a3f..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForMultipleExistingBeansWithOnePrimaryIntegrationTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleGenericStringServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleStringGenericService; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to inject a spy - * instance when there are multiple candidates and one is primary. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnTestFieldForMultipleExistingBeansWithOnePrimaryIntegrationTests { - - @SpyBean - private SimpleExampleStringGenericService spy; - - @Autowired - private ExampleGenericStringServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say two"); - assertThat(Mockito.mockingDetails(this.spy).getMockCreationSettings().getMockName()).hasToString("two"); - then(this.spy).should().greeting(); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleGenericStringServiceCaller.class) - static class Config { - - @Bean - SimpleExampleStringGenericService one() { - return new SimpleExampleStringGenericService("one"); - } - - @Bean - @Primary - SimpleExampleStringGenericService two() { - return new SimpleExampleStringGenericService("two"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForNewBeanIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForNewBeanIntegrationTests.java deleted file mode 100644 index 54342be3757e..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanOnTestFieldForNewBeanIntegrationTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to inject new spy - * instances. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanOnTestFieldForNewBeanIntegrationTests { - - @SpyBean - private SimpleExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - assertThat(this.caller.sayGreeting()).isEqualTo("I say simple"); - then(this.caller.getService()).should().greeting(); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithAopProxyAndNotProxyTargetAwareTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithAopProxyAndNotProxyTargetAwareTests.java deleted file mode 100644 index b7fb99ec3359..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithAopProxyAndNotProxyTargetAwareTests.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.exceptions.misusing.UnfinishedVerificationException; - -import org.springframework.cache.CacheManager; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.annotation.EnableCaching; -import org.springframework.cache.concurrent.ConcurrentMapCacheManager; -import org.springframework.cache.interceptor.CacheResolver; -import org.springframework.cache.interceptor.SimpleCacheResolver; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Service; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.reset; - -/** - * Test {@link SpyBean @SpyBean} when mixed with Spring AOP. - * - * @author Phillip Webb - * @see 5837 - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanWithAopProxyAndNotProxyTargetAwareTests { - - @SpyBean(proxyTargetAware = false) - private DateService dateService; - - @Test - void verifyShouldUseProxyTarget() { - this.dateService.getDate(false); - then(this.dateService).should().getDate(false); - assertThatExceptionOfType(UnfinishedVerificationException.class).isThrownBy(() -> reset(this.dateService)); - } - - @Configuration(proxyBeanMethods = false) - @EnableCaching(proxyTargetClass = true) - @Import(DateService.class) - static class Config { - - @Bean - CacheResolver cacheResolver(CacheManager cacheManager) { - SimpleCacheResolver resolver = new SimpleCacheResolver(); - resolver.setCacheManager(cacheManager); - return resolver; - } - - @Bean - ConcurrentMapCacheManager cacheManager() { - ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); - cacheManager.setCacheNames(Arrays.asList("test")); - return cacheManager; - } - - } - - @Service - public static class DateService { - - @Cacheable(cacheNames = "test") - public Long getDate(boolean arg) { - return System.nanoTime(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithAopProxyTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithAopProxyTests.java deleted file mode 100644 index b51c7241109a..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithAopProxyTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.cache.CacheManager; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.annotation.EnableCaching; -import org.springframework.cache.concurrent.ConcurrentMapCacheManager; -import org.springframework.cache.interceptor.CacheResolver; -import org.springframework.cache.interceptor.SimpleCacheResolver; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Service; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.then; - -/** - * Test {@link SpyBean @SpyBean} when mixed with Spring AOP. - * - * @author Phillip Webb - * @see 5837 - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanWithAopProxyTests { - - @SpyBean - private DateService dateService; - - @Test - void verifyShouldUseProxyTarget() throws Exception { - Long d1 = this.dateService.getDate(false); - Thread.sleep(200); - Long d2 = this.dateService.getDate(false); - assertThat(d1).isEqualTo(d2); - then(this.dateService).should().getDate(false); - then(this.dateService).should().getDate(eq(false)); - then(this.dateService).should().getDate(anyBoolean()); - } - - @Configuration(proxyBeanMethods = false) - @EnableCaching(proxyTargetClass = true) - @Import(DateService.class) - static class Config { - - @Bean - CacheResolver cacheResolver(CacheManager cacheManager) { - SimpleCacheResolver resolver = new SimpleCacheResolver(); - resolver.setCacheManager(cacheManager); - return resolver; - } - - @Bean - ConcurrentMapCacheManager cacheManager() { - ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); - cacheManager.setCacheNames(Arrays.asList("test")); - return cacheManager; - } - - } - - @Service - public static class DateService { - - @Cacheable(cacheNames = "test") - public Long getDate(boolean arg) { - return System.nanoTime(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithDirtiesContextClassModeBeforeMethodIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithDirtiesContextClassModeBeforeMethodIntegrationTests.java deleted file mode 100644 index 44dc01e48fba..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithDirtiesContextClassModeBeforeMethodIntegrationTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.SimpleExampleService; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.ClassMode; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.mockito.BDDMockito.then; - -/** - * Integration tests for using {@link SpyBean @SpyBean} with - * {@link DirtiesContext @DirtiesContext} and {@link ClassMode#BEFORE_EACH_TEST_METHOD}. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD) -class SpyBeanWithDirtiesContextClassModeBeforeMethodIntegrationTests { - - @SpyBean - private SimpleExampleService exampleService; - - @Autowired - private ExampleServiceCaller caller; - - @Test - void testSpying() { - this.caller.sayGreeting(); - then(this.exampleService).should().greeting(); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleServiceCaller.class) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithJdkProxyTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithJdkProxyTests.java deleted file mode 100644 index 22ae8ba8d77d..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithJdkProxyTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import java.lang.reflect.Proxy; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Tests for {@link SpyBean @SpyBean} with a JDK proxy. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanWithJdkProxyTests { - - @Autowired - private ExampleService service; - - @SpyBean - private ExampleRepository repository; - - @Test - void jdkProxyCanBeSpied() { - Example example = this.service.find("id"); - assertThat(example.id).isEqualTo("id"); - then(this.repository).should().find("id"); - } - - @Configuration(proxyBeanMethods = false) - @Import(ExampleService.class) - static class Config { - - @Bean - ExampleRepository dateService() { - return (ExampleRepository) Proxy.newProxyInstance(getClass().getClassLoader(), - new Class[] { ExampleRepository.class }, (proxy, method, args) -> new Example((String) args[0])); - } - - } - - static class ExampleService { - - private final ExampleRepository repository; - - ExampleService(ExampleRepository repository) { - this.repository = repository; - } - - Example find(String id) { - return this.repository.find(id); - } - - } - - interface ExampleRepository { - - Example find(String id); - - } - - static class Example { - - private final String id; - - Example(String id) { - this.id = id; - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithNameOnTestFieldForMultipleExistingBeansTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithNameOnTestFieldForMultipleExistingBeansTests.java deleted file mode 100644 index 0591f79b6c2e..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyBeanWithNameOnTestFieldForMultipleExistingBeansTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockingDetails; -import org.mockito.Mockito; - -import org.springframework.boot.test.mock.mockito.example.SimpleExampleStringGenericService; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Test {@link SpyBean @SpyBean} on a test class field can be used to inject a spy - * instance when there are multiple candidates and one is chosen using the name attribute. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@ExtendWith(SpringExtension.class) -class SpyBeanWithNameOnTestFieldForMultipleExistingBeansTests { - - @SpyBean(name = "two") - private SimpleExampleStringGenericService spy; - - @Test - void testSpying() { - MockingDetails mockingDetails = Mockito.mockingDetails(this.spy); - assertThat(mockingDetails.isSpy()).isTrue(); - assertThat(mockingDetails.getMockCreationSettings().getMockName()).hasToString("two"); - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - SimpleExampleStringGenericService one() { - return new SimpleExampleStringGenericService("one"); - } - - @Bean - SimpleExampleStringGenericService two() { - return new SimpleExampleStringGenericService("two"); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyDefinitionTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyDefinitionTests.java deleted file mode 100644 index f19d48918041..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/SpyDefinitionTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito; - -import org.junit.jupiter.api.Test; -import org.mockito.Answers; -import org.mockito.Mockito; -import org.mockito.mock.MockCreationSettings; - -import org.springframework.boot.test.mock.mockito.example.ExampleService; -import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller; -import org.springframework.boot.test.mock.mockito.example.RealExampleService; -import org.springframework.core.ResolvableType; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link SpyDefinition}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class SpyDefinitionTests { - - private static final ResolvableType REAL_SERVICE_TYPE = ResolvableType.forClass(RealExampleService.class); - - @Test - void classToSpyMustNotBeNull() { - assertThatIllegalArgumentException().isThrownBy(() -> new SpyDefinition(null, null, null, true, null)) - .withMessageContaining("'typeToSpy' must not be null"); - } - - @Test - void createWithDefaults() { - SpyDefinition definition = new SpyDefinition(null, REAL_SERVICE_TYPE, null, true, null); - assertThat(definition.getName()).isNull(); - assertThat(definition.getTypeToSpy()).isEqualTo(REAL_SERVICE_TYPE); - assertThat(definition.getReset()).isEqualTo(MockReset.AFTER); - assertThat(definition.isProxyTargetAware()).isTrue(); - assertThat(definition.getQualifier()).isNull(); - } - - @Test - void createExplicit() { - QualifierDefinition qualifier = mock(QualifierDefinition.class); - SpyDefinition definition = new SpyDefinition("name", REAL_SERVICE_TYPE, MockReset.BEFORE, false, qualifier); - assertThat(definition.getName()).isEqualTo("name"); - assertThat(definition.getTypeToSpy()).isEqualTo(REAL_SERVICE_TYPE); - assertThat(definition.getReset()).isEqualTo(MockReset.BEFORE); - assertThat(definition.isProxyTargetAware()).isFalse(); - assertThat(definition.getQualifier()).isEqualTo(qualifier); - } - - @Test - void createSpy() { - SpyDefinition definition = new SpyDefinition("name", REAL_SERVICE_TYPE, MockReset.BEFORE, true, null); - RealExampleService spy = definition.createSpy(new RealExampleService("hello")); - MockCreationSettings settings = Mockito.mockingDetails(spy).getMockCreationSettings(); - assertThat(spy).isInstanceOf(ExampleService.class); - assertThat(settings.getMockName()).hasToString("name"); - assertThat(settings.getDefaultAnswer()).isEqualTo(Answers.CALLS_REAL_METHODS); - assertThat(MockReset.get(spy)).isEqualTo(MockReset.BEFORE); - } - - @Test - void createSpyWhenNullInstanceShouldThrowException() { - SpyDefinition definition = new SpyDefinition("name", REAL_SERVICE_TYPE, MockReset.BEFORE, true, null); - assertThatIllegalArgumentException().isThrownBy(() -> definition.createSpy(null)) - .withMessageContaining("'instance' must not be null"); - } - - @Test - void createSpyWhenWrongInstanceShouldThrowException() { - SpyDefinition definition = new SpyDefinition("name", REAL_SERVICE_TYPE, MockReset.BEFORE, true, null); - assertThatIllegalArgumentException().isThrownBy(() -> definition.createSpy(new ExampleServiceCaller(null))) - .withMessageContaining("must be an instance of"); - } - - @Test - void createSpyTwice() { - SpyDefinition definition = new SpyDefinition("name", REAL_SERVICE_TYPE, MockReset.BEFORE, true, null); - Object instance = new RealExampleService("hello"); - instance = definition.createSpy(instance); - definition.createSpy(instance); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/CustomQualifier.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/CustomQualifier.java deleted file mode 100644 index fe1a919aad05..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/CustomQualifier.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import org.springframework.beans.factory.annotation.Qualifier; - -/** - * Custom qualifier for testing. - * - * @author Stephane Nicoll - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@Deprecated(since = "3.4.0", forRemoval = true) -@Qualifier -@Retention(RetentionPolicy.RUNTIME) -public @interface CustomQualifier { - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/CustomQualifierExampleService.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/CustomQualifierExampleService.java deleted file mode 100644 index 64ee9d73a051..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/CustomQualifierExampleService.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * An {@link ExampleService} that uses a custom qualifier. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@CustomQualifier -public class CustomQualifierExampleService implements ExampleService { - - @Override - public String greeting() { - return "CustomQualifier"; - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleExtraInterface.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleExtraInterface.java deleted file mode 100644 index 51a9b462dbcd..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleExtraInterface.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example extra interface for mocking tests. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public interface ExampleExtraInterface { - - String doExtra(); - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericService.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericService.java deleted file mode 100644 index bfd5d080bbd3..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericService.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example service interface for mocking tests. - * - * @param the generic type - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public interface ExampleGenericService { - - T greeting(); - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericServiceCaller.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericServiceCaller.java deleted file mode 100644 index d7a4bf61a7db..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericServiceCaller.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example bean for mocking tests that calls {@link ExampleGenericService}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class ExampleGenericServiceCaller { - - private final ExampleGenericService integerService; - - private final ExampleGenericService stringService; - - public ExampleGenericServiceCaller(ExampleGenericService integerService, - ExampleGenericService stringService) { - this.integerService = integerService; - this.stringService = stringService; - } - - public ExampleGenericService getIntegerService() { - return this.integerService; - } - - public ExampleGenericService getStringService() { - return this.stringService; - } - - public String sayGreeting() { - return "I say " + this.integerService.greeting() + " " + this.stringService.greeting(); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericStringServiceCaller.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericStringServiceCaller.java deleted file mode 100644 index 82a7102e0f87..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleGenericStringServiceCaller.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example bean for mocking tests that calls {@link ExampleGenericService}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class ExampleGenericStringServiceCaller { - - private final ExampleGenericService stringService; - - public ExampleGenericStringServiceCaller(ExampleGenericService stringService) { - this.stringService = stringService; - } - - public ExampleGenericService getStringService() { - return this.stringService; - } - - public String sayGreeting() { - return "I say " + this.stringService.greeting(); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleService.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleService.java deleted file mode 100644 index 8e9ecc5d50bf..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleService.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example service interface for mocking tests. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public interface ExampleService { - - String greeting(); - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleServiceCaller.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleServiceCaller.java deleted file mode 100644 index e627c7c87796..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/ExampleServiceCaller.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example bean for mocking tests that calls {@link ExampleService}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class ExampleServiceCaller { - - private final ExampleService service; - - public ExampleServiceCaller(ExampleService service) { - this.service = service; - } - - public ExampleService getService() { - return this.service; - } - - public String sayGreeting() { - return "I say " + this.service.greeting(); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/FailingExampleService.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/FailingExampleService.java deleted file mode 100644 index 33f008bb4b10..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/FailingExampleService.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -import org.springframework.stereotype.Service; - -/** - * An {@link ExampleService} that always throws an exception. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@Service -public class FailingExampleService implements ExampleService { - - @Override - public String greeting() { - throw new IllegalStateException("Failed"); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/RealExampleService.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/RealExampleService.java deleted file mode 100644 index 98b4df1c83b5..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/RealExampleService.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example service implementation for spy tests. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class RealExampleService implements ExampleService { - - private final String greeting; - - public RealExampleService(String greeting) { - this.greeting = greeting; - } - - @Override - public String greeting() { - return this.greeting; - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleIntegerGenericService.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleIntegerGenericService.java deleted file mode 100644 index 6de592517f85..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleIntegerGenericService.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example generic service implementation for spy tests. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class SimpleExampleIntegerGenericService implements ExampleGenericService { - - @Override - public Integer greeting() { - return 123; - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleService.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleService.java deleted file mode 100644 index a617f727986c..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleService.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example service implementation for spy tests. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class SimpleExampleService extends RealExampleService { - - public SimpleExampleService() { - super("simple"); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleStringGenericService.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleStringGenericService.java deleted file mode 100644 index 075744e61bd4..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/example/SimpleExampleStringGenericService.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.test.mock.mockito.example; - -/** - * Example generic service implementation for spy tests. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class SimpleExampleStringGenericService implements ExampleGenericService { - - private final String greeting; - - public SimpleExampleStringGenericService() { - this("simple"); - } - - public SimpleExampleStringGenericService(String greeting) { - this.greeting = greeting; - } - - @Override - public String greeting() { - return this.greeting; - } - -} diff --git a/spring-boot-project/spring-boot-testcontainers/build.gradle b/spring-boot-project/spring-boot-testcontainers/build.gradle index 29151f6e6d1a..d4ddf6cc947a 100644 --- a/spring-boot-project/spring-boot-testcontainers/build.gradle +++ b/spring-boot-project/spring-boot-testcontainers/build.gradle @@ -16,6 +16,7 @@ plugins { id "java-library" + id "java-test-fixtures" id "org.springframework.boot.auto-configuration" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.deployed" @@ -32,86 +33,30 @@ dependencies { dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) dockerTestImplementation("ch.qos.logback:logback-classic") - dockerTestImplementation("co.elastic.clients:elasticsearch-java") - dockerTestImplementation("com.couchbase.client:java-client") - dockerTestImplementation("com.hazelcast:hazelcast") - dockerTestImplementation("io.micrometer:micrometer-registry-otlp") - dockerTestImplementation("io.rest-assured:rest-assured") - dockerTestImplementation("org.apache.activemq:activemq-client") - dockerTestImplementation("org.apache.activemq:artemis-jakarta-client") - dockerTestImplementation("org.apache.cassandra:java-driver-core") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } + dockerTestImplementation("com.redis:testcontainers-redis") dockerTestImplementation("org.assertj:assertj-core") dockerTestImplementation("org.awaitility:awaitility") dockerTestImplementation("org.elasticsearch.client:elasticsearch-rest-client") - dockerTestImplementation("org.flywaydb:flyway-core") dockerTestImplementation("org.junit.jupiter:junit-jupiter") dockerTestImplementation("org.junit.platform:junit-platform-launcher") - dockerTestImplementation("org.liquibase:liquibase-core") { - exclude(group: "javax.xml.bind", module: "jaxb-api") - } dockerTestImplementation("org.mockito:mockito-core") dockerTestImplementation("org.springframework:spring-core-test") dockerTestImplementation("org.springframework:spring-jdbc") - dockerTestImplementation("org.springframework:spring-jms") - dockerTestImplementation("org.springframework:spring-r2dbc") - dockerTestImplementation("org.springframework.amqp:spring-rabbit") - dockerTestImplementation("org.springframework.data:spring-data-redis") - dockerTestImplementation("org.springframework.kafka:spring-kafka") - dockerTestImplementation("org.springframework.ldap:spring-ldap-core") - dockerTestImplementation("org.springframework.pulsar:spring-pulsar") dockerTestImplementation("org.testcontainers:junit-jupiter") + dockerTestImplementation("org.testcontainers:postgresql") - dockerTestRuntimeOnly("com.oracle.database.r2dbc:oracle-r2dbc") dockerTestRuntimeOnly("com.zaxxer:HikariCP") - dockerTestRuntimeOnly("io.lettuce:lettuce-core") - dockerTestRuntimeOnly("org.flywaydb:flyway-database-postgresql") + dockerTestRuntimeOnly("com.h2database:h2") dockerTestRuntimeOnly("org.postgresql:postgresql") - optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) optional("org.springframework:spring-test") optional("org.springframework.data:spring-data-mongodb") optional("org.springframework.data:spring-data-neo4j") - optional("org.testcontainers:activemq") - optional("org.testcontainers:cassandra") - optional("org.testcontainers:clickhouse") - optional("org.testcontainers:couchbase") - optional("org.testcontainers:elasticsearch") - optional("org.testcontainers:grafana") - optional("org.testcontainers:jdbc") - optional("org.testcontainers:kafka") - optional("org.testcontainers:ldap") - optional("org.testcontainers:mariadb") - optional("org.testcontainers:mongodb") - optional("org.testcontainers:mssqlserver") - optional("org.testcontainers:mysql") - optional("org.testcontainers:neo4j") - optional("org.testcontainers:oracle-xe") - optional("org.testcontainers:oracle-free") - optional("org.testcontainers:postgresql") - optional("org.testcontainers:pulsar") - optional("org.testcontainers:rabbitmq") - optional("org.testcontainers:redpanda") - optional("org.testcontainers:r2dbc") - optional("com.redis:testcontainers-redis") - optional("com.hazelcast:hazelcast") testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("org.assertj:assertj-core") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.springframework:spring-core-test") - testImplementation("org.springframework:spring-jdbc") - testImplementation("org.springframework:spring-jms") - testImplementation("org.springframework:spring-r2dbc") - testImplementation("org.springframework.amqp:spring-rabbit") - testImplementation("org.springframework.data:spring-data-redis") - testImplementation("org.springframework.kafka:spring-kafka") - testImplementation("org.springframework.pulsar:spring-pulsar") testImplementation("org.testcontainers:junit-jupiter") + testImplementation("org.testcontainers:postgresql") } dockerTest { diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/LoadTimeWeaverAwareConsumerImportTestcontainersTests.java b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/LoadTimeWeaverAwareConsumerImportTestcontainersTests.java index 7896a0d21d1e..62bd5e625bf9 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/LoadTimeWeaverAwareConsumerImportTestcontainersTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/LoadTimeWeaverAwareConsumerImportTestcontainersTests.java @@ -16,19 +16,21 @@ package org.springframework.boot.testcontainers; +import javax.sql.DataSource; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.testcontainers.context.ImportTestcontainers; +import org.springframework.boot.testcontainers.service.connection.DatabaseConnectionDetails; import org.springframework.boot.testsupport.container.DisabledIfDockerUnavailable; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.weaving.LoadTimeWeaverAware; import org.springframework.instrument.classloading.LoadTimeWeaver; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import static org.assertj.core.api.Assertions.assertThat; @@ -46,11 +48,18 @@ void loadTimeWeaverAwareBeanCanUseJdbcUrlFromContainerBasedConnectionDetails() { } @Configuration - @ImportAutoConfiguration(DataSourceAutoConfiguration.class) static class TestConfiguration { @Bean - LoadTimeWeaverAwareConsumer loadTimeWeaverAwareConsumer(JdbcConnectionDetails connectionDetails) { + DataSource dataSource() { + EmbeddedDatabaseFactory embeddedDatabaseFactory = new EmbeddedDatabaseFactory(); + embeddedDatabaseFactory.setGenerateUniqueDatabaseName(true); + embeddedDatabaseFactory.setDatabaseType(EmbeddedDatabaseType.H2); + return embeddedDatabaseFactory.getDatabase(); + } + + @Bean + LoadTimeWeaverAwareConsumer loadTimeWeaverAwareConsumer(DatabaseConnectionDetails connectionDetails) { return new LoadTimeWeaverAwareConsumer(connectionDetails); } @@ -60,7 +69,7 @@ static class LoadTimeWeaverAwareConsumer implements LoadTimeWeaverAware { private final String jdbcUrl; - LoadTimeWeaverAwareConsumer(JdbcConnectionDetails connectionDetails) { + LoadTimeWeaverAwareConsumer(DatabaseConnectionDetails connectionDetails) { this.jdbcUrl = connectionDetails.getJdbcUrl(); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfigurationTests.java index 03f6159cd3e9..04eae9e0ed1d 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfigurationTests.java @@ -16,9 +16,6 @@ package org.springframework.boot.testcontainers.properties; -import java.util.ArrayList; -import java.util.List; - import com.redis.testcontainers.RedisContainer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -32,7 +29,6 @@ import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; -import org.springframework.context.ApplicationEvent; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -55,59 +51,6 @@ class TestcontainersPropertySourceAutoConfigurationTests { .withInitializer(new TestcontainersLifecycleApplicationContextInitializer()) .withConfiguration(AutoConfigurations.of(TestcontainersPropertySourceAutoConfiguration.class)); - @Test - @SuppressWarnings("removal") - @Deprecated(since = "3.4.0", forRemoval = true) - void registeringADynamicPropertyFailsByDefault() { - this.contextRunner.withUserConfiguration(ContainerAndPropertiesConfiguration.class) - .run((context) -> assertThat(context).getFailure() - .rootCause() - .isInstanceOf( - org.springframework.boot.testcontainers.properties.TestcontainersPropertySource.DynamicPropertyRegistryInjectionException.class) - .hasMessageStartingWith( - "Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated")); - } - - @Test - @SuppressWarnings("removal") - @Deprecated(since = "3.4.0", forRemoval = true) - void registeringADynamicPropertyCanLogAWarningAndContributeProperty(CapturedOutput output) { - List events = new ArrayList<>(); - this.contextRunner.withPropertyValues("spring.testcontainers.dynamic-property-registry-injection=warn") - .withUserConfiguration(ContainerAndPropertiesConfiguration.class) - .withInitializer((context) -> context.addApplicationListener(events::add)) - .run((context) -> { - TestBean testBean = context.getBean(TestBean.class); - RedisContainer redisContainer = context.getBean(RedisContainer.class); - assertThat(testBean.getUsingPort()).isEqualTo(redisContainer.getFirstMappedPort()); - assertThat(events.stream() - .filter(org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent.class::isInstance)) - .hasSize(1); - assertThat(output) - .contains("Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated"); - }); - } - - @Test - @SuppressWarnings("removal") - @Deprecated(since = "3.4.0", forRemoval = true) - void registeringADynamicPropertyCanBePermittedAndContributeProperty(CapturedOutput output) { - List events = new ArrayList<>(); - this.contextRunner.withPropertyValues("spring.testcontainers.dynamic-property-registry-injection=allow") - .withUserConfiguration(ContainerAndPropertiesConfiguration.class) - .withInitializer((context) -> context.addApplicationListener(events::add)) - .run((context) -> { - TestBean testBean = context.getBean(TestBean.class); - RedisContainer redisContainer = context.getBean(RedisContainer.class); - assertThat(testBean.getUsingPort()).isEqualTo(redisContainer.getFirstMappedPort()); - assertThat(events.stream() - .filter(org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent.class::isInstance)) - .hasSize(1); - assertThat(output) - .doesNotContain("Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated"); - }); - } - @Test void dynamicPropertyRegistrarBeanContributesProperties(CapturedOutput output) { this.contextRunner.withUserConfiguration(ContainerAndPropertyRegistrarConfiguration.class).run((context) -> { diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegrationTest.java b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegrationTest.java index d1bd754c2d6e..bdc862829bee 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegrationTest.java +++ b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegrationTest.java @@ -27,7 +27,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.test.context.DynamicPropertyRegistrar; -import org.springframework.test.context.DynamicPropertyRegistry; import static org.assertj.core.api.Assertions.assertThat; @@ -45,11 +44,6 @@ class TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegration @Autowired private Environment environment; - @Test - void injectsRegistryIntoBeanMethod() { - assertThat(this.environment.getProperty("from.bean.method")).isEqualTo("one"); - } - @Test void callsRegistrars() { assertThat(this.environment.getProperty("from.registrar")).isEqualTo("two"); @@ -60,12 +54,6 @@ void callsRegistrars() { @SpringBootConfiguration static class TestConfig { - @Bean - String example(DynamicPropertyRegistry registry) { - registry.add("from.bean.method", () -> "one"); - return "Hello"; - } - @Bean DynamicPropertyRegistrar propertyRegistrar() { return (registry) -> registry.add("from.registrar", () -> "two"); diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationTests.java b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationTests.java index 47e00613d647..4a5214772ad7 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationTests.java @@ -18,20 +18,19 @@ import java.util.Set; -import com.redis.testcontainers.RedisContainer; +import javax.sql.DataSource; + import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import org.testcontainers.containers.PostgreSQLContainer; import org.springframework.aot.test.generate.TestGenerationContext; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails; import org.springframework.boot.testcontainers.beans.TestcontainerBeanDefinition; import org.springframework.boot.testcontainers.lifecycle.TestcontainersLifecycleApplicationContextInitializer; -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.container.DisabledIfDockerUnavailable; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -43,6 +42,8 @@ import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.type.AnnotationMetadata; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNoException; @@ -57,8 +58,7 @@ @DisabledIfDockerUnavailable class ServiceConnectionAutoConfigurationTests { - private static final String REDIS_CONTAINER_CONNECTION_DETAILS = "org.springframework.boot.testcontainers.service.connection.redis." - + "RedisContainerConnectionDetailsFactory$RedisContainerConnectionDetails"; + private static final String DATABASE_CONTAINER_CONNECTION_DETAILS = TestDatabaseConnectionDetails.class.getName(); @Test void whenNoExistingBeansRegistersServiceConnection() { @@ -66,31 +66,30 @@ void whenNoExistingBeansRegistersServiceConnection() { applicationContext.register(WithNoExtraAutoConfiguration.class, ContainerConfiguration.class); new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext); applicationContext.refresh(); - RedisConnectionDetails connectionDetails = applicationContext.getBean(RedisConnectionDetails.class); - assertThat(connectionDetails.getClass().getName()).isEqualTo(REDIS_CONTAINER_CONNECTION_DETAILS); + DatabaseConnectionDetails connectionDetails = applicationContext.getBean(DatabaseConnectionDetails.class); + assertThat(connectionDetails.getClass().getName()).isEqualTo(DATABASE_CONTAINER_CONNECTION_DETAILS); } } @Test void whenHasExistingAutoConfigurationRegistersReplacement() { try (AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext()) { - applicationContext.register(WithRedisAutoConfiguration.class, ContainerConfiguration.class); + applicationContext.register(WithDatasourceConfiguration.class, ContainerConfiguration.class); new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext); applicationContext.refresh(); - RedisConnectionDetails connectionDetails = applicationContext.getBean(RedisConnectionDetails.class); - assertThat(connectionDetails.getClass().getName()).isEqualTo(REDIS_CONTAINER_CONNECTION_DETAILS); + DatabaseConnectionDetails connectionDetails = applicationContext.getBean(DatabaseConnectionDetails.class); + assertThat(connectionDetails.getClass().getName()).isEqualTo(DATABASE_CONTAINER_CONNECTION_DETAILS); } } @Test - @ClassPathExclusions("lettuce-core-*.jar") void whenHasUserConfigurationDoesNotRegisterReplacement() { try (AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext()) { - applicationContext.register(UserConfiguration.class, WithRedisAutoConfiguration.class, + applicationContext.register(UserConfiguration.class, WithDatasourceConfiguration.class, ContainerConfiguration.class); new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext); applicationContext.refresh(); - RedisConnectionDetails connectionDetails = applicationContext.getBean(RedisConnectionDetails.class); + DatabaseConnectionDetails connectionDetails = applicationContext.getBean(DatabaseConnectionDetails.class); assertThat(Mockito.mockingDetails(connectionDetails).isMock()).isTrue(); } } @@ -102,8 +101,8 @@ void whenHasTestcontainersBeanDefinition() { TestcontainerBeanDefinitionConfiguration.class); new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext); applicationContext.refresh(); - RedisConnectionDetails connectionDetails = applicationContext.getBean(RedisConnectionDetails.class); - assertThat(connectionDetails.getClass().getName()).isEqualTo(REDIS_CONTAINER_CONNECTION_DETAILS); + DatabaseConnectionDetails connectionDetails = applicationContext.getBean(DatabaseConnectionDetails.class); + assertThat(connectionDetails.getClass().getName()).isEqualTo(DATABASE_CONTAINER_CONNECTION_DETAILS); } } @@ -125,8 +124,16 @@ static class WithNoExtraAutoConfiguration { } @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ ServiceConnectionAutoConfiguration.class, RedisAutoConfiguration.class }) - static class WithRedisAutoConfiguration { + @ImportAutoConfiguration(ServiceConnectionAutoConfiguration.class) + static class WithDatasourceConfiguration { + + @Bean + DataSource dataSource() { + EmbeddedDatabaseFactory embeddedDatabaseFactory = new EmbeddedDatabaseFactory(); + embeddedDatabaseFactory.setGenerateUniqueDatabaseName(true); + embeddedDatabaseFactory.setDatabaseType(EmbeddedDatabaseType.H2); + return embeddedDatabaseFactory.getDatabase(); + } } @@ -135,8 +142,8 @@ static class ContainerConfiguration { @Bean @ServiceConnection - RedisContainer redisContainer() { - return TestImage.container(RedisContainer.class); + PostgreSQLContainer postgresContainer() { + return TestImage.container(PostgreSQLContainer.class); } } @@ -145,8 +152,8 @@ RedisContainer redisContainer() { static class UserConfiguration { @Bean - RedisConnectionDetails redisConnectionDetails() { - return mock(RedisConnectionDetails.class); + DatabaseConnectionDetails databaseConnectionDetails() { + return mock(DatabaseConnectionDetails.class); } } @@ -162,17 +169,17 @@ static class TestcontainerBeanDefinitionRegistrar implements ImportBeanDefinitio @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) { - registry.registerBeanDefinition("redisContainer", new TestcontainersRootBeanDefinition()); + registry.registerBeanDefinition("postgresContainer", new TestcontainersRootBeanDefinition()); } } static class TestcontainersRootBeanDefinition extends RootBeanDefinition implements TestcontainerBeanDefinition { - private final RedisContainer container = TestImage.container(RedisContainer.class); + private final PostgreSQLContainer container = TestImage.container(PostgreSQLContainer.class); TestcontainersRootBeanDefinition() { - setBeanClass(RedisContainer.class); + setBeanClass(PostgreSQLContainer.class); setInstanceSupplier(() -> this.container); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionStartsConnectionOnceIntegrationTests.java b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionStartsConnectionOnceIntegrationTests.java index 47dd51ae0324..12feddd4a678 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionStartsConnectionOnceIntegrationTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionStartsConnectionOnceIntegrationTests.java @@ -18,16 +18,19 @@ import java.util.concurrent.atomic.AtomicInteger; +import javax.sql.DataSource; + import org.junit.jupiter.api.Test; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import static org.assertj.core.api.Assertions.assertThat; @@ -52,9 +55,16 @@ void startedOnlyOnce() { } @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration(DataSourceAutoConfiguration.class) static class TestConfiguration { + @Bean + DataSource dataSource() { + EmbeddedDatabaseFactory embeddedDatabaseFactory = new EmbeddedDatabaseFactory(); + embeddedDatabaseFactory.setGenerateUniqueDatabaseName(true); + embeddedDatabaseFactory.setDatabaseType(EmbeddedDatabaseType.H2); + return embeddedDatabaseFactory.getDatabase(); + } + } static class StartCountingPostgreSQLContainer extends PostgreSQLContainer { diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactoryTests.java deleted file mode 100644 index 06f1e03e976d..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactoryTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.testcontainers.service.connection.cassandra; - -import com.datastax.oss.driver.api.core.CqlSession; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.CassandraContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link DeprecatedCassandraContainerConnectionDetailsFactory}. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SpringJUnitConfig -@Testcontainers(disabledWithoutDocker = true) -@Deprecated(since = "3.4.0", forRemoval = true) -class DeprecatedCassandraContainerConnectionDetailsFactoryTests { - - @Container - @ServiceConnection - static final CassandraContainer cassandra = TestImage.container(CassandraContainer.class); - - @Autowired(required = false) - private CassandraConnectionDetails connectionDetails; - - @Autowired - private CqlSession cqlSession; - - @Test - void connectionCanBeMadeToCassandraContainer() { - assertThat(this.connectionDetails).isNotNull(); - assertThat(this.cqlSession.getMetadata().getNodes()).hasSize(1); - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration(CassandraAutoConfiguration.class) - static class TestConfiguration { - - } - -} diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java deleted file mode 100644 index 643dfb4306b7..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.testcontainers.service.connection.kafka; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import org.awaitility.Awaitility; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.KafkaContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.boot.testsupport.container.TestImage; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.kafka.annotation.KafkaListener; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link DeprecatedConfluentKafkaContainerConnectionDetailsFactory}. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SpringJUnitConfig -@Testcontainers(disabledWithoutDocker = true) -@TestPropertySource(properties = { "spring.kafka.consumer.group-id=test-group", - "spring.kafka.consumer.auto-offset-reset=earliest" }) -@Deprecated(since = "3.4.0", forRemoval = true) -class DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests { - - @Container - @ServiceConnection - static final KafkaContainer kafka = TestImage.container(KafkaContainer.class); - - @Autowired - private KafkaTemplate kafkaTemplate; - - @Autowired - private TestListener listener; - - @Test - void connectionCanBeMadeToKafkaContainer() { - this.kafkaTemplate.send("test-topic", "test-data"); - Awaitility.waitAtMost(Duration.ofMinutes(4)) - .untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data")); - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration(KafkaAutoConfiguration.class) - static class TestConfiguration { - - @Bean - TestListener testListener() { - return new TestListener(); - } - - } - - static class TestListener { - - private final List messages = new ArrayList<>(); - - @KafkaListener(topics = "test-topic") - void processMessage(String message) { - this.messages.add(message); - } - - } - -} diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/BeforeTestcontainerUsedEvent.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/BeforeTestcontainerUsedEvent.java deleted file mode 100644 index ca765cf917c0..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/BeforeTestcontainerUsedEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.testcontainers.lifecycle; - -import org.testcontainers.containers.Container; - -import org.springframework.context.ApplicationEvent; -import org.springframework.test.context.DynamicPropertyRegistrar; - -/** - * Event published just before a Testcontainers {@link Container} is used. - * - * @author Andy Wilkinson - * @since 3.2.6 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of property registration using a - * {@link DynamicPropertyRegistrar} bean that injects the {@link Container} from which the - * properties will be sourced. - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public class BeforeTestcontainerUsedEvent extends ApplicationEvent { - - public BeforeTestcontainerUsedEvent(Object source) { - super(source); - } - -} diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleApplicationContextInitializer.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleApplicationContextInitializer.java index 806e3178a851..e6d21c0c5eee 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleApplicationContextInitializer.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleApplicationContextInitializer.java @@ -51,7 +51,6 @@ public void initialize(ConfigurableApplicationContext applicationContext) { TestcontainersLifecycleBeanPostProcessor beanPostProcessor = new TestcontainersLifecycleBeanPostProcessor( beanFactory, startup); beanFactory.addBeanPostProcessor(beanPostProcessor); - applicationContext.addApplicationListener(beanPostProcessor); } } diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleBeanPostProcessor.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleBeanPostProcessor.java index 05d536dda4c4..4f067dd8db9a 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleBeanPostProcessor.java @@ -39,7 +39,6 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor; -import org.springframework.context.ApplicationListener; import org.springframework.context.aot.AbstractAotProcessor; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; @@ -59,10 +58,8 @@ * @author Scott Frederick * @see TestcontainersLifecycleApplicationContextInitializer */ -@SuppressWarnings({ "removal", "deprecation" }) @Order(Ordered.LOWEST_PRECEDENCE) -class TestcontainersLifecycleBeanPostProcessor - implements DestructionAwareBeanPostProcessor, ApplicationListener { +class TestcontainersLifecycleBeanPostProcessor implements DestructionAwareBeanPostProcessor { private static final Log logger = LogFactory.getLog(TestcontainersLifecycleBeanPostProcessor.class); @@ -80,12 +77,6 @@ class TestcontainersLifecycleBeanPostProcessor this.startup = startup; } - @Override - @Deprecated(since = "3.4.0", forRemoval = true) - public void onApplicationEvent(BeforeTestcontainerUsedEvent event) { - initializeContainers(); - } - @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (this.beanFactory.isConfigurationFrozen() && !isAotProcessingInProgress()) { diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySource.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySource.java deleted file mode 100644 index 81d7a3de5dc4..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySource.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.testcontainers.properties; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.function.Supplier; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.testcontainers.containers.Container; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.context.properties.bind.BindResult; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.PropertySource; -import org.springframework.test.context.DynamicPropertyRegistrar; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.util.Assert; -import org.springframework.util.function.SupplierUtils; - -/** - * {@link EnumerablePropertySource} backed by a map with values supplied from one or more - * {@link Container testcontainers}. - * - * @author Phillip Webb - * @since 3.1.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of declaring one or more - * {@link DynamicPropertyRegistrar} beans. - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -public class TestcontainersPropertySource extends MapPropertySource { - - private static final Log logger = LogFactory.getLog(TestcontainersPropertySource.class); - - static final String NAME = "testcontainersPropertySource"; - - private final DynamicPropertyRegistry registry; - - private final Set eventPublishers = new CopyOnWriteArraySet<>(); - - TestcontainersPropertySource(DynamicPropertyRegistryInjection registryInjection) { - this(Collections.synchronizedMap(new LinkedHashMap<>()), registryInjection); - } - - private TestcontainersPropertySource(Map> valueSuppliers, - DynamicPropertyRegistryInjection registryInjection) { - super(NAME, Collections.unmodifiableMap(valueSuppliers)); - this.registry = (name, valueSupplier) -> { - Assert.hasText(name, "'name' must not be empty"); - DynamicPropertyRegistryInjectionException.throwIfNecessary(name, registryInjection); - Assert.notNull(valueSupplier, "'valueSupplier' must not be null"); - valueSuppliers.put(name, valueSupplier); - }; - } - - private void addEventPublisher(ApplicationEventPublisher eventPublisher) { - this.eventPublishers.add(eventPublisher); - } - - @Override - public Object getProperty(String name) { - Object valueSupplier = this.source.get(name); - return (valueSupplier != null) ? getProperty(name, valueSupplier) : null; - } - - private Object getProperty(String name, Object valueSupplier) { - BeforeTestcontainerUsedEvent event = new BeforeTestcontainerUsedEvent(this); - this.eventPublishers.forEach((eventPublisher) -> eventPublisher.publishEvent(event)); - return SupplierUtils.resolve(valueSupplier); - } - - public static DynamicPropertyRegistry attach(Environment environment) { - return attach(environment, null); - } - - static DynamicPropertyRegistry attach(ConfigurableApplicationContext applicationContext) { - return attach(applicationContext.getEnvironment(), applicationContext, null); - } - - public static DynamicPropertyRegistry attach(Environment environment, BeanDefinitionRegistry registry) { - return attach(environment, null, registry); - } - - private static DynamicPropertyRegistry attach(Environment environment, ApplicationEventPublisher eventPublisher, - BeanDefinitionRegistry registry) { - Assert.state(environment instanceof ConfigurableEnvironment, - "TestcontainersPropertySource can only be attached to a ConfigurableEnvironment"); - TestcontainersPropertySource propertySource = getOrAdd((ConfigurableEnvironment) environment); - if (eventPublisher != null) { - propertySource.addEventPublisher(eventPublisher); - } - else if (registry != null && !registry.containsBeanDefinition(EventPublisherRegistrar.NAME)) { - registry.registerBeanDefinition(EventPublisherRegistrar.NAME, new RootBeanDefinition( - EventPublisherRegistrar.class, () -> new EventPublisherRegistrar(environment))); - } - return propertySource.registry; - } - - static TestcontainersPropertySource getOrAdd(ConfigurableEnvironment environment) { - PropertySource propertySource = environment.getPropertySources().get(NAME); - if (propertySource == null) { - BindResult bindingResult = Binder.get(environment) - .bind("spring.testcontainers.dynamic-property-registry-injection", - DynamicPropertyRegistryInjection.class); - environment.getPropertySources() - .addFirst( - new TestcontainersPropertySource(bindingResult.orElse(DynamicPropertyRegistryInjection.FAIL))); - return getOrAdd(environment); - } - Assert.state(propertySource instanceof TestcontainersPropertySource, - "Incorrect TestcontainersPropertySource type registered"); - return ((TestcontainersPropertySource) propertySource); - } - - /** - * {@link BeanFactoryPostProcessor} to register the {@link ApplicationEventPublisher} - * to the {@link TestcontainersPropertySource}. This class is a - * {@link BeanFactoryPostProcessor} so that it is initialized as early as possible. - */ - static class EventPublisherRegistrar implements BeanFactoryPostProcessor, ApplicationEventPublisherAware { - - static final String NAME = EventPublisherRegistrar.class.getName(); - - private final Environment environment; - - private ApplicationEventPublisher eventPublisher; - - EventPublisherRegistrar(Environment environment) { - this.environment = environment; - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { - this.eventPublisher = eventPublisher; - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - if (this.eventPublisher != null) { - TestcontainersPropertySource.getOrAdd((ConfigurableEnvironment) this.environment) - .addEventPublisher(this.eventPublisher); - } - } - - } - - private enum DynamicPropertyRegistryInjection { - - ALLOW, - - FAIL, - - WARN - - } - - static final class DynamicPropertyRegistryInjectionException extends RuntimeException { - - private DynamicPropertyRegistryInjectionException(String propertyName) { - super("Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated. Register '" - + propertyName + "' using a DynamicPropertyRegistrar bean instead. Alternatively, set " - + "spring.testcontainers.dynamic-property-registry-injection to 'warn' to replace this " - + "failure with a warning or to 'allow' to permit injection of the registry."); - } - - private static void throwIfNecessary(String propertyName, DynamicPropertyRegistryInjection registryInjection) { - switch (registryInjection) { - case FAIL -> throw new DynamicPropertyRegistryInjectionException(propertyName); - case WARN -> logger - .warn("Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated. Register '" - + propertyName + "' using a DynamicPropertyRegistrar bean instead."); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfiguration.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfiguration.java index 89eda23fb2ee..9485742eb7b1 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfiguration.java @@ -22,7 +22,6 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Role; import org.springframework.core.Ordered; @@ -44,13 +43,6 @@ @ConditionalOnClass(DynamicPropertyRegistry.class) public class TestcontainersPropertySourceAutoConfiguration { - @Bean - @SuppressWarnings("removal") - @Deprecated(since = "3.4.0", forRemoval = true) - static DynamicPropertyRegistry dynamicPropertyRegistry(ConfigurableApplicationContext applicationContext) { - return TestcontainersPropertySource.attach(applicationContext); - } - @Bean @ConditionalOnMissingBean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/package-info.java deleted file mode 100644 index 6f70d8259332..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/activemq/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers ActiveMQ service connections. - */ -package org.springframework.boot.testcontainers.service.connection.activemq; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/amqp/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/amqp/package-info.java deleted file mode 100644 index 12019d126ac8..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/amqp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers RabbitMQ service connections. - */ -package org.springframework.boot.testcontainers.service.connection.amqp; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactory.java deleted file mode 100644 index 937a59fc72d4..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactory.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.testcontainers.service.connection.cassandra; - -import java.net.InetSocketAddress; -import java.util.List; - -import org.testcontainers.containers.CassandraContainer; - -import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; -import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; - -/** - * {@link ContainerConnectionDetailsFactory} to create {@link CassandraConnectionDetails} - * from a {@link ServiceConnection @ServiceConnection}-annotated - * {@link CassandraContainer}. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link CassandraContainerConnectionDetailsFactory}. - */ -@Deprecated(since = "3.4.0", forRemoval = true) -class DeprecatedCassandraContainerConnectionDetailsFactory - extends ContainerConnectionDetailsFactory, CassandraConnectionDetails> { - - @Override - protected CassandraConnectionDetails getContainerConnectionDetails( - ContainerConnectionSource> source) { - return new CassandraContainerConnectionDetails(source); - } - - /** - * {@link CassandraConnectionDetails} backed by a {@link ContainerConnectionSource}. - */ - private static final class CassandraContainerConnectionDetails - extends ContainerConnectionDetails> implements CassandraConnectionDetails { - - private CassandraContainerConnectionDetails(ContainerConnectionSource> source) { - super(source); - } - - @Override - public List getContactPoints() { - InetSocketAddress contactPoint = getContainer().getContactPoint(); - return List.of(new Node(contactPoint.getHostString(), contactPoint.getPort())); - } - - @Override - public String getUsername() { - return getContainer().getUsername(); - } - - @Override - public String getPassword() { - return getContainer().getPassword(); - } - - @Override - public String getLocalDatacenter() { - return getContainer().getLocalDatacenter(); - } - - @Override - public SslBundle getSslBundle() { - return super.getSslBundle(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/package-info.java deleted file mode 100644 index 672aace4c27e..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Cassandra service connections. - */ -package org.springframework.boot.testcontainers.service.connection.cassandra; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/couchbase/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/couchbase/package-info.java deleted file mode 100644 index a13c2f5e6e72..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/couchbase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Couchbase service connections. - */ -package org.springframework.boot.testcontainers.service.connection.couchbase; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/package-info.java deleted file mode 100644 index a66d60b57a8c..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/elasticsearch/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Elasticsearch service connections. - */ -package org.springframework.boot.testcontainers.service.connection.elasticsearch; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/flyway/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/flyway/package-info.java deleted file mode 100644 index 367c69627c3d..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/flyway/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Flyway service connections. - */ -package org.springframework.boot.testcontainers.service.connection.flyway; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/hazelcast/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/hazelcast/package-info.java deleted file mode 100644 index 02966c79b8d5..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/hazelcast/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Hazelcast service connections. - */ -package org.springframework.boot.testcontainers.service.connection.hazelcast; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/jdbc/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/jdbc/package-info.java deleted file mode 100644 index cd1bc4fdb4f9..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/jdbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers JDBC service connections. - */ -package org.springframework.boot.testcontainers.service.connection.jdbc; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactory.java deleted file mode 100644 index bbcfbf50ee0d..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactory.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.testcontainers.service.connection.kafka; - -import java.util.List; - -import org.testcontainers.containers.KafkaContainer; - -import org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; -import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; - -/** - * {@link ContainerConnectionDetailsFactory} to create {@link KafkaConnectionDetails} from - * a {@link ServiceConnection @ServiceConnection}-annotated {@link KafkaContainer}. - * - * @author Moritz Halbritter - * @author Andy Wilkinson - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link ConfluentKafkaContainerConnectionDetailsFactory}. - */ -@Deprecated(since = "3.4.0", forRemoval = true) -class DeprecatedConfluentKafkaContainerConnectionDetailsFactory - extends ContainerConnectionDetailsFactory { - - @Override - protected KafkaConnectionDetails getContainerConnectionDetails(ContainerConnectionSource source) { - return new ConfluentKafkaContainerConnectionDetails(source); - } - - /** - * {@link KafkaConnectionDetails} backed by a {@link ContainerConnectionSource}. - */ - private static final class ConfluentKafkaContainerConnectionDetails - extends ContainerConnectionDetails implements KafkaConnectionDetails { - - private ConfluentKafkaContainerConnectionDetails(ContainerConnectionSource source) { - super(source); - } - - @Override - public List getBootstrapServers() { - return List.of(getContainer().getBootstrapServers()); - } - - @Override - public SslBundle getSslBundle() { - return super.getSslBundle(); - } - - @Override - public String getSecurityProtocol() { - return (getSslBundle() != null) ? "SSL" : "PLAINTEXT"; - } - - } - -} diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/package-info.java deleted file mode 100644 index 31046b8093f9..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Kafka service connections. - */ -package org.springframework.boot.testcontainers.service.connection.kafka; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/package-info.java deleted file mode 100644 index 9bd69ed41653..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ldap/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Ldap service connections. - */ -package org.springframework.boot.testcontainers.service.connection.ldap; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/liquibase/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/liquibase/package-info.java deleted file mode 100644 index 8fb3cf62158b..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/liquibase/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Liquibase service connections. - */ -package org.springframework.boot.testcontainers.service.connection.liquibase; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/mongo/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/mongo/package-info.java deleted file mode 100644 index 6aa97c5705cb..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/mongo/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers MongoDB service connections. - */ -package org.springframework.boot.testcontainers.service.connection.mongo; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/neo4j/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/neo4j/package-info.java deleted file mode 100644 index 123bef23f12d..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/neo4j/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Neo4J service connections. - */ -package org.springframework.boot.testcontainers.service.connection.neo4j; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/package-info.java deleted file mode 100644 index 1f4b07b40de7..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers OpenTelemetry service connections. - */ -package org.springframework.boot.testcontainers.service.connection.otlp; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/pulsar/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/pulsar/package-info.java deleted file mode 100644 index b71538137c39..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/pulsar/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Pulsar service connections. - */ -package org.springframework.boot.testcontainers.service.connection.pulsar; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/package-info.java deleted file mode 100644 index 1860c21feab6..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/r2dbc/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers R2DBC service connections. - */ -package org.springframework.boot.testcontainers.service.connection.r2dbc; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redis/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redis/package-info.java deleted file mode 100644 index dfab94bd2665..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redis/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Redis service connections. - */ -package org.springframework.boot.testcontainers.service.connection.redis; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redpanda/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redpanda/package-info.java deleted file mode 100644 index 2f9139a237f5..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/redpanda/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Redpanda service connections. - */ -package org.springframework.boot.testcontainers.service.connection.redpanda; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/zipkin/package-info.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/zipkin/package-info.java deleted file mode 100644 index b42fda572e79..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/zipkin/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for testcontainers Zipkin service connections. - */ -package org.springframework.boot.testcontainers.service.connection.zipkin; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories index 20a62beb5fbe..965d32bf8b61 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories @@ -6,41 +6,3 @@ org.springframework.boot.testcontainers.lifecycle.TestcontainersLifecycleApplica org.springframework.test.context.ContextCustomizerFactory=\ org.springframework.boot.testcontainers.service.connection.ServiceConnectionContextCustomizerFactory -# Connection Details Factories -org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ -org.springframework.boot.testcontainers.service.connection.activemq.ActiveMQClassicContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.activemq.ActiveMQContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.activemq.ArtemisContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.amqp.RabbitContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.cassandra.CassandraContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.cassandra.DeprecatedCassandraContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.couchbase.CouchbaseContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.elasticsearch.ElasticsearchContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.flyway.FlywayContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.hazelcast.HazelcastContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.jdbc.JdbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.kafka.ApacheKafkaContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.kafka.ConfluentKafkaContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.kafka.DeprecatedConfluentKafkaContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.ldap.LLdapContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.ldap.OpenLdapContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.liquibase.LiquibaseContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.mongo.MongoContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.neo4j.Neo4jContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.otlp.GrafanaOpenTelemetryLoggingContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.otlp.GrafanaOpenTelemetryMetricsContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.otlp.GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.otlp.OpenTelemetryLoggingContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.otlp.OpenTelemetryMetricsContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.otlp.OpenTelemetryTracingContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.pulsar.PulsarContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.ClickHouseR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.MariaDbR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.MySqlR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.OracleFreeR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.OracleXeR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.PostgresR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.SqlServerR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.redis.RedisContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.redpanda.RedpandaContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.zipkin.ZipkinContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceTests.java deleted file mode 100644 index ebe274fa1186..000000000000 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceTests.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.testcontainers.properties; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.PropertySource; -import org.springframework.mock.env.MockEnvironment; -import org.springframework.test.context.DynamicPropertyRegistry; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * Tests for {@link TestcontainersPropertySource}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class TestcontainersPropertySourceTests { - - private MockEnvironment environment = new MockEnvironment() - .withProperty("spring.testcontainers.dynamic-property-registry-injection", "allow"); - - private GenericApplicationContext context = new GenericApplicationContext(); - - TestcontainersPropertySourceTests() { - ((DefaultListableBeanFactory) this.context.getBeanFactory()).setAllowBeanDefinitionOverriding(false); - this.context.setEnvironment(this.environment); - } - - @Test - void getPropertyWhenHasValueSupplierReturnsSuppliedValue() { - DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment); - registry.add("test", () -> "spring"); - assertThat(this.environment.getProperty("test")).isEqualTo("spring"); - } - - @Test - void getPropertyWhenHasNoValueSupplierReturnsNull() { - DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment); - registry.add("test", () -> "spring"); - assertThat(this.environment.getProperty("missing")).isNull(); - } - - @Test - void containsPropertyWhenHasPropertyReturnsTrue() { - DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment); - registry.add("test", () -> null); - assertThat(this.environment.containsProperty("test")).isTrue(); - } - - @Test - void containsPropertyWhenHasNoPropertyReturnsFalse() { - DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment); - registry.add("test", () -> null); - assertThat(this.environment.containsProperty("missing")).isFalse(); - } - - @Test - void getPropertyNamesReturnsNames() { - DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment); - registry.add("test", () -> null); - registry.add("other", () -> null); - EnumerablePropertySource propertySource = (EnumerablePropertySource) this.environment.getPropertySources() - .get(TestcontainersPropertySource.NAME); - assertThat(propertySource.getPropertyNames()).containsExactly("test", "other"); - } - - @Test - @SuppressWarnings("unchecked") - void getSourceReturnsImmutableSource() { - TestcontainersPropertySource.attach(this.environment); - PropertySource propertySource = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME); - Map map = (Map) propertySource.getSource(); - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(map::clear); - } - - @Test - void attachToEnvironmentWhenNotAttachedAttaches() { - TestcontainersPropertySource.attach(this.environment); - PropertySource propertySource = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME); - assertThat(propertySource).isNotNull(); - } - - @Test - void attachToEnvironmentWhenAlreadyAttachedReturnsExisting() { - DynamicPropertyRegistry r1 = TestcontainersPropertySource.attach(this.environment); - PropertySource p1 = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME); - DynamicPropertyRegistry r2 = TestcontainersPropertySource.attach(this.environment); - PropertySource p2 = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME); - assertThat(r1).isSameAs(r2); - assertThat(p1).isSameAs(p2); - } - - @Test - void attachToEnvironmentAndContextWhenNotAttachedAttaches() { - TestcontainersPropertySource.attach(this.environment, this.context); - PropertySource propertySource = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME); - assertThat(propertySource).isNotNull(); - assertThat(this.context.containsBean( - org.springframework.boot.testcontainers.properties.TestcontainersPropertySource.EventPublisherRegistrar.NAME)); - } - - @Test - void attachToEnvironmentAndContextWhenAlreadyAttachedReturnsExisting() { - DynamicPropertyRegistry r1 = TestcontainersPropertySource.attach(this.environment, this.context); - PropertySource p1 = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME); - DynamicPropertyRegistry r2 = TestcontainersPropertySource.attach(this.environment, this.context); - PropertySource p2 = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME); - assertThat(r1).isSameAs(r2); - assertThat(p1).isSameAs(p2); - } - - @Test - void getPropertyPublishesEvent() { - try (GenericApplicationContext applicationContext = new GenericApplicationContext()) { - ConfigurableEnvironment environment = applicationContext.getEnvironment(); - environment.getPropertySources() - .addLast(new MapPropertySource("test", - Map.of("spring.testcontainers.dynamic-property-registry-injection", "allow"))); - List events = new ArrayList<>(); - applicationContext.addApplicationListener(events::add); - DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(environment, - (BeanDefinitionRegistry) applicationContext.getBeanFactory()); - applicationContext.refresh(); - registry.add("test", () -> "spring"); - assertThat(environment.containsProperty("test")).isTrue(); - assertThat(events.isEmpty()); - assertThat(environment.getProperty("test")).isEqualTo("spring"); - assertThat(events.stream().filter(BeforeTestcontainerUsedEvent.class::isInstance)).hasSize(1); - } - } - -} diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryTests.java index 9ad0464d9eb7..60563ed3570f 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryTests.java @@ -22,15 +22,13 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.JdbcDatabaseContainer; import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.elasticsearch.ElasticsearchContainer; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory; import org.springframework.boot.origin.Origin; -import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryTests.TestContainerConnectionDetailsFactory.TestContainerConnectionDetails; import org.springframework.core.annotation.MergedAnnotation; import static org.assertj.core.api.Assertions.assertThat; @@ -106,11 +104,11 @@ void getConnectionDetailsWhenTypesMatchAndNameRestrictionsDoNotMatchReturnsNull( } @Test + @SuppressWarnings("resource") void getConnectionDetailsWhenContainerTypeDoesNotMatchReturnsNull() { - ElasticsearchContainer container = mock(ElasticsearchContainer.class); + GenericContainer container = mock(GenericContainer.class); ContainerConnectionSource source = new ContainerConnectionSource<>(this.beanNameSuffix, this.origin, - ElasticsearchContainer.class, container.getDockerImageName(), this.annotation, () -> container, null, - null); + GenericContainer.class, container.getDockerImageName(), this.annotation, () -> container, null, null); TestContainerConnectionDetailsFactory factory = new TestContainerConnectionDetailsFactory(); ConnectionDetails connectionDetails = getConnectionDetails(factory, source); assertThat(connectionDetails).isNull(); @@ -126,7 +124,7 @@ void getConnectionDetailsHasOrigin() { @Test void getContainerWhenNotInitializedThrowsException() { TestContainerConnectionDetailsFactory factory = new TestContainerConnectionDetailsFactory(); - TestContainerConnectionDetails connectionDetails = getConnectionDetails(factory, this.source); + TestDatabaseConnectionDetails connectionDetails = getConnectionDetails(factory, this.source); assertThatIllegalStateException().isThrownBy(connectionDetails::callGetContainer) .withMessage("Container cannot be obtained before the connection details bean has been initialized"); } @@ -134,7 +132,7 @@ void getContainerWhenNotInitializedThrowsException() { @Test void getContainerWhenInitializedReturnsSuppliedContainer() throws Exception { TestContainerConnectionDetailsFactory factory = new TestContainerConnectionDetailsFactory(); - TestContainerConnectionDetails connectionDetails = getConnectionDetails(factory, this.source); + TestDatabaseConnectionDetails connectionDetails = getConnectionDetails(factory, this.source); connectionDetails.afterPropertiesSet(); assertThat(connectionDetails.callGetContainer()).isSameAs(this.container); } @@ -152,16 +150,16 @@ void creatingFactoryWithNullNamesThrows() { } @SuppressWarnings({ "rawtypes", "unchecked" }) - private TestContainerConnectionDetails getConnectionDetails(ConnectionDetailsFactory factory, + private TestDatabaseConnectionDetails getConnectionDetails(ConnectionDetailsFactory factory, ContainerConnectionSource source) { - return (TestContainerConnectionDetails) ((ConnectionDetailsFactory) factory).getConnectionDetails(source); + return (TestDatabaseConnectionDetails) ((ConnectionDetailsFactory) factory).getConnectionDetails(source); } /** * Test {@link ContainerConnectionDetailsFactory}. */ static class TestContainerConnectionDetailsFactory - extends ContainerConnectionDetailsFactory, JdbcConnectionDetails> { + extends ContainerConnectionDetailsFactory, DatabaseConnectionDetails> { TestContainerConnectionDetailsFactory() { this(ANY_CONNECTION_NAME); @@ -176,37 +174,9 @@ static class TestContainerConnectionDetailsFactory } @Override - protected JdbcConnectionDetails getContainerConnectionDetails( + protected DatabaseConnectionDetails getContainerConnectionDetails( ContainerConnectionSource> source) { - return new TestContainerConnectionDetails(source); - } - - static final class TestContainerConnectionDetails extends ContainerConnectionDetails> - implements JdbcConnectionDetails { - - private TestContainerConnectionDetails(ContainerConnectionSource> source) { - super(source); - } - - @Override - public String getUsername() { - return "user"; - } - - @Override - public String getPassword() { - return "secret"; - } - - @Override - public String getJdbcUrl() { - return "jdbc:example"; - } - - JdbcDatabaseContainer callGetContainer() { - return super.getContainer(); - } - + return new TestDatabaseConnectionDetails(source); } } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionSourceTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionSourceTests.java index cc45215c05e9..cb02563e6e3d 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionSourceTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionSourceTests.java @@ -20,12 +20,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.testcontainers.containers.FutureContainer; import org.testcontainers.containers.JdbcDatabaseContainer; import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.elasticsearch.ElasticsearchContainer; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; +import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; import org.springframework.boot.origin.Origin; import org.springframework.core.annotation.MergedAnnotation; @@ -66,8 +65,8 @@ void setup() { @Test void acceptsWhenContainerIsNotInstanceOfRequiredContainerTypeReturnsFalse() { String requiredConnectionName = null; - Class requiredContainerType = ElasticsearchContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredContainerType = FutureContainer.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isFalse(); } @@ -76,7 +75,7 @@ void acceptsWhenContainerIsNotInstanceOfRequiredContainerTypeReturnsFalse() { void acceptsWhenContainerIsInstanceOfRequiredContainerTypeReturnsTrue() { String requiredConnectionName = null; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isTrue(); } @@ -86,7 +85,7 @@ void acceptsWhenRequiredConnectionNameDoesNotMatchNameTakenFromAnnotationReturns setupSourceAnnotatedWithName("myname"); String requiredConnectionName = "othername"; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isFalse(); } @@ -95,7 +94,7 @@ void acceptsWhenRequiredConnectionNameDoesNotMatchNameTakenFromAnnotationReturns void acceptsWhenRequiredConnectionNameDoesNotMatchNameTakenFromContainerReturnsFalse() { String requiredConnectionName = "othername"; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isFalse(); } @@ -104,7 +103,7 @@ void acceptsWhenRequiredConnectionNameDoesNotMatchNameTakenFromContainerReturnsF void acceptsWhenRequiredConnectionNameIsUnrestrictedReturnsTrue() { String requiredConnectionName = null; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isTrue(); } @@ -114,7 +113,7 @@ void acceptsWhenRequiredConnectionNameMatchesNameTakenFromAnnotationReturnsTrue( setupSourceAnnotatedWithName("myname"); String requiredConnectionName = "myname"; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isTrue(); } @@ -123,27 +122,27 @@ void acceptsWhenRequiredConnectionNameMatchesNameTakenFromAnnotationReturnsTrue( void acceptsWhenRequiredConnectionNameMatchesNameTakenFromContainerReturnsTrue() { String requiredConnectionName = "postgres"; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isTrue(); } @Test void acceptsWhenRequiredConnectionDetailsTypeNotInAnnotationRestrictionReturnsFalse() { - setupSourceAnnotatedWithType(ElasticsearchConnectionDetails.class); + setupSourceAnnotatedWithType(ExampleConnectionDetails.class); String requiredConnectionName = null; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isFalse(); } @Test void acceptsWhenRequiredConnectionDetailsTypeInAnnotationRestrictionReturnsTrue() { - setupSourceAnnotatedWithType(JdbcConnectionDetails.class); + setupSourceAnnotatedWithType(DatabaseConnectionDetails.class); String requiredConnectionName = null; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isTrue(); } @@ -152,7 +151,7 @@ void acceptsWhenRequiredConnectionDetailsTypeInAnnotationRestrictionReturnsTrue( void acceptsWhenRequiredConnectionDetailsTypeIsNotRestrictedReturnsTrue() { String requiredConnectionName = null; Class requiredContainerType = JdbcDatabaseContainer.class; - Class requiredConnectionDetailsType = JdbcConnectionDetails.class; + Class requiredConnectionDetailsType = DatabaseConnectionDetails.class; assertThat(this.source.accepts(requiredConnectionName, requiredContainerType, requiredConnectionDetailsType)) .isTrue(); } @@ -190,4 +189,8 @@ private void setupSourceAnnotatedWithType(Class type) { this.container.getDockerImageName(), this.annotation, () -> this.container, null, null); } + interface ExampleConnectionDetails extends ConnectionDetails { + + } + } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/DatabaseConnectionDetails.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/DatabaseConnectionDetails.java new file mode 100644 index 000000000000..60ba7aa0244c --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/DatabaseConnectionDetails.java @@ -0,0 +1,25 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.testcontainers.service.connection; + +import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; + +public interface DatabaseConnectionDetails extends ConnectionDetails { + + String getJdbcUrl(); + +} diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/DatabaseContainerDatabaseConnectionDetails.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/DatabaseContainerDatabaseConnectionDetails.java new file mode 100644 index 000000000000..51ebb2dd2e19 --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/DatabaseContainerDatabaseConnectionDetails.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.testcontainers.service.connection; + +import org.testcontainers.containers.JdbcDatabaseContainer; + +public class DatabaseContainerDatabaseConnectionDetails + extends ContainerConnectionDetailsFactory, DatabaseConnectionDetails> { + + @Override + protected DatabaseConnectionDetails getContainerConnectionDetails( + ContainerConnectionSource> source) { + return new TestDatabaseConnectionDetails(source); + } + +} diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionContextCustomizerTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionContextCustomizerTests.java index 1ff6696a329b..37c91d605c3b 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionContextCustomizerTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionContextCustomizerTests.java @@ -26,7 +26,6 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories; import org.springframework.boot.origin.Origin; import org.springframework.context.ConfigurableApplicationContext; @@ -78,15 +77,15 @@ void customizeContextRegistersServiceConnections() { DefaultListableBeanFactory beanFactory = spy(new DefaultListableBeanFactory()); given(context.getBeanFactory()).willReturn(beanFactory); MergedContextConfiguration mergedConfig = mock(MergedContextConfiguration.class); - JdbcConnectionDetails connectionDetails = new TestJdbcConnectionDetails(); + DatabaseConnectionDetails connectionDetails = new TestConnectionDetails(); given(this.factories.getConnectionDetails(this.source, true)) - .willReturn(Map.of(JdbcConnectionDetails.class, connectionDetails)); + .willReturn(Map.of(DatabaseConnectionDetails.class, connectionDetails)); customizer.customizeContext(context, mergedConfig); then(beanFactory).should() - .registerBeanDefinition(eq("testJdbcConnectionDetailsForTest"), + .registerBeanDefinition(eq("testConnectionDetailsForTest"), ArgumentMatchers.assertArg((beanDefinition) -> { assertThat(beanDefinition.getInstanceSupplier().get()).isSameAs(connectionDetails); - assertThat(beanDefinition.getBeanClass()).isEqualTo(TestJdbcConnectionDetails.class); + assertThat(beanDefinition.getBeanClass()).isEqualTo(TestConnectionDetails.class); })); } @@ -99,7 +98,7 @@ void equalsAndHashCode() { MergedAnnotation annotation2 = MergedAnnotation.of(ServiceConnection.class, Map.of("name", "", "type", new Class[0])); MergedAnnotation annotation3 = MergedAnnotation.of(ServiceConnection.class, - Map.of("name", "", "type", new Class[] { JdbcConnectionDetails.class })); + Map.of("name", "", "type", new Class[] { DatabaseConnectionDetails.class })); // Connection Names ServiceConnectionContextCustomizer n1 = new ServiceConnectionContextCustomizer( List.of(new ContainerConnectionSource<>("test", this.origin, PostgreSQLContainer.class, "name", @@ -138,20 +137,7 @@ void equalsAndHashCode() { assertThat(c1).isEqualTo(c2).isNotEqualTo(c3); } - /** - * Test {@link JdbcConnectionDetails}. - */ - static class TestJdbcConnectionDetails implements JdbcConnectionDetails { - - @Override - public String getUsername() { - return null; - } - - @Override - public String getPassword() { - return null; - } + static class TestConnectionDetails implements DatabaseConnectionDetails { @Override public String getJdbcUrl() { diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/TestDatabaseConnectionDetails.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/TestDatabaseConnectionDetails.java new file mode 100644 index 000000000000..24dbee711101 --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/TestDatabaseConnectionDetails.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.testcontainers.service.connection; + +import org.testcontainers.containers.JdbcDatabaseContainer; + +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory.ContainerConnectionDetails; + +class TestDatabaseConnectionDetails extends ContainerConnectionDetails> + implements DatabaseConnectionDetails { + + TestDatabaseConnectionDetails(ContainerConnectionSource> source) { + super(source); + } + + @Override + public String getJdbcUrl() { + return getContainer().getJdbcUrl(); + } + + JdbcDatabaseContainer callGetContainer() { + return super.getContainer(); + } + +} diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-testcontainers/src/test/resources/META-INF/spring.factories new file mode 100644 index 000000000000..63e1752eed27 --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/test/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Test Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.testcontainers.service.connection.DatabaseContainerDatabaseConnectionDetails diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryHints.java b/spring-boot-project/spring-boot-testcontainers/src/testFixtures/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryHints.java similarity index 100% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryHints.java rename to spring-boot-project/spring-boot-testcontainers/src/testFixtures/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryHints.java diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/TestContainerConnectionSource.java b/spring-boot-project/spring-boot-testcontainers/src/testFixtures/java/org/springframework/boot/testcontainers/service/connection/TestContainerConnectionSource.java similarity index 100% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/TestContainerConnectionSource.java rename to spring-boot-project/spring-boot-testcontainers/src/testFixtures/java/org/springframework/boot/testcontainers/service/connection/TestContainerConnectionSource.java diff --git a/spring-boot-project/spring-boot-thymeleaf/build.gradle b/spring-boot-project/spring-boot-thymeleaf/build.gradle new file mode 100644 index 000000000000..4b85e2dcc546 --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/build.gradle @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Thymeleaf" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.thymeleaf:thymeleaf-spring6") + api("org.springframework:spring-web") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-webflux")) + optional(project(":spring-boot-project:spring-boot-webmvc")) + optional("org.springframework.security:spring-security-web") + optional("org.thymeleaf:thymeleaf") + optional("org.thymeleaf.extras:thymeleaf-extras-springsecurity6") + optional("com.github.mxab.thymeleaf.extras:thymeleaf-extras-data-attribute") + optional("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect") + optional("jakarta.servlet:jakarta.servlet-api") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/TemplateEngineConfigurations.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/TemplateEngineConfigurations.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/TemplateEngineConfigurations.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/TemplateEngineConfigurations.java index 45753f5046e3..94de2ffc3f9e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/TemplateEngineConfigurations.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/TemplateEngineConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import org.thymeleaf.ITemplateEngine; import org.thymeleaf.dialect.IDialect; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafAutoConfiguration.java index 6959f8295b74..9a80751d9ac0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import java.util.LinkedHashMap; @@ -36,16 +36,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.template.TemplateLocation; -import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties.Reactive; import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.thymeleaf.autoconfigure.ThymeleafProperties.Reactive; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -69,9 +67,10 @@ * @author Daniel Fernández * @author Kazuki Shimizu * @author Artsiom Yudovin - * @since 1.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class }) +@AutoConfiguration(afterName = { "org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration", + "org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration" }) @EnableConfigurationProperties(ThymeleafProperties.class) @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class }) @Import({ TemplateEngineConfigurations.ReactiveTemplateEngineConfiguration.class, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafProperties.java index 80d1ed9f5b39..46481963d40c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -32,7 +32,7 @@ * @author Brian Clozel * @author Daniel Fernández * @author Kazuki Shimizu - * @since 1.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.thymeleaf") public class ThymeleafProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProvider.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProvider.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProvider.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProvider.java index da3164c74918..2ea849333843 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProvider.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; import org.springframework.core.env.Environment; @@ -27,7 +27,7 @@ * * @author Andy Wilkinson * @author Madhura Bhave - * @since 1.1.0 + * @since 4.0.0 */ public class ThymeleafTemplateAvailabilityProvider implements TemplateAvailabilityProvider { diff --git a/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/package-info.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/package-info.java new file mode 100644 index 000000000000..947b5e4b5b3f --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Thymeleaf. + */ +package org.springframework.boot.thymeleaf.autoconfigure; diff --git a/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..a252e02be272 --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,37 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.thymeleaf.prefix", + "defaultValue": "classpath:/templates/" + }, + { + "name": "spring.thymeleaf.reactive.media-types", + "defaultValue": [ + "text/html", + "application/xhtml+xml", + "application/xml", + "text/xml", + "application/rss+xml", + "application/atom+xml", + "application/javascript", + "application/ecmascript", + "text/javascript", + "text/ecmascript", + "application/json", + "text/css", + "text/plain", + "text/event-stream" + ] + }, + { + "name": "spring.thymeleaf.suffix", + "defaultValue": ".html" + } + ], + "hints": [], + "ignored": { + "properties": [ + ] + } +} diff --git a/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..a0365b1889d3 --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Template Availability Providers +org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ +org.springframework.boot.thymeleaf.autoconfigure.ThymeleafTemplateAvailabilityProvider diff --git a/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..e1faae4a813c --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafReactiveAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java rename to spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafReactiveAutoConfigurationTests.java index fef631c032a5..ea7307ee6f7a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafReactiveAutoConfigurationTests.java @@ -14,17 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; -import java.io.File; +import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collections; import java.util.Locale; import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect; import nz.net.ultraq.thymeleaf.layoutdialect.decorators.strategies.GroupingStrategy; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.context.WebContext; @@ -42,7 +46,6 @@ import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.testsupport.BuildOutput; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -61,12 +64,11 @@ * @author Brian Clozel * @author Kazuki Shimizu * @author Stephane Nicoll + * @author Moritz Halbritter */ @ExtendWith(OutputCaptureExtension.class) class ThymeleafReactiveAutoConfigurationTests { - private final BuildOutput buildOutput = new BuildOutput(getClass()); - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(ThymeleafAutoConfiguration.class)); @@ -88,26 +90,27 @@ void overrideCharacterEncoding() { assertThat(resolver).isInstanceOf(SpringResourceTemplateResolver.class); assertThat(((SpringResourceTemplateResolver) resolver).getCharacterEncoding()).isEqualTo("UTF-16"); ThymeleafReactiveViewResolver views = context.getBean(ThymeleafReactiveViewResolver.class); - assertThat(views.getDefaultCharset().name()).isEqualTo("UTF-16"); + Assertions.assertThat(views.getDefaultCharset().name()).isEqualTo("UTF-16"); }); } @Test void defaultMediaTypes() { - this.contextRunner - .run((context) -> assertThat(context.getBean(ThymeleafReactiveViewResolver.class).getSupportedMediaTypes()) - .containsExactly(MediaType.TEXT_HTML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_XML, - MediaType.TEXT_XML, MediaType.APPLICATION_RSS_XML, MediaType.APPLICATION_ATOM_XML, - new MediaType("application", "javascript"), new MediaType("application", "ecmascript"), - new MediaType("text", "javascript"), new MediaType("text", "ecmascript"), - MediaType.APPLICATION_JSON, new MediaType("text", "css"), MediaType.TEXT_PLAIN, - MediaType.TEXT_EVENT_STREAM)); + this.contextRunner.run((context) -> Assertions + .assertThat(context.getBean(ThymeleafReactiveViewResolver.class).getSupportedMediaTypes()) + .containsExactly(MediaType.TEXT_HTML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_XML, + MediaType.TEXT_XML, MediaType.APPLICATION_RSS_XML, MediaType.APPLICATION_ATOM_XML, + new MediaType("application", "javascript"), new MediaType("application", "ecmascript"), + new MediaType("text", "javascript"), new MediaType("text", "ecmascript"), + MediaType.APPLICATION_JSON, new MediaType("text", "css"), MediaType.TEXT_PLAIN, + MediaType.TEXT_EVENT_STREAM)); } @Test void overrideMediaTypes() { this.contextRunner.withPropertyValues("spring.thymeleaf.reactive.media-types:text/html,text/plain") - .run((context) -> assertThat(context.getBean(ThymeleafReactiveViewResolver.class).getSupportedMediaTypes()) + .run((context) -> Assertions + .assertThat(context.getBean(ThymeleafReactiveViewResolver.class).getSupportedMediaTypes()) .containsExactly(MediaType.TEXT_HTML, MediaType.TEXT_PLAIN)); } @@ -183,9 +186,10 @@ void templateLocationDoesNotExist(CapturedOutput output) { } @Test - void templateLocationEmpty(CapturedOutput output) { - new File(this.buildOutput.getTestResourcesLocation(), "empty-templates/empty-directory").mkdirs(); - this.contextRunner.withPropertyValues("spring.thymeleaf.prefix:classpath:/empty-templates/empty-directory/") + void templateLocationEmpty(CapturedOutput output, @TempDir Path tempDir) throws IOException { + Path directory = tempDir.resolve("empty-templates/empty-directory").toAbsolutePath(); + Files.createDirectories(directory); + this.contextRunner.withPropertyValues("spring.thymeleaf.prefix:file:" + directory) .run((context) -> assertThat(output).doesNotContain("Cannot find template location")); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafServletAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java rename to spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafServletAutoConfigurationTests.java index 0804982bd8df..7652afef7884 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafServletAutoConfigurationTests.java @@ -14,9 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; -import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collections; import java.util.EnumSet; import java.util.Locale; @@ -26,8 +28,10 @@ import jakarta.servlet.ServletContext; import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect; import nz.net.ultraq.thymeleaf.layoutdialect.decorators.strategies.GroupingStrategy; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.context.WebContext; @@ -40,15 +44,14 @@ import org.thymeleaf.web.servlet.JakartaServletWebApplication; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.servlet.filter.OrderedCharacterEncodingFilter; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.testsupport.BuildOutput; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mock.web.MockHttpServletRequest; @@ -74,12 +77,11 @@ * @author Brian Clozel * @author Kazuki Shimizu * @author Artsiom Yudovin + * @author Moritz Halbritter */ @ExtendWith(OutputCaptureExtension.class) class ThymeleafServletAutoConfigurationTests { - private final BuildOutput buildOutput = new BuildOutput(getClass()); - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(ThymeleafAutoConfiguration.class)); @@ -179,9 +181,10 @@ void templateLocationDoesNotExist(CapturedOutput output) { } @Test - void templateLocationEmpty(CapturedOutput output) { - new File(this.buildOutput.getTestResourcesLocation(), "empty-templates/empty-directory").mkdirs(); - this.contextRunner.withPropertyValues("spring.thymeleaf.prefix:classpath:/empty-templates/empty-directory/") + void templateLocationEmpty(CapturedOutput output, @TempDir Path tempDir) throws IOException { + Path directory = tempDir.resolve("empty-templates/empty-directory").toAbsolutePath(); + Files.createDirectories(directory); + this.contextRunner.withPropertyValues("spring.thymeleaf.prefix:file:" + directory) .run((context) -> assertThat(output).doesNotContain("Cannot find template location")); } @@ -354,7 +357,7 @@ void layoutDialectCanBeCustomized() { @Test void cachingCanBeDisabled() { this.contextRunner.withPropertyValues("spring.thymeleaf.cache:false").run((context) -> { - assertThat(context.getBean(ThymeleafViewResolver.class).isCache()).isFalse(); + Assertions.assertThat(context.getBean(ThymeleafViewResolver.class).isCache()).isFalse(); SpringResourceTemplateResolver templateResolver = context.getBean(SpringResourceTemplateResolver.class); assertThat(templateResolver.isCacheable()).isFalse(); }); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProviderTests.java b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProviderTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProviderTests.java rename to spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProviderTests.java index bbec845b2b95..b29335cae78d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProviderTests.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-tomcat/build.gradle b/spring-boot-project/spring-boot-tomcat/build.gradle new file mode 100644 index 000000000000..d1e36d1225f2 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/build.gradle @@ -0,0 +1,86 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Tomcat" + +def tomcatConfigProperties = layout.buildDirectory.dir("tomcat-config-properties") + +configurations { + tomcatDistribution +} + +dependencies { + api(project(":spring-boot-project:spring-boot-web-server")) + api("org.apache.tomcat.embed:tomcat-embed-core") { + exclude group: "org.apache.tomcat", module: "tomcat-annotations-api" + } + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional("io.micrometer:micrometer-core") + optional("org.apache.tomcat.embed:tomcat-embed-jasper") + optional("org.apache.tomcat.embed:tomcat-embed-websocket") { + exclude group: "org.apache.tomcat", module: "tomcat-annotations-api" + } + optional("org.springframework:spring-webflux") + + runtimeOnly("jakarta.annotation:jakarta.annotation-api") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("org.apache.httpcomponents.client5:httpclient5") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("io.projectreactor:reactor-test") + testRuntimeOnly("io.projectreactor.netty:reactor-netty-http") + testRuntimeOnly("org.eclipse.jetty:jetty-client") + testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client") + testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client-transport") + testRuntimeOnly("org.springframework:spring-webmvc") + + tomcatDistribution("org.apache.tomcat:tomcat:${tomcatVersion}@zip") +} + +tasks.register("extractTomcatConfigProperties", Sync) { + destinationDir = file(tomcatConfigProperties) + from { + zipTree(configurations.tomcatDistribution.incoming.files.singleFile).matching { + include '**/conf/catalina.properties' + }.singleFile + } +} + +sourceSets { + test { + output.dir(tomcatConfigProperties, builtBy: "extractTomcatConfigProperties") + } +} + +test { + jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/CompressionConnectorCustomizer.java similarity index 91% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/CompressionConnectorCustomizer.java index 26c8403fee12..dc1ddc376e21 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/CompressionConnectorCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.apache.catalina.connector.Connector; import org.apache.coyote.ProtocolHandler; @@ -28,12 +28,13 @@ * Connector. * * @author Brian Clozel + * @since 4.0.0 */ -class CompressionConnectorCustomizer implements TomcatConnectorCustomizer { +public class CompressionConnectorCustomizer implements TomcatConnectorCustomizer { private final Compression compression; - CompressionConnectorCustomizer(Compression compression) { + public CompressionConnectorCustomizer(Compression compression) { this.compression = compression; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConfigurableTomcatWebServerFactory.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConfigurableTomcatWebServerFactory.java similarity index 82% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConfigurableTomcatWebServerFactory.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConfigurableTomcatWebServerFactory.java index 10dfee3124b2..7a175b8236d4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConfigurableTomcatWebServerFactory.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConfigurableTomcatWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import java.io.File; import java.nio.charset.Charset; @@ -24,13 +24,15 @@ import org.apache.catalina.Valve; import org.apache.catalina.connector.Connector; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.ConfigurableWebServerFactory; /** * {@link ConfigurableWebServerFactory} for Tomcat-specific features. * * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 * @see TomcatServletWebServerFactory * @see TomcatReactiveWebServerFactory */ @@ -72,7 +74,7 @@ public interface ConfigurableTomcatWebServerFactory extends ConfigurableWebServe * Add {@link TomcatProtocolHandlerCustomizer}s that should be added to the Tomcat * {@link Connector}. * @param tomcatProtocolHandlerCustomizers the customizers to add - * @since 2.2.0 + * @since 4.0.0 */ void addProtocolHandlerCustomizers(TomcatProtocolHandlerCustomizer... tomcatProtocolHandlerCustomizers); @@ -83,4 +85,17 @@ public interface ConfigurableTomcatWebServerFactory extends ConfigurableWebServe */ void setUriEncoding(Charset uriEncoding); + /** + * Whether to use APR. + * @param useApr whether to use APR + */ + void setUseApr(boolean useApr); + + /** + * Set whether the factory should disable Tomcat's MBean registry prior to creating + * the server. + * @param disableMBeanRegistry whether to disable the MBean registry + */ + void setDisableMBeanRegistry(boolean disableMBeanRegistry); + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConnectorStartFailedException.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConnectorStartFailedException.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConnectorStartFailedException.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConnectorStartFailedException.java index 3dabe15284d2..83eae80b1c9b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConnectorStartFailedException.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConnectorStartFailedException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.apache.catalina.connector.Connector; @@ -25,7 +25,7 @@ * to start, for example due to a port clash or incorrect SSL configuration. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class ConnectorStartFailedException extends WebServerException { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConnectorStartFailureAnalyzer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConnectorStartFailureAnalyzer.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConnectorStartFailureAnalyzer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConnectorStartFailureAnalyzer.java index 17a15d53ee55..d270a3dcd693 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConnectorStartFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/ConnectorStartFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/DisableReferenceClearingContextCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/DisableReferenceClearingContextCustomizer.java similarity index 89% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/DisableReferenceClearingContextCustomizer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/DisableReferenceClearingContextCustomizer.java index 978458920b82..5f77f3e78970 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/DisableReferenceClearingContextCustomizer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/DisableReferenceClearingContextCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.apache.catalina.Context; import org.apache.catalina.core.StandardContext; @@ -24,8 +24,9 @@ * to avoid reflective access warnings on Java 9 and later JVMs. * * @author Andy Wilkinson + * @since 4.0.0 */ -class DisableReferenceClearingContextCustomizer implements TomcatContextCustomizer { +public class DisableReferenceClearingContextCustomizer implements TomcatContextCustomizer { @Override public void customize(Context context) { diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/GracefulShutdown.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/GracefulShutdown.java new file mode 100644 index 000000000000..9d8d7d217e82 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/GracefulShutdown.java @@ -0,0 +1,134 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +import org.apache.catalina.Container; +import org.apache.catalina.Service; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.core.StandardWrapper; +import org.apache.catalina.startup.Tomcat; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.boot.web.server.GracefulShutdownCallback; +import org.springframework.boot.web.server.GracefulShutdownResult; + +/** + * Handles Tomcat graceful shutdown. + * + * @author Andy Wilkinson + */ +final class GracefulShutdown { + + private static final Log logger = LogFactory.getLog(GracefulShutdown.class); + + private final Tomcat tomcat; + + private volatile boolean aborted = false; + + GracefulShutdown(Tomcat tomcat) { + this.tomcat = tomcat; + } + + void shutDownGracefully(GracefulShutdownCallback callback) { + logger.info("Commencing graceful shutdown. Waiting for active requests to complete"); + CountDownLatch shutdownUnderway = new CountDownLatch(1); + new Thread(() -> doShutdown(callback, shutdownUnderway), "tomcat-shutdown").start(); + try { + shutdownUnderway.await(); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + + private void doShutdown(GracefulShutdownCallback callback, CountDownLatch shutdownUnderway) { + try { + List connectors = getConnectors(); + connectors.forEach(this::close); + shutdownUnderway.countDown(); + awaitInactiveOrAborted(); + if (this.aborted) { + logger.info("Graceful shutdown aborted with one or more requests still active"); + callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE); + } + else { + logger.info("Graceful shutdown complete"); + callback.shutdownComplete(GracefulShutdownResult.IDLE); + } + } + finally { + shutdownUnderway.countDown(); + } + } + + private List getConnectors() { + List connectors = new ArrayList<>(); + for (Service service : this.tomcat.getServer().findServices()) { + Collections.addAll(connectors, service.findConnectors()); + } + return connectors; + } + + private void close(Connector connector) { + connector.pause(); + connector.getProtocolHandler().closeServerSocketGraceful(); + } + + private void awaitInactiveOrAborted() { + try { + for (Container host : this.tomcat.getEngine().findChildren()) { + for (Container context : host.findChildren()) { + while (!this.aborted && isActive(context)) { + Thread.sleep(50); + } + } + } + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + + private boolean isActive(Container context) { + try { + if (((StandardContext) context).getInProgressAsyncCount() > 0) { + return true; + } + for (Container wrapper : context.findChildren()) { + if (((StandardWrapper) wrapper).getCountAllocated() > 0) { + return true; + } + } + return false; + } + catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + void abort() { + this.aborted = true; + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/LazySessionIdGenerator.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/LazySessionIdGenerator.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/LazySessionIdGenerator.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/LazySessionIdGenerator.java index e77722fe7928..2848f77bd618 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/LazySessionIdGenerator.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/LazySessionIdGenerator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleState; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java index 8529d3ebbe39..1d3ba09b0ed0 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import java.util.Map; @@ -42,8 +42,9 @@ * @author Scott Frederick * @author Cyril Dangerville * @author Moritz Halbritter + * @since 4.0.0 */ -class SslConnectorCustomizer { +public class SslConnectorCustomizer { private final Log logger; @@ -51,20 +52,20 @@ class SslConnectorCustomizer { private final Connector connector; - SslConnectorCustomizer(Log logger, Connector connector, ClientAuth clientAuth) { + public SslConnectorCustomizer(Log logger, Connector connector, ClientAuth clientAuth) { this.logger = logger; this.clientAuth = clientAuth; this.connector = connector; } - void update(String serverName, SslBundle updatedSslBundle) { + public void update(String serverName, SslBundle updatedSslBundle) { AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) this.connector.getProtocolHandler(); String host = (serverName != null) ? serverName : protocol.getDefaultSSLHostConfigName(); this.logger.debug("SSL Bundle for host " + host + " has been updated, reloading SSL configuration"); addSslHostConfig(protocol, host, updatedSslBundle); } - void customize(SslBundle sslBundle, Map serverNameSslBundles) { + public void customize(SslBundle sslBundle, Map serverNameSslBundles) { ProtocolHandler handler = this.connector.getProtocolHandler(); Assert.state(handler instanceof AbstractHttp11Protocol, "To use SSL, the connector's protocol handler must be an AbstractHttp11Protocol subclass"); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatConnectorCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatConnectorCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatConnectorCustomizer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatConnectorCustomizer.java index 658e2380f560..435a69d2266e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatConnectorCustomizer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatConnectorCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.apache.catalina.connector.Connector; @@ -22,7 +22,7 @@ * Callback interface that can be used to customize a Tomcat {@link Connector}. * * @author Dave Syer - * @since 2.0.0 + * @since 4.0.0 * @see ConfigurableTomcatWebServerFactory */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatContextCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatContextCustomizer.java similarity index 87% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatContextCustomizer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatContextCustomizer.java index 42b89c85292b..25eac4b52bca 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatContextCustomizer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatContextCustomizer.java @@ -14,15 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.apache.catalina.Context; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; + /** * Callback interface that can be used to customize a Tomcat {@link Context}. * * @author Dave Syer - * @since 2.0.0 + * @since 4.0.0 * @see TomcatServletWebServerFactory */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedContext.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatEmbeddedContext.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedContext.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatEmbeddedContext.java index 87a1b93be8ba..be5e75b63226 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedContext.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatEmbeddedContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import java.util.ArrayList; import java.util.Arrays; @@ -41,8 +41,9 @@ * * @author Phillip Webb * @author Andy Wilkinson + * @since 4.0.0 */ -class TomcatEmbeddedContext extends StandardContext { +public class TomcatEmbeddedContext extends StandardContext { private TomcatStarter starter; @@ -114,7 +115,7 @@ private void doWithThreadContextClassLoader(ClassLoader classLoader, Runnable co } } - void setStarter(TomcatStarter starter) { + public void setStarter(TomcatStarter starter) { this.starter = starter; } @@ -122,7 +123,7 @@ TomcatStarter getStarter() { return this.starter; } - void setMimeMappings(MimeMappings mimeMappings) { + public void setMimeMappings(MimeMappings mimeMappings) { this.mimeMappings = mimeMappings; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoader.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoader.java index 18123914545f..9a6a9b23a617 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoader.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import java.io.IOException; import java.net.URL; @@ -34,7 +34,7 @@ * * @author Phillip Webb * @author Andy Clement - * @since 2.0.0 + * @since 4.0.0 */ public class TomcatEmbeddedWebappClassLoader extends ParallelWebappClassLoader { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatProtocolHandlerCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatProtocolHandlerCustomizer.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatProtocolHandlerCustomizer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatProtocolHandlerCustomizer.java index c4213014e210..acd0cdeb2e7c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatProtocolHandlerCustomizer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatProtocolHandlerCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.apache.catalina.connector.Connector; import org.apache.coyote.ProtocolHandler; @@ -25,7 +25,7 @@ * * @param specified type for customization based on {@link ProtocolHandler} * @author Pascal Zwick - * @since 2.2.0 + * @since 4.0.0 * @see ConfigurableTomcatWebServerFactory */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatStarter.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatStarter.java similarity index 88% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatStarter.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatStarter.java index dd510a97d35d..e4fef78d4c4e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatStarter.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatStarter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import java.util.Set; @@ -32,16 +32,17 @@ * * @author Phillip Webb * @author Andy Wilkinson + * @since 4.0.0 */ -class TomcatStarter implements ServletContainerInitializer { +public class TomcatStarter implements ServletContainerInitializer { private static final Log logger = LogFactory.getLog(TomcatStarter.class); - private final ServletContextInitializer[] initializers; + private final Iterable initializers; private volatile Exception startUpException; - TomcatStarter(ServletContextInitializer[] initializers) { + public TomcatStarter(Iterable initializers) { this.initializers = initializers; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatWebServer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatWebServer.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatWebServer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatWebServer.java index 6ab44eba3c0f..a927840e2f9c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatWebServer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatWebServer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import java.util.Arrays; import java.util.HashMap; @@ -39,6 +39,8 @@ import org.apache.commons.logging.LogFactory; import org.apache.naming.ContextBindings; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.GracefulShutdownCallback; import org.springframework.boot.web.server.GracefulShutdownResult; import org.springframework.boot.web.server.PortInUseException; @@ -55,7 +57,7 @@ * * @author Brian Clozel * @author Kristine Jetzke - * @since 2.0.0 + * @since 4.0.0 */ public class TomcatWebServer implements WebServer { @@ -97,7 +99,7 @@ public TomcatWebServer(Tomcat tomcat, boolean autoStart) { * @param tomcat the underlying Tomcat server * @param autoStart if the server should be started * @param shutdown type of shutdown supported by the server - * @since 2.3.0 + * @since 4.0.0 */ public TomcatWebServer(Tomcat tomcat, boolean autoStart, Shutdown shutdown) { Assert.notNull(tomcat, "'tomcat' must not be null"); diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatWebServerFactory.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatWebServerFactory.java new file mode 100644 index 000000000000..6e098a5e970c --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/TomcatWebServerFactory.java @@ -0,0 +1,462 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat; + +import java.io.File; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.apache.catalina.Context; +import org.apache.catalina.Engine; +import org.apache.catalina.Executor; +import org.apache.catalina.LifecycleListener; +import org.apache.catalina.Valve; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.startup.Tomcat; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.coyote.AbstractProtocol; +import org.apache.coyote.ProtocolHandler; +import org.apache.coyote.http2.Http2Protocol; +import org.apache.tomcat.util.modeler.Registry; + +import org.springframework.boot.util.LambdaSafe; +import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.Ssl; +import org.springframework.core.NativeDetector; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Base class for factories that produce a {@link TomcatWebServer}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class TomcatWebServerFactory extends AbstractConfigurableWebServerFactory + implements ConfigurableTomcatWebServerFactory { + + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + + /** + * The class name of default protocol used. + */ + public static final String DEFAULT_PROTOCOL = "org.apache.coyote.http11.Http11NioProtocol"; + + private final Log logger = LogFactory.getLog(getClass()); + + private File baseDirectory; + + private int backgroundProcessorDelay; + + private List engineValves = new ArrayList<>(); + + private List contextValves = new ArrayList<>(); + + private List contextLifecycleListeners = new ArrayList<>(); + + private Set contextCustomizers = new LinkedHashSet<>(); + + private Set connectorCustomizers = new LinkedHashSet<>(); + + private Set> protocolHandlerCustomizers = new LinkedHashSet<>(); + + private List additionalConnectors = new ArrayList<>(); + + private Charset uriEncoding = DEFAULT_CHARSET; + + private String protocol = DEFAULT_PROTOCOL; + + private boolean disableMBeanRegistry = true; + + private boolean useApr; + + protected TomcatWebServerFactory() { + } + + protected TomcatWebServerFactory(int port) { + super(port); + } + + private List getDefaultServerLifecycleListeners() { + ArrayList lifecycleListeners = new ArrayList<>(); + if (this.useApr && !NativeDetector.inNativeImage()) { + lifecycleListeners.add(new AprLifecycleListener()); + } + return lifecycleListeners; + } + + @Override + public void setBaseDirectory(File baseDirectory) { + this.baseDirectory = baseDirectory; + } + + public File getBaseDirectory() { + return this.baseDirectory; + } + + /** + * Returns a mutable collection of the {@link Valve}s that will be applied to the + * Tomcat {@link Engine}. + * @return the engine valves that will be applied + */ + public Collection getEngineValves() { + return this.engineValves; + } + + /** + * Set {@link Valve}s that should be applied to the Tomcat {@link Engine}. Calling + * this method will replace any existing valves. + * @param engineValves the valves to set + */ + public void setEngineValves(Collection engineValves) { + Assert.notNull(engineValves, "'engineValves' must not be null"); + this.engineValves = new ArrayList<>(engineValves); + } + + @Override + public void addEngineValves(Valve... engineValves) { + Assert.notNull(engineValves, "'engineValves' must not be null"); + this.engineValves.addAll(Arrays.asList(engineValves)); + } + + public Charset getUriEncoding() { + return this.uriEncoding; + } + + @Override + public void setUriEncoding(Charset uriEncoding) { + this.uriEncoding = uriEncoding; + } + + public int getBackgroundProcessorDelay() { + return this.backgroundProcessorDelay; + } + + @Override + public void setBackgroundProcessorDelay(int delay) { + this.backgroundProcessorDelay = delay; + } + + public String getProtocol() { + return this.protocol; + } + + /** + * The Tomcat protocol to use when create the {@link Connector}. + * @param protocol the protocol + * @see Connector#Connector(String) + */ + public void setProtocol(String protocol) { + Assert.hasLength(protocol, "'protocol' must not be empty"); + this.protocol = protocol; + } + + /** + * Returns a mutable collection of the {@link Valve}s that will be applied to the + * Tomcat {@link Context}. + * @return the context valves that will be applied + * @see #getEngineValves() + */ + public Collection getContextValves() { + return this.contextValves; + } + + /** + * Set {@link Valve}s that should be applied to the Tomcat {@link Context}. Calling + * this method will replace any existing valves. + * @param contextValves the valves to set + */ + public void setContextValves(Collection contextValves) { + Assert.notNull(contextValves, "'contextValves' must not be null"); + this.contextValves = new ArrayList<>(contextValves); + } + + /** + * Add {@link Valve}s that should be applied to the Tomcat {@link Context}. + * @param contextValves the valves to add + */ + public void addContextValves(Valve... contextValves) { + Assert.notNull(contextValves, "'contextValves' must not be null"); + this.contextValves.addAll(Arrays.asList(contextValves)); + } + + /** + * Returns a mutable collection of the {@link LifecycleListener}s that will be applied + * to the Tomcat {@link Context}. + * @return the context lifecycle listeners that will be applied + */ + public Collection getContextLifecycleListeners() { + return this.contextLifecycleListeners; + } + + /** + * Set {@link LifecycleListener}s that should be applied to the Tomcat + * {@link Context}. Calling this method will replace any existing listeners. + * @param contextLifecycleListeners the listeners to set + */ + public void setContextLifecycleListeners(Collection contextLifecycleListeners) { + Assert.notNull(contextLifecycleListeners, "'contextLifecycleListeners' must not be null"); + this.contextLifecycleListeners = new ArrayList<>(contextLifecycleListeners); + } + + /** + * Add {@link LifecycleListener}s that should be added to the Tomcat {@link Context}. + * @param contextLifecycleListeners the listeners to add + */ + public void addContextLifecycleListeners(LifecycleListener... contextLifecycleListeners) { + Assert.notNull(contextLifecycleListeners, "'contextLifecycleListeners' must not be null"); + this.contextLifecycleListeners.addAll(Arrays.asList(contextLifecycleListeners)); + } + + /** + * Returns a mutable collection of the {@link TomcatContextCustomizer}s that will be + * applied to the Tomcat {@link Context}. + * @return the listeners that will be applied + */ + public Collection getContextCustomizers() { + return this.contextCustomizers; + } + + /** + * Set {@link TomcatContextCustomizer}s that should be applied to the Tomcat + * {@link Context}. Calling this method will replace any existing customizers. + * @param contextCustomizers the customizers to set + */ + public void setContextCustomizers(Collection contextCustomizers) { + Assert.notNull(contextCustomizers, "'contextCustomizers' must not be null"); + this.contextCustomizers = new LinkedHashSet<>(contextCustomizers); + } + + @Override + public void addContextCustomizers(TomcatContextCustomizer... contextCustomizers) { + Assert.notNull(contextCustomizers, "'contextCustomizers' must not be null"); + this.contextCustomizers.addAll(Arrays.asList(contextCustomizers)); + } + + /** + * Returns a mutable collection of the {@link TomcatConnectorCustomizer}s that will be + * applied to the Tomcat {@link Connector}. + * @return the customizers that will be applied + */ + public Set getConnectorCustomizers() { + return this.connectorCustomizers; + } + + /** + * Set {@link TomcatConnectorCustomizer}s that should be applied to the Tomcat + * {@link Connector}. Calling this method will replace any existing customizers. + * @param connectorCustomizers the customizers to set + */ + public void setConnectorCustomizers(Collection connectorCustomizers) { + Assert.notNull(connectorCustomizers, "'connectorCustomizers' must not be null"); + this.connectorCustomizers = new LinkedHashSet<>(connectorCustomizers); + } + + @Override + public void addConnectorCustomizers(TomcatConnectorCustomizer... connectorCustomizers) { + Assert.notNull(connectorCustomizers, "'connectorCustomizers' must not be null"); + this.connectorCustomizers.addAll(Arrays.asList(connectorCustomizers)); + } + + /** + * Returns a mutable collection of the {@link TomcatProtocolHandlerCustomizer}s that + * will be applied to the Tomcat {@link Connector}. + * @return the customizers that will be applied + */ + public Set> getProtocolHandlerCustomizers() { + return this.protocolHandlerCustomizers; + } + + /** + * Set {@link TomcatProtocolHandlerCustomizer}s that should be applied to the Tomcat + * {@link Connector}. Calling this method will replace any existing customizers. + * @param protocolHandlerCustomizers the customizers to set + */ + public void setProtocolHandlerCustomizers( + Collection> protocolHandlerCustomizers) { + Assert.notNull(protocolHandlerCustomizers, "'protocolHandlerCustomizers' must not be null"); + this.protocolHandlerCustomizers = new LinkedHashSet<>(protocolHandlerCustomizers); + } + + @Override + public void addProtocolHandlerCustomizers(TomcatProtocolHandlerCustomizer... protocolHandlerCustomizers) { + Assert.notNull(protocolHandlerCustomizers, "'protocolHandlerCustomizers' must not be null"); + this.protocolHandlerCustomizers.addAll(Arrays.asList(protocolHandlerCustomizers)); + } + + /** + * Returns a mutable collection of the {@link Connector}s that will be added to the + * Tomcat server. + * @return the additional connectors + */ + public List getAdditionalConnectors() { + return this.additionalConnectors; + } + + /** + * Set additional {@link Connector}s that should be added to the Tomcat server . + * Calling this method will replace any existing additional connectors. + * @param additionalConnectors the additionalConnectors to set + */ + public void setAdditionalConnectors(Collection additionalConnectors) { + Assert.notNull(additionalConnectors, "'additionalConnectors' must not be null"); + this.additionalConnectors = new ArrayList<>(additionalConnectors); + } + + /** + * Add {@link Connector}s in addition to the default connector, e.g. for SSL or AJP. + *

    + * {@link #getConnectorCustomizers Connector customizers} are not applied to + * connectors added this way. + * @param connectors the connectors to add + */ + public void addAdditionalConnectors(Connector... connectors) { + Assert.notNull(connectors, "'connectors' must not be null"); + this.additionalConnectors.addAll(Arrays.asList(connectors)); + } + + /** + * Returns whether the factory should disable Tomcat's MBean registry prior to + * creating the server. + * @return whether to disable Tomcat's MBean registry + */ + public boolean isDisableMBeanRegistry() { + return this.disableMBeanRegistry; + } + + /** + * Set whether the factory should disable Tomcat's MBean registry prior to creating + * the server. + * @param disableMBeanRegistry whether to disable the MBean registry + */ + @Override + public void setDisableMBeanRegistry(boolean disableMBeanRegistry) { + this.disableMBeanRegistry = disableMBeanRegistry; + } + + /** + * Whether to use APR. + * @param useApr whether to use APR + */ + @Override + public void setUseApr(boolean useApr) { + this.useApr = useApr; + } + + protected Tomcat createTomcat() { + if (this.isDisableMBeanRegistry()) { + Registry.disableRegistry(); + } + Tomcat tomcat = new Tomcat(); + File baseDir = (getBaseDirectory() != null) ? getBaseDirectory() : createTempDir("tomcat"); + tomcat.setBaseDir(baseDir.getAbsolutePath()); + for (LifecycleListener listener : getDefaultServerLifecycleListeners()) { + tomcat.getServer().addLifecycleListener(listener); + } + Connector connector = new Connector(getProtocol()); + connector.setThrowOnFailure(true); + tomcat.getService().addConnector(connector); + customizeConnector(connector); + tomcat.setConnector(connector); + registerConnectorExecutor(tomcat, connector); + tomcat.getHost().setAutoDeploy(false); + configureEngine(tomcat.getEngine()); + for (Connector additionalConnector : this.getAdditionalConnectors()) { + tomcat.getService().addConnector(additionalConnector); + registerConnectorExecutor(tomcat, additionalConnector); + } + return tomcat; + } + + protected void customizeConnector(Connector connector) { + int port = Math.max(getPort(), 0); + connector.setPort(port); + if (StringUtils.hasText(getServerHeader())) { + connector.setProperty("server", getServerHeader()); + } + if (connector.getProtocolHandler() instanceof AbstractProtocol abstractProtocol) { + customizeProtocol(abstractProtocol); + } + invokeProtocolHandlerCustomizers(connector.getProtocolHandler()); + if (getUriEncoding() != null) { + connector.setURIEncoding(getUriEncoding().name()); + } + if (getHttp2() != null && getHttp2().isEnabled()) { + connector.addUpgradeProtocol(new Http2Protocol()); + } + if (Ssl.isEnabled(getSsl())) { + customizeSsl(connector); + } + TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer(getCompression()); + compression.customize(connector); + for (TomcatConnectorCustomizer customizer : this.getConnectorCustomizers()) { + customizer.customize(connector); + } + } + + private void customizeProtocol(AbstractProtocol protocol) { + if (getAddress() != null) { + protocol.setAddress(getAddress()); + } + } + + @SuppressWarnings("unchecked") + private void invokeProtocolHandlerCustomizers(ProtocolHandler protocolHandler) { + LambdaSafe + .callbacks(TomcatProtocolHandlerCustomizer.class, this.getProtocolHandlerCustomizers(), protocolHandler) + .invoke((customizer) -> customizer.customize(protocolHandler)); + } + + private void customizeSsl(Connector connector) { + SslConnectorCustomizer customizer = new SslConnectorCustomizer(this.logger, connector, + getSsl().getClientAuth()); + customizer.customize(getSslBundle(), getServerNameSslBundles()); + addBundleUpdateHandler(null, getSsl().getBundle(), customizer); + getSsl().getServerNameBundles() + .forEach((serverNameSslBundle) -> addBundleUpdateHandler(serverNameSslBundle.serverName(), + serverNameSslBundle.bundle(), customizer)); + } + + private void addBundleUpdateHandler(String serverName, String sslBundleName, SslConnectorCustomizer customizer) { + if (StringUtils.hasText(sslBundleName)) { + getSslBundles().addBundleUpdateHandler(sslBundleName, + (sslBundle) -> customizer.update(serverName, sslBundle)); + } + } + + private void registerConnectorExecutor(Tomcat tomcat, Connector connector) { + if (connector.getProtocolHandler().getExecutor() instanceof Executor executor) { + tomcat.getService().addExecutor(executor); + } + } + + private void configureEngine(Engine engine) { + engine.setBackgroundProcessorDelay(getBackgroundProcessorDelay()); + for (Valve valve : getEngineValves()) { + engine.getPipeline().addValve(valve); + } + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatBackgroundPreinitializer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatBackgroundPreinitializer.java new file mode 100644 index 000000000000..7092df0731e0 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatBackgroundPreinitializer.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure; + +import org.apache.catalina.authenticator.NonLoginAuthenticator; +import org.apache.tomcat.util.http.Rfc6265CookieProcessor; + +import org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer; + +/** + * {@link BackgroundPreinitializer} for Tomcat. + * + * @author Phillip Webb + */ +final class TomcatBackgroundPreinitializer implements BackgroundPreinitializer { + + @Override + public void preinitialize() throws Exception { + new Rfc6265CookieProcessor(); + new NonLoginAuthenticator(); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerProperties.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerProperties.java new file mode 100644 index 000000000000..90879dea831a --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerProperties.java @@ -0,0 +1,868 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure; + +import java.io.File; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.convert.DurationUnit; +import org.springframework.util.unit.DataSize; + +/** + * Tomcat server properties. + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Ivan Sopov + * @author Marcos Barbero + * @author Eddú Meléndez + * @author Quinten De Swaef + * @author Venil Noronha + * @author Aurélien Leboulanger + * @author Brian Clozel + * @author Olivier Lamy + * @author Chentao Qu + * @author Artsiom Yudovin + * @author Andrew McGhie + * @author Rafiullah Hamedy + * @author Dirk Deyne + * @author HaiTao Zhang + * @author Victor Mandujano + * @author Chris Bono + * @author Parviz Rozikov + * @author Florian Storz + * @author Michael Weidmann + * @author Lasse Wulff + * @since 4.0.0 + */ +@ConfigurationProperties("server.tomcat") +public class TomcatServerProperties { + + /** + * Tomcat base directory. If not specified, a temporary directory is used. + */ + private File basedir; + + /** + * Delay between the invocation of backgroundProcess methods. If a duration suffix is + * not specified, seconds will be used. + */ + @DurationUnit(ChronoUnit.SECONDS) + private Duration backgroundProcessorDelay = Duration.ofSeconds(10); + + /** + * Maximum size of the form content in any HTTP post request. + */ + private DataSize maxHttpFormPostSize = DataSize.ofMegabytes(2); + + /** + * Maximum per-part header size permitted in a multipart/form-data request. Requests + * that exceed this limit will be rejected. A value of less than 0 means no limit. + */ + private DataSize maxPartHeaderSize = DataSize.ofBytes(512); + + /** + * Maximum total number of parts permitted in a multipart/form-data request. Requests + * that exceed this limit will be rejected. A value of less than 0 means no limit. + */ + private int maxPartCount = 10; + + /** + * Maximum amount of request body to swallow. + */ + private DataSize maxSwallowSize = DataSize.ofMegabytes(2); + + /** + * Whether requests to the context root should be redirected by appending a / to the + * path. When using SSL terminated at a proxy, this property should be set to false. + */ + private Boolean redirectContextRoot = true; + + /** + * Whether HTTP 1.1 and later location headers generated by a call to sendRedirect + * will use relative or absolute redirects. + */ + private boolean useRelativeRedirects; + + /** + * Character encoding to use to decode the URI. + */ + private Charset uriEncoding = StandardCharsets.UTF_8; + + /** + * Maximum number of connections that the server accepts and processes at any given + * time. Once the limit has been reached, the operating system may still accept + * connections based on the "acceptCount" property. + */ + private int maxConnections = 8192; + + /** + * Maximum queue length for incoming connection requests when all possible request + * processing threads are in use. + */ + private int acceptCount = 100; + + /** + * Maximum number of idle processors that will be retained in the cache and reused + * with a subsequent request. When set to -1 the cache will be unlimited with a + * theoretical maximum size equal to the maximum number of connections. + */ + private int processorCache = 200; + + /** + * Time to wait for another HTTP request before the connection is closed. When not set + * the connectionTimeout is used. When set to -1 there will be no timeout. + */ + private Duration keepAliveTimeout; + + /** + * Maximum number of HTTP requests that can be pipelined before the connection is + * closed. When set to 0 or 1, keep-alive and pipelining are disabled. When set to -1, + * an unlimited number of pipelined or keep-alive requests are allowed. + */ + private int maxKeepAliveRequests = 100; + + /** + * List of additional patterns that match jars to ignore for TLD scanning. The special + * '?' and '*' characters can be used in the pattern to match one and only one + * character and zero or more characters respectively. + */ + private List additionalTldSkipPatterns = new ArrayList<>(); + + /** + * List of additional unencoded characters that should be allowed in URI paths. Only + * "< > [ \ ] ^ ` { | }" are allowed. + */ + private List relaxedPathChars = new ArrayList<>(); + + /** + * List of additional unencoded characters that should be allowed in URI query + * strings. Only "< > [ \ ] ^ ` { | }" are allowed. + */ + private List relaxedQueryChars = new ArrayList<>(); + + /** + * Amount of time the connector will wait, after accepting a connection, for the + * request URI line to be presented. + */ + private Duration connectionTimeout; + + /** + * Maximum size of the HTTP response header. + */ + private DataSize maxHttpResponseHeaderSize = DataSize.ofKilobytes(8); + + /** + * Maximum number of parameters (GET plus POST) that will be automatically parsed by + * the container. A value of less than 0 means no limit. + */ + private int maxParameterCount = 1000; + + /** + * Whether to use APR. + */ + private UseApr useApr = UseApr.NEVER; + + /** + * Access log configuration. + */ + private final Accesslog accesslog = new Accesslog(); + + /** + * Thread related configuration. + */ + private final Threads threads = new Threads(); + + /** + * Static resource configuration. + */ + private final Resource resource = new Resource(); + + /** + * Modeler MBean Registry configuration. + */ + private final Mbeanregistry mbeanregistry = new Mbeanregistry(); + + /** + * Remote Ip Valve configuration. + */ + private final Remoteip remoteip = new Remoteip(); + + public Duration getBackgroundProcessorDelay() { + return this.backgroundProcessorDelay; + } + + public void setBackgroundProcessorDelay(Duration backgroundProcessorDelay) { + this.backgroundProcessorDelay = backgroundProcessorDelay; + } + + public File getBasedir() { + return this.basedir; + } + + public void setBasedir(File basedir) { + this.basedir = basedir; + } + + public Boolean getRedirectContextRoot() { + return this.redirectContextRoot; + } + + public void setRedirectContextRoot(Boolean redirectContextRoot) { + this.redirectContextRoot = redirectContextRoot; + } + + public boolean isUseRelativeRedirects() { + return this.useRelativeRedirects; + } + + public void setUseRelativeRedirects(boolean useRelativeRedirects) { + this.useRelativeRedirects = useRelativeRedirects; + } + + public Charset getUriEncoding() { + return this.uriEncoding; + } + + public void setUriEncoding(Charset uriEncoding) { + this.uriEncoding = uriEncoding; + } + + public int getMaxConnections() { + return this.maxConnections; + } + + public void setMaxConnections(int maxConnections) { + this.maxConnections = maxConnections; + } + + public DataSize getMaxSwallowSize() { + return this.maxSwallowSize; + } + + public void setMaxSwallowSize(DataSize maxSwallowSize) { + this.maxSwallowSize = maxSwallowSize; + } + + public int getAcceptCount() { + return this.acceptCount; + } + + public void setAcceptCount(int acceptCount) { + this.acceptCount = acceptCount; + } + + public int getProcessorCache() { + return this.processorCache; + } + + public void setProcessorCache(int processorCache) { + this.processorCache = processorCache; + } + + public Duration getKeepAliveTimeout() { + return this.keepAliveTimeout; + } + + public void setKeepAliveTimeout(Duration keepAliveTimeout) { + this.keepAliveTimeout = keepAliveTimeout; + } + + public int getMaxKeepAliveRequests() { + return this.maxKeepAliveRequests; + } + + public void setMaxKeepAliveRequests(int maxKeepAliveRequests) { + this.maxKeepAliveRequests = maxKeepAliveRequests; + } + + public List getAdditionalTldSkipPatterns() { + return this.additionalTldSkipPatterns; + } + + public void setAdditionalTldSkipPatterns(List additionalTldSkipPatterns) { + this.additionalTldSkipPatterns = additionalTldSkipPatterns; + } + + public List getRelaxedPathChars() { + return this.relaxedPathChars; + } + + public void setRelaxedPathChars(List relaxedPathChars) { + this.relaxedPathChars = relaxedPathChars; + } + + public List getRelaxedQueryChars() { + return this.relaxedQueryChars; + } + + public void setRelaxedQueryChars(List relaxedQueryChars) { + this.relaxedQueryChars = relaxedQueryChars; + } + + public Duration getConnectionTimeout() { + return this.connectionTimeout; + } + + public void setConnectionTimeout(Duration connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public DataSize getMaxHttpResponseHeaderSize() { + return this.maxHttpResponseHeaderSize; + } + + public void setMaxHttpResponseHeaderSize(DataSize maxHttpResponseHeaderSize) { + this.maxHttpResponseHeaderSize = maxHttpResponseHeaderSize; + } + + public DataSize getMaxHttpFormPostSize() { + return this.maxHttpFormPostSize; + } + + public void setMaxHttpFormPostSize(DataSize maxHttpFormPostSize) { + this.maxHttpFormPostSize = maxHttpFormPostSize; + } + + public DataSize getMaxPartHeaderSize() { + return this.maxPartHeaderSize; + } + + public void setMaxPartHeaderSize(DataSize maxPartHeaderSize) { + this.maxPartHeaderSize = maxPartHeaderSize; + } + + public int getMaxPartCount() { + return this.maxPartCount; + } + + public void setMaxPartCount(int maxPartCount) { + this.maxPartCount = maxPartCount; + } + + public int getMaxParameterCount() { + return this.maxParameterCount; + } + + public void setMaxParameterCount(int maxParameterCount) { + this.maxParameterCount = maxParameterCount; + } + + public UseApr getUseApr() { + return this.useApr; + } + + public void setUseApr(UseApr useApr) { + this.useApr = useApr; + } + + public Accesslog getAccesslog() { + return this.accesslog; + } + + public Threads getThreads() { + return this.threads; + } + + public Resource getResource() { + return this.resource; + } + + public Mbeanregistry getMbeanregistry() { + return this.mbeanregistry; + } + + public Remoteip getRemoteip() { + return this.remoteip; + } + + /** + * Tomcat access log properties. + */ + public static class Accesslog { + + /** + * Enable access log. + */ + private boolean enabled = false; + + /** + * Whether logging of the request will only be enabled if + * "ServletRequest.getAttribute(conditionIf)" does not yield null. + */ + private String conditionIf; + + /** + * Whether logging of the request will only be enabled if + * "ServletRequest.getAttribute(conditionUnless)" yield null. + */ + private String conditionUnless; + + /** + * Format pattern for access logs. + */ + private String pattern = "common"; + + /** + * Directory in which log files are created. Can be absolute or relative to the + * Tomcat base dir. + */ + private String directory = "logs"; + + /** + * Log file name prefix. + */ + protected String prefix = "access_log"; + + /** + * Log file name suffix. + */ + private String suffix = ".log"; + + /** + * Character set used by the log file. Default to the system default character + * set. + */ + private String encoding; + + /** + * Locale used to format timestamps in log entries and in log file name suffix. + * Default to the default locale of the Java process. + */ + private String locale; + + /** + * Whether to check for log file existence so it can be recreated if an external + * process has renamed it. + */ + private boolean checkExists = false; + + /** + * Whether to enable access log rotation. + */ + private boolean rotate = true; + + /** + * Whether to defer inclusion of the date stamp in the file name until rotate + * time. + */ + private boolean renameOnRotate = false; + + /** + * Number of days to retain the access log files before they are removed. + */ + private int maxDays = -1; + + /** + * Date format to place in the log file name. + */ + private String fileDateFormat = ".yyyy-MM-dd"; + + /** + * Whether to use IPv6 canonical representation format as defined by RFC 5952. + */ + private boolean ipv6Canonical = false; + + /** + * Set request attributes for the IP address, Hostname, protocol, and port used + * for the request. + */ + private boolean requestAttributesEnabled = false; + + /** + * Whether to buffer output such that it is flushed only periodically. + */ + private boolean buffered = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getConditionIf() { + return this.conditionIf; + } + + public void setConditionIf(String conditionIf) { + this.conditionIf = conditionIf; + } + + public String getConditionUnless() { + return this.conditionUnless; + } + + public void setConditionUnless(String conditionUnless) { + this.conditionUnless = conditionUnless; + } + + public String getPattern() { + return this.pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public String getDirectory() { + return this.directory; + } + + public void setDirectory(String directory) { + this.directory = directory; + } + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return this.suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public String getEncoding() { + return this.encoding; + } + + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + public String getLocale() { + return this.locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + + public boolean isCheckExists() { + return this.checkExists; + } + + public void setCheckExists(boolean checkExists) { + this.checkExists = checkExists; + } + + public boolean isRotate() { + return this.rotate; + } + + public void setRotate(boolean rotate) { + this.rotate = rotate; + } + + public boolean isRenameOnRotate() { + return this.renameOnRotate; + } + + public void setRenameOnRotate(boolean renameOnRotate) { + this.renameOnRotate = renameOnRotate; + } + + public int getMaxDays() { + return this.maxDays; + } + + public void setMaxDays(int maxDays) { + this.maxDays = maxDays; + } + + public String getFileDateFormat() { + return this.fileDateFormat; + } + + public void setFileDateFormat(String fileDateFormat) { + this.fileDateFormat = fileDateFormat; + } + + public boolean isIpv6Canonical() { + return this.ipv6Canonical; + } + + public void setIpv6Canonical(boolean ipv6Canonical) { + this.ipv6Canonical = ipv6Canonical; + } + + public boolean isRequestAttributesEnabled() { + return this.requestAttributesEnabled; + } + + public void setRequestAttributesEnabled(boolean requestAttributesEnabled) { + this.requestAttributesEnabled = requestAttributesEnabled; + } + + public boolean isBuffered() { + return this.buffered; + } + + public void setBuffered(boolean buffered) { + this.buffered = buffered; + } + + } + + /** + * Tomcat thread properties. + */ + public static class Threads { + + /** + * Maximum amount of worker threads. Doesn't have an effect if virtual threads are + * enabled. + */ + private int max = 200; + + /** + * Minimum amount of worker threads. Doesn't have an effect if virtual threads are + * enabled. + */ + private int minSpare = 10; + + /** + * Maximum capacity of the thread pool's backing queue. This setting only has an + * effect if the value is greater than 0. + */ + private int maxQueueCapacity = 2147483647; + + public int getMax() { + return this.max; + } + + public void setMax(int max) { + this.max = max; + } + + public int getMinSpare() { + return this.minSpare; + } + + public void setMinSpare(int minSpare) { + this.minSpare = minSpare; + } + + public int getMaxQueueCapacity() { + return this.maxQueueCapacity; + } + + public void setMaxQueueCapacity(int maxQueueCapacity) { + this.maxQueueCapacity = maxQueueCapacity; + } + + } + + /** + * Tomcat static resource properties. + */ + public static class Resource { + + /** + * Whether static resource caching is permitted for this web application. + */ + private boolean allowCaching = true; + + /** + * Time-to-live of the static resource cache. + */ + private Duration cacheTtl; + + public boolean isAllowCaching() { + return this.allowCaching; + } + + public void setAllowCaching(boolean allowCaching) { + this.allowCaching = allowCaching; + } + + public Duration getCacheTtl() { + return this.cacheTtl; + } + + public void setCacheTtl(Duration cacheTtl) { + this.cacheTtl = cacheTtl; + } + + } + + public static class Mbeanregistry { + + /** + * Whether Tomcat's MBean Registry should be enabled. + */ + private boolean enabled; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + + public static class Remoteip { + + /** + * Regular expression that matches proxies that are to be trusted. + */ + private String internalProxies = "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 10/8 + + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" // 192.168/16 + + "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" // 169.254/16 + + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 127/8 + + "100\\.6[4-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.[7-9]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.1[0-1]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.12[0-7]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + + "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + + "0:0:0:0:0:0:0:1|" // 0:0:0:0:0:0:0:1 + + "::1|" // ::1 + + "fe[89ab]\\p{XDigit}:.*|" // + + "f[cd]\\p{XDigit}{2}+:.*"; + + /** + * Header that holds the incoming protocol, usually named "X-Forwarded-Proto". + */ + private String protocolHeader; + + /** + * Value of the protocol header indicating whether the incoming request uses SSL. + */ + private String protocolHeaderHttpsValue = "https"; + + /** + * Name of the HTTP header from which the remote host is extracted. + */ + private String hostHeader = "X-Forwarded-Host"; + + /** + * Name of the HTTP header used to override the original port value. + */ + private String portHeader = "X-Forwarded-Port"; + + /** + * Name of the HTTP header from which the remote IP is extracted. For instance, + * 'X-FORWARDED-FOR'. + */ + private String remoteIpHeader; + + /** + * Regular expression defining proxies that are trusted when they appear in the + * "remote-ip-header" header. + */ + private String trustedProxies; + + public String getInternalProxies() { + return this.internalProxies; + } + + public void setInternalProxies(String internalProxies) { + this.internalProxies = internalProxies; + } + + public String getProtocolHeader() { + return this.protocolHeader; + } + + public void setProtocolHeader(String protocolHeader) { + this.protocolHeader = protocolHeader; + } + + public String getProtocolHeaderHttpsValue() { + return this.protocolHeaderHttpsValue; + } + + public String getHostHeader() { + return this.hostHeader; + } + + public void setHostHeader(String hostHeader) { + this.hostHeader = hostHeader; + } + + public void setProtocolHeaderHttpsValue(String protocolHeaderHttpsValue) { + this.protocolHeaderHttpsValue = protocolHeaderHttpsValue; + } + + public String getPortHeader() { + return this.portHeader; + } + + public void setPortHeader(String portHeader) { + this.portHeader = portHeader; + } + + public String getRemoteIpHeader() { + return this.remoteIpHeader; + } + + public void setRemoteIpHeader(String remoteIpHeader) { + this.remoteIpHeader = remoteIpHeader; + } + + public String getTrustedProxies() { + return this.trustedProxies; + } + + public void setTrustedProxies(String trustedProxies) { + this.trustedProxies = trustedProxies; + } + + } + + /** + * When to use APR. + */ + public enum UseApr { + + /** + * Always use APR and fail if it's not available. + */ + ALWAYS, + + /** + * Use APR if it is available. + */ + WHEN_AVAILABLE, + + /** + * Never use APR. + */ + NEVER + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatVirtualThreadsWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatVirtualThreadsWebServerFactoryCustomizer.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatVirtualThreadsWebServerFactoryCustomizer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatVirtualThreadsWebServerFactoryCustomizer.java index 5a383ec30fca..c28e6db6081b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatVirtualThreadsWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatVirtualThreadsWebServerFactoryCustomizer.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.tomcat.autoconfigure; import org.apache.coyote.ProtocolHandler; import org.apache.tomcat.util.threads.VirtualThreadExecutor; -import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory; +import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.core.Ordered; @@ -28,7 +28,7 @@ * handler}. * * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ public class TomcatVirtualThreadsWebServerFactoryCustomizer implements WebServerFactoryCustomizer, Ordered { diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerConfiguration.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerConfiguration.java new file mode 100644 index 000000000000..799eb73f4338 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerConfiguration.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure; + +import org.apache.tomcat.websocket.server.WsSci; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; +import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; +import org.springframework.boot.autoconfigure.thread.Threading; +import org.springframework.boot.tomcat.autoconfigure.reactive.TomcatReactiveWebServerAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * {@link Configuration Configuration} for a Tomcat-based reactive or servlet web server. + * + * @author Andy Wilkinson + * @since 4.0.0 + * @see TomcatReactiveWebServerAutoConfiguration + * @see TomcatServletWebServerAutoConfiguration + */ +@ConditionalOnNotWarDeployment +@Configuration(proxyBeanMethods = false) +public class TomcatWebServerConfiguration { + + @Bean + TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, + ServerProperties serverProperties, TomcatServerProperties tomcatProperties) { + return new TomcatWebServerFactoryCustomizer(environment, serverProperties, tomcatProperties); + } + + @Bean + @ConditionalOnThreading(Threading.VIRTUAL) + TomcatVirtualThreadsWebServerFactoryCustomizer tomcatVirtualThreadsProtocolHandlerCustomizer() { + return new TomcatVirtualThreadsWebServerFactoryCustomizer(); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(WsSci.class) + static class TomcatWebSocketConfiguration { + + @Bean + WebSocketTomcatWebServerFactoryCustomizer webSocketWebServerCustomizer() { + return new WebSocketTomcatWebServerFactoryCustomizer(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizer.java similarity index 82% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizer.java index 881e746f941f..16ee01c871d5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.tomcat.autoconfigure; import java.time.Duration; import java.util.List; @@ -22,6 +22,7 @@ import java.util.stream.Collectors; import org.apache.catalina.Lifecycle; +import org.apache.catalina.core.AprLifecycleListener; import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.valves.ErrorReportValve; import org.apache.catalina.valves.RemoteIpValve; @@ -33,21 +34,22 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeAttribute; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Accesslog; -import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Remoteip; import org.springframework.boot.cloud.CloudPlatform; import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory; +import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties.Accesslog; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties.Remoteip; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties.UseApr; import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.core.Ordered; import org.springframework.core.env.Environment; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.unit.DataSize; /** - * Customization for Tomcat-specific features common for both Servlet and Reactive - * servers. + * Customization for Tomcat-specific features common to both Servlet and Reactive servers. * * @author Brian Clozel * @author Yulin Qin @@ -62,7 +64,7 @@ * @author Parviz Rozikov * @author Florian Storz * @author Michael Weidmann - * @since 2.0.0 + * @since 4.0.0 */ public class TomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer, Ordered { @@ -73,9 +75,13 @@ public class TomcatWebServerFactoryCustomizer private final ServerProperties serverProperties; - public TomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { + private final TomcatServerProperties tomcatProperties; + + public TomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties, + TomcatServerProperties tomcatProperties) { this.environment = environment; this.serverProperties = serverProperties; + this.tomcatProperties = tomcatProperties; } @Override @@ -86,15 +92,14 @@ public int getOrder() { @Override @SuppressWarnings("removal") public void customize(ConfigurableTomcatWebServerFactory factory) { - ServerProperties.Tomcat properties = this.serverProperties.getTomcat(); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(properties::getBasedir).to(factory::setBaseDirectory); - map.from(properties::getBackgroundProcessorDelay) + map.from(this.tomcatProperties::getBasedir).to(factory::setBaseDirectory); + map.from(this.tomcatProperties::getBackgroundProcessorDelay) .as(Duration::getSeconds) .as(Long::intValue) .to(factory::setBackgroundProcessorDelay); customizeRemoteIpValve(factory); - ServerProperties.Tomcat.Threads threadProperties = properties.getThreads(); + TomcatServerProperties.Threads threadProperties = this.tomcatProperties.getThreads(); map.from(threadProperties::getMax) .when(this::isPositive) .to((maxThreads) -> customizeMaxThreads(factory, maxThreads)); @@ -108,51 +113,74 @@ public void customize(ConfigurableTomcatWebServerFactory factory) { .asInt(DataSize::toBytes) .when(this::isPositive) .to((maxHttpRequestHeaderSize) -> customizeMaxHttpRequestHeaderSize(factory, maxHttpRequestHeaderSize)); - map.from(properties::getMaxHttpResponseHeaderSize) + map.from(this.tomcatProperties::getMaxHttpResponseHeaderSize) .asInt(DataSize::toBytes) .when(this::isPositive) .to((maxHttpResponseHeaderSize) -> customizeMaxHttpResponseHeaderSize(factory, maxHttpResponseHeaderSize)); - map.from(properties::getMaxSwallowSize) + map.from(this.tomcatProperties::getMaxSwallowSize) .asInt(DataSize::toBytes) .to((maxSwallowSize) -> customizeMaxSwallowSize(factory, maxSwallowSize)); - map.from(properties::getMaxHttpFormPostSize) + map.from(this.tomcatProperties::getMaxHttpFormPostSize) .asInt(DataSize::toBytes) .when((maxHttpFormPostSize) -> maxHttpFormPostSize != 0) .to((maxHttpFormPostSize) -> customizeMaxHttpFormPostSize(factory, maxHttpFormPostSize)); - map.from(properties::getMaxParameterCount) + map.from(this.tomcatProperties::getMaxParameterCount) .to((maxParameterCount) -> customizeMaxParameterCount(factory, maxParameterCount)); - map.from(properties::getMaxPartHeaderSize) + map.from(this.tomcatProperties::getMaxPartHeaderSize) .asInt(DataSize::toBytes) .to((maxPartHeaderSize) -> customizeMaxPartHeaderSize(factory, maxPartHeaderSize)); - map.from(properties::getMaxPartCount).to((maxPartCount) -> customizeMaxPartCount(factory, maxPartCount)); - map.from(properties::getAccesslog) - .when(ServerProperties.Tomcat.Accesslog::isEnabled) + map.from(this.tomcatProperties::getMaxPartCount) + .to((maxPartCount) -> customizeMaxPartCount(factory, maxPartCount)); + map.from(this.tomcatProperties::getAccesslog) + .when(TomcatServerProperties.Accesslog::isEnabled) .to((enabled) -> customizeAccessLog(factory)); - map.from(properties::getUriEncoding).to(factory::setUriEncoding); - map.from(properties::getConnectionTimeout) + map.from(this.tomcatProperties::getUriEncoding).to(factory::setUriEncoding); + map.from(this.tomcatProperties::getConnectionTimeout) .to((connectionTimeout) -> customizeConnectionTimeout(factory, connectionTimeout)); - map.from(properties::getMaxConnections) + map.from(this.tomcatProperties::getMaxConnections) .when(this::isPositive) .to((maxConnections) -> customizeMaxConnections(factory, maxConnections)); - map.from(properties::getAcceptCount) + map.from(this.tomcatProperties::getAcceptCount) .when(this::isPositive) .to((acceptCount) -> customizeAcceptCount(factory, acceptCount)); - map.from(properties::getProcessorCache) + map.from(this.tomcatProperties::getProcessorCache) .to((processorCache) -> customizeProcessorCache(factory, processorCache)); - map.from(properties::getKeepAliveTimeout) + map.from(this.tomcatProperties::getKeepAliveTimeout) .to((keepAliveTimeout) -> customizeKeepAliveTimeout(factory, keepAliveTimeout)); - map.from(properties::getMaxKeepAliveRequests) + map.from(this.tomcatProperties::getMaxKeepAliveRequests) .to((maxKeepAliveRequests) -> customizeMaxKeepAliveRequests(factory, maxKeepAliveRequests)); - map.from(properties::getRelaxedPathChars) + map.from(this.tomcatProperties::getRelaxedPathChars) .as(this::joinCharacters) .whenHasText() .to((relaxedChars) -> customizeRelaxedPathChars(factory, relaxedChars)); - map.from(properties::getRelaxedQueryChars) + map.from(this.tomcatProperties::getRelaxedQueryChars) .as(this::joinCharacters) .whenHasText() .to((relaxedChars) -> customizeRelaxedQueryChars(factory, relaxedChars)); + map.from(this.tomcatProperties.getMbeanregistry()::isEnabled) + .as((enable) -> !enable) + .to(factory::setDisableMBeanRegistry); customizeStaticResources(factory); customizeErrorReportValve(this.serverProperties.getError(), factory); + factory.setUseApr(getUseApr(this.tomcatProperties.getUseApr())); + } + + private boolean getUseApr(UseApr useApr) { + return switch (useApr) { + case ALWAYS -> { + Assert.state(isAprAvailable(), "APR has been configured to 'ALWAYS', but it's not available"); + yield true; + } + case WHEN_AVAILABLE -> isAprAvailable(); + case NEVER -> false; + }; + } + + private boolean isAprAvailable() { + // At least one instance of AprLifecycleListener has to be created for + // isAprAvailable() to work + new AprLifecycleListener(); + return AprLifecycleListener.isAprAvailable(); } private boolean isPositive(int value) { @@ -228,7 +256,7 @@ private String joinCharacters(List content) { } private void customizeRemoteIpValve(ConfigurableTomcatWebServerFactory factory) { - Remoteip remoteIpProperties = this.serverProperties.getTomcat().getRemoteip(); + Remoteip remoteIpProperties = this.tomcatProperties.getRemoteip(); String protocolHeader = remoteIpProperties.getProtocolHeader(); String remoteIpHeader = remoteIpProperties.getRemoteIpHeader(); // For back compatibility the valve is also enabled if protocol-header is set @@ -325,10 +353,9 @@ private void customizeMaxPartHeaderSize(ConfigurableTomcatWebServerFactory facto } private void customizeAccessLog(ConfigurableTomcatWebServerFactory factory) { - ServerProperties.Tomcat tomcatProperties = this.serverProperties.getTomcat(); AccessLogValve valve = new AccessLogValve(); PropertyMapper map = PropertyMapper.get(); - Accesslog accessLogConfig = tomcatProperties.getAccesslog(); + Accesslog accessLogConfig = this.tomcatProperties.getAccesslog(); map.from(accessLogConfig.getConditionIf()).to(valve::setConditionIf); map.from(accessLogConfig.getConditionUnless()).to(valve::setConditionUnless); map.from(accessLogConfig.getPattern()).to(valve::setPattern); @@ -349,7 +376,7 @@ private void customizeAccessLog(ConfigurableTomcatWebServerFactory factory) { } private void customizeStaticResources(ConfigurableTomcatWebServerFactory factory) { - ServerProperties.Tomcat.Resource resource = this.serverProperties.getTomcat().getResource(); + TomcatServerProperties.Resource resource = this.tomcatProperties.getResource(); factory.addContextCustomizers((context) -> context.addLifecycleListener((event) -> { if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) { context.getResources().setCachingAllowed(resource.isAllowCaching()); diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/WebSocketTomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/WebSocketTomcatWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..4c54c9b2bdd5 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/WebSocketTomcatWebServerFactoryCustomizer.java @@ -0,0 +1,38 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure; + +import org.apache.tomcat.websocket.server.WsSci; + +import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; + +/** + * {@link WebServerFactoryCustomizer} that configures Tomcat's WebSocket support. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class WebSocketTomcatWebServerFactoryCustomizer + implements WebServerFactoryCustomizer { + + @Override + public void customize(ConfigurableTomcatWebServerFactory factory) { + factory.addContextCustomizers((context) -> context.addServletContainerInitializer(new WsSci(), null)); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatAccessLogCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatAccessLogCustomizer.java new file mode 100644 index 000000000000..99bf1cc432bc --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatAccessLogCustomizer.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.actuate.web; + +import java.util.Collection; +import java.util.function.Function; + +import org.apache.catalina.Valve; +import org.apache.catalina.valves.AccessLogValve; + +import org.springframework.boot.actuate.autoconfigure.web.server.AccessLogCustomizer; +import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory; + +/** + * {@link AccessLogCustomizer} for Tomcat. + * + * @param the type of factory that can be customized + * @author Andy Wilkinson + */ +class TomcatAccessLogCustomizer extends AccessLogCustomizer { + + private final Function> engineValvesExtractor; + + TomcatAccessLogCustomizer(TomcatManagementServerProperties properties, + Function> engineValvesExtractor) { + super(properties.getAccesslog().getPrefix()); + this.engineValvesExtractor = engineValvesExtractor; + } + + @Override + public void customize(T factory) { + AccessLogValve accessLogValve = findAccessLogValve(factory); + if (accessLogValve == null) { + return; + } + accessLogValve.setPrefix(customizePrefix(accessLogValve.getPrefix())); + } + + private AccessLogValve findAccessLogValve(T factory) { + for (Valve engineValve : this.engineValvesExtractor.apply(factory)) { + if (engineValve instanceof AccessLogValve accessLogValve) { + return accessLogValve; + } + } + return null; + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatManagementServerProperties.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatManagementServerProperties.java new file mode 100644 index 000000000000..c8f1342b58ab --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatManagementServerProperties.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.actuate.web; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Properties for a Tomcat-based management server. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +@ConfigurationProperties("management.server.tomcat") +public class TomcatManagementServerProperties { + + private final Accesslog accesslog = new Accesslog(); + + public Accesslog getAccesslog() { + return this.accesslog; + } + + public static class Accesslog { + + /** + * Management log file name prefix. + */ + private String prefix = "management_"; + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatReactiveManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatReactiveManagementChildContextConfiguration.java new file mode 100644 index 000000000000..c5220591e742 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatReactiveManagementChildContextConfiguration.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.actuate.web; + +import org.apache.catalina.startup.Tomcat; + +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Tomcat-based + * reactive web endpoint infrastructure when a separate management context running on a + * different port is required. + * + * @author Andy Wilkinson + */ +@ConditionalOnClass(Tomcat.class) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@EnableConfigurationProperties(TomcatManagementServerProperties.class) +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +class TomcatReactiveManagementChildContextConfiguration { + + @Bean + TomcatAccessLogCustomizer tomcatManagementAccessLogCustomizer( + TomcatManagementServerProperties properties) { + return new TomcatAccessLogCustomizer<>(properties, TomcatReactiveWebServerFactory::getEngineValves); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatReactiveManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatReactiveManagementContextAutoConfiguration.java new file mode 100644 index 000000000000..2492f9f60dbd --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatReactiveManagementContextAutoConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.actuate.web; + +import org.apache.catalina.startup.Tomcat; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.tomcat.autoconfigure.TomcatWebServerConfiguration; +import org.springframework.boot.tomcat.autoconfigure.reactive.TomcatReactiveWebServerAutoConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * Auto-configuration for a Tomcat-based reactive management context. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ Tomcat.class, ManagementContextFactory.class }) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) +public class TomcatReactiveManagementContextAutoConfiguration { + + @Bean + static ManagementContextFactory reactiveWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, + TomcatReactiveWebServerAutoConfiguration.class, TomcatWebServerConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatServletManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatServletManagementChildContextConfiguration.java new file mode 100644 index 000000000000..f4fc52a6b4ba --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatServletManagementChildContextConfiguration.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.actuate.web; + +import org.apache.catalina.startup.Tomcat; + +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for Tomcat-based + * servlet web endpoint infrastructure when a separate management context running on a + * different port is required. + * + * @author Andy Wilkinson + */ +@ConditionalOnClass(Tomcat.class) +@ConditionalOnWebApplication(type = Type.SERVLET) +@EnableConfigurationProperties(TomcatManagementServerProperties.class) +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +class TomcatServletManagementChildContextConfiguration { + + @Bean + TomcatAccessLogCustomizer tomcatManagementAccessLogCustomizer( + TomcatManagementServerProperties properties) { + return new TomcatAccessLogCustomizer<>(properties, TomcatServletWebServerFactory::getEngineValves); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatServletManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatServletManagementContextAutoConfiguration.java new file mode 100644 index 000000000000..b5a1a26c0073 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatServletManagementContextAutoConfiguration.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.actuate.web; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.tomcat.autoconfigure.TomcatWebServerConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * Auto-configuration for a Tomcat-based servlet management context. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass(ManagementContextFactory.class) +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) +public class TomcatServletManagementContextAutoConfiguration { + + @Bean + static ManagementContextFactory servletWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.SERVLET, ServletWebServerFactory.class, + TomcatWebServerConfiguration.class, TomcatServletWebServerAutoConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/package-info.java new file mode 100644 index 000000000000..5d47ac2f0b47 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Tomcat actuator web concerns. + */ +package org.springframework.boot.tomcat.autoconfigure.actuate.web; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfiguration.java index 86efeba8cb1d..7c81ab9bb542 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfiguration.java @@ -14,31 +14,30 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat; +package org.springframework.boot.tomcat.autoconfigure.metrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics; import org.apache.catalina.Manager; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.metrics.web.tomcat.TomcatMetricsBinder; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.tomcat.metrics.TomcatMetricsBinder; import org.springframework.context.annotation.Bean; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link TomcatMetrics}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = CompositeMeterRegistryAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration") @ConditionalOnWebApplication -@ConditionalOnClass({ TomcatMetrics.class, Manager.class }) +@ConditionalOnClass({ TomcatMetrics.class, Manager.class, MeterRegistry.class }) public class TomcatMetricsAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/metrics/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/metrics/package-info.java new file mode 100644 index 000000000000..bbb1e26a4b02 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Tomcat metrics. + */ +package org.springframework.boot.tomcat.autoconfigure.metrics; diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/package-info.java new file mode 100644 index 000000000000..5aebe432ce01 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a servlet or reactive web server using + * Tomcat. + */ +package org.springframework.boot.tomcat.autoconfigure; diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfiguration.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfiguration.java new file mode 100644 index 000000000000..4224a9844f32 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfiguration.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.reactive; + +import org.apache.catalina.startup.Tomcat; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.tomcat.TomcatContextCustomizer; +import org.springframework.boot.tomcat.TomcatProtocolHandlerCustomizer; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties; +import org.springframework.boot.tomcat.autoconfigure.TomcatWebServerConfiguration; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; +import org.springframework.boot.web.server.autoconfigure.reactive.ReactiveWebServerConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.http.ReactiveHttpInputMessage; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for a Tomcat-based reactive web + * server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ReactiveHttpInputMessage.class, Tomcat.class, TomcatReactiveWebServerFactory.class }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +@EnableConfigurationProperties(TomcatServerProperties.class) +@Import({ TomcatWebServerConfiguration.class, ReactiveWebServerConfiguration.class }) +public class TomcatReactiveWebServerAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(ReactiveWebServerFactory.class) + TomcatReactiveWebServerFactory tomcatReactiveWebServerFactory( + ObjectProvider connectorCustomizers, + ObjectProvider contextCustomizers, + ObjectProvider> protocolHandlerCustomizers) { + TomcatReactiveWebServerFactory factory = new TomcatReactiveWebServerFactory(); + factory.getConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList()); + factory.getContextCustomizers().addAll(contextCustomizers.orderedStream().toList()); + factory.getProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList()); + return factory; + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..101d3d538c2e --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a reactive web server using Tomcat. + */ +package org.springframework.boot.tomcat.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerAutoConfiguration.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerAutoConfiguration.java new file mode 100644 index 000000000000..23064bf5ab09 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerAutoConfiguration.java @@ -0,0 +1,91 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.servlet; + +import jakarta.servlet.ServletRequest; +import org.apache.catalina.startup.Tomcat; +import org.apache.coyote.UpgradeProtocol; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.autoconfigure.condition.SearchStrategy; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.tomcat.TomcatContextCustomizer; +import org.springframework.boot.tomcat.TomcatProtocolHandlerCustomizer; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties; +import org.springframework.boot.tomcat.autoconfigure.TomcatWebServerConfiguration; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.servlet.ForwardedHeaderFilterCustomizer; +import org.springframework.boot.web.server.autoconfigure.servlet.ServletWebServerConfiguration; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for a Tomcat-based servlet web + * server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ServletRequest.class, Tomcat.class, UpgradeProtocol.class, TomcatServletWebServerFactory.class }) +@ConditionalOnWebApplication(type = Type.SERVLET) +@EnableConfigurationProperties(TomcatServerProperties.class) +@Import({ ServletWebServerConfiguration.class, TomcatWebServerConfiguration.class }) +public class TomcatServletWebServerAutoConfiguration { + + private final TomcatServerProperties tomcatProperties; + + public TomcatServletWebServerAutoConfiguration(TomcatServerProperties tomcatProperties) { + this.tomcatProperties = tomcatProperties; + } + + @Bean + @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT) + TomcatServletWebServerFactory tomcatServletWebServerFactory( + ObjectProvider connectorCustomizers, + ObjectProvider contextCustomizers, + ObjectProvider> protocolHandlerCustomizers) { + TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); + factory.getConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList()); + factory.getContextCustomizers().addAll(contextCustomizers.orderedStream().toList()); + factory.getProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList()); + return factory; + } + + @Bean + TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer( + TomcatServerProperties tomcatProperties) { + return new TomcatServletWebServerFactoryCustomizer(tomcatProperties); + } + + @Bean + @ConditionalOnProperty(name = "server.forward-headers-strategy", havingValue = "framework") + ForwardedHeaderFilterCustomizer tomcatForwardedHeaderFilterCustomizer(ServerProperties serverProperties) { + return (filter) -> filter.setRelativeRedirects(this.tomcatProperties.isUseRelativeRedirects()); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..7af0d96e6d36 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerFactoryCustomizer.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.servlet; + +import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.core.Ordered; +import org.springframework.util.ObjectUtils; + +/** + * {@link WebServerFactoryCustomizer} to apply {@link TomcatServerProperties} to Tomcat + * web servers. + * + * @author Brian Clozel + * @author Phillip Webb + */ +class TomcatServletWebServerFactoryCustomizer + implements WebServerFactoryCustomizer, Ordered { + + private final TomcatServerProperties tomcatProperties; + + TomcatServletWebServerFactoryCustomizer(TomcatServerProperties tomcatProperties) { + this.tomcatProperties = tomcatProperties; + } + + @Override + public int getOrder() { + return 0; + } + + @Override + public void customize(TomcatServletWebServerFactory factory) { + if (!ObjectUtils.isEmpty(this.tomcatProperties.getAdditionalTldSkipPatterns())) { + factory.getTldSkipPatterns().addAll(this.tomcatProperties.getAdditionalTldSkipPatterns()); + } + if (this.tomcatProperties.getRedirectContextRoot() != null) { + customizeRedirectContextRoot(factory, this.tomcatProperties.getRedirectContextRoot()); + } + customizeUseRelativeRedirects(factory, this.tomcatProperties.isUseRelativeRedirects()); + } + + private void customizeRedirectContextRoot(ConfigurableTomcatWebServerFactory factory, boolean redirectContextRoot) { + factory.addContextCustomizers((context) -> context.setMapperContextRootRedirectEnabled(redirectContextRoot)); + } + + private void customizeUseRelativeRedirects(ConfigurableTomcatWebServerFactory factory, + boolean useRelativeRedirects) { + factory.addContextCustomizers((context) -> context.setUseRelativeRedirects(useRelativeRedirects)); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..a43d3e597f56 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a servlet web server using Tomcat. + */ +package org.springframework.boot.tomcat.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/metrics/TomcatMetricsBinder.java similarity index 93% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/metrics/TomcatMetricsBinder.java index 1029300e1ff5..f9a51d0883ff 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/metrics/TomcatMetricsBinder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.tomcat; +package org.springframework.boot.tomcat.metrics; import java.util.Collections; @@ -27,9 +27,9 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.boot.context.event.ApplicationStartedEvent; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.TomcatWebServer; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; @@ -37,7 +37,7 @@ * Binds {@link TomcatMetrics} in response to the {@link ApplicationStartedEvent}. * * @author Andy Wilkinson - * @since 2.1.0 + * @since 4.0.0 */ public class TomcatMetricsBinder implements ApplicationListener, DisposableBean { diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/metrics/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/metrics/package-info.java new file mode 100644 index 000000000000..3282bf36bd85 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/metrics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Tomcat metrics. + */ +package org.springframework.boot.tomcat.metrics; diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/package-info.java new file mode 100644 index 000000000000..87e9664dd00e --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive and servlet web server implementations backed by Tomcat. + * + * @see org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory + * @see org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory + */ +package org.springframework.boot.tomcat; diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactory.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactory.java new file mode 100644 index 000000000000..0d52aa95c498 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactory.java @@ -0,0 +1,134 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.reactive; + +import java.io.File; + +import org.apache.catalina.Context; +import org.apache.catalina.Host; +import org.apache.catalina.WebResourceRoot; +import org.apache.catalina.loader.WebappLoader; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.webresources.StandardRoot; +import org.apache.tomcat.util.scan.StandardJarScanFilter; + +import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory; +import org.springframework.boot.tomcat.DisableReferenceClearingContextCustomizer; +import org.springframework.boot.tomcat.TomcatEmbeddedContext; +import org.springframework.boot.tomcat.TomcatEmbeddedWebappClassLoader; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.TomcatWebServerFactory; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.http.server.reactive.TomcatHttpHandlerAdapter; +import org.springframework.util.ClassUtils; + +/** + * {@link ReactiveWebServerFactory} that can be used to create a {@link TomcatWebServer}. + * + * @author Brian Clozel + * @author HaiTao Zhang + * @author Moritz Halbritter + * @author Scott Frederick + * @since 4.0.0 + */ +public class TomcatReactiveWebServerFactory extends TomcatWebServerFactory + implements ConfigurableTomcatWebServerFactory, ConfigurableReactiveWebServerFactory { + + /** + * Create a new {@link TomcatReactiveWebServerFactory} instance. + */ + public TomcatReactiveWebServerFactory() { + } + + /** + * Create a new {@link TomcatReactiveWebServerFactory} that listens for requests using + * the specified port. + * @param port the port to listen on + */ + public TomcatReactiveWebServerFactory(int port) { + super(port); + } + + @Override + public WebServer getWebServer(HttpHandler httpHandler) { + Tomcat tomcat = createTomcat(); + TomcatHttpHandlerAdapter servlet = new TomcatHttpHandlerAdapter(httpHandler); + prepareContext(tomcat.getHost(), servlet); + return getTomcatWebServer(tomcat); + } + + protected void prepareContext(Host host, TomcatHttpHandlerAdapter servlet) { + File docBase = createTempDir("tomcat-docbase"); + TomcatEmbeddedContext context = new TomcatEmbeddedContext(); + WebResourceRoot resourceRoot = new StandardRoot(context); + ignoringNoSuchMethodError(() -> resourceRoot.setReadOnly(true)); + context.setResources(resourceRoot); + context.setPath(""); + context.setDocBase(docBase.getAbsolutePath()); + context.addLifecycleListener(new Tomcat.FixContextListener()); + ClassLoader parentClassLoader = ClassUtils.getDefaultClassLoader(); + context.setParentClassLoader(parentClassLoader); + skipAllTldScanning(context); + WebappLoader loader = new WebappLoader(); + loader.setLoaderInstance(new TomcatEmbeddedWebappClassLoader(parentClassLoader)); + loader.setDelegate(true); + context.setLoader(loader); + Tomcat.addServlet(context, "httpHandlerServlet", servlet).setAsyncSupported(true); + context.addServletMappingDecoded("/", "httpHandlerServlet"); + host.addChild(context); + configureContext(context); + } + + private void ignoringNoSuchMethodError(Runnable method) { + try { + method.run(); + } + catch (NoSuchMethodError ex) { + } + } + + private void skipAllTldScanning(TomcatEmbeddedContext context) { + StandardJarScanFilter filter = new StandardJarScanFilter(); + filter.setTldSkip("*.jar"); + context.getJarScanner().setJarScanFilter(filter); + } + + /** + * Configure the Tomcat {@link Context}. + * @param context the Tomcat context + */ + protected void configureContext(Context context) { + this.getContextLifecycleListeners().forEach(context::addLifecycleListener); + new DisableReferenceClearingContextCustomizer().customize(context); + this.getContextCustomizers().forEach((customizer) -> customizer.customize(context)); + } + + /** + * Factory method called to create the {@link TomcatWebServer}. Subclasses can + * override this method to return a different {@link TomcatWebServer} or apply + * additional processing to the Tomcat server. + * @param tomcat the Tomcat server. + * @return a new {@link TomcatWebServer} instance + */ + protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { + return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown()); + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/reactive/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/reactive/package-info.java new file mode 100644 index 000000000000..2abc50624f6f --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive web server implementation backed by Tomcat. + */ +package org.springframework.boot.tomcat.reactive; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/NestedJarResourceSet.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/NestedJarResourceSet.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/NestedJarResourceSet.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/NestedJarResourceSet.java index 75864f80b505..cb937d487859 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/NestedJarResourceSet.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/NestedJarResourceSet.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat.servlet; import java.io.IOException; import java.net.JarURLConnection; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/TldPatterns.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java rename to spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/TldPatterns.java index 4eb9887dbcfa..b992bbdc6399 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/TldPatterns.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat.servlet; import java.util.Collections; import java.util.LinkedHashSet; diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactory.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactory.java new file mode 100644 index 000000000000..180a5fad184b --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactory.java @@ -0,0 +1,683 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.servlet; + +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.stream.Collectors; + +import jakarta.servlet.ServletContainerInitializer; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import org.apache.catalina.Context; +import org.apache.catalina.Host; +import org.apache.catalina.Lifecycle; +import org.apache.catalina.LifecycleEvent; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.LifecycleListener; +import org.apache.catalina.Manager; +import org.apache.catalina.Valve; +import org.apache.catalina.WebResource; +import org.apache.catalina.WebResourceRoot; +import org.apache.catalina.WebResourceRoot.ResourceSetType; +import org.apache.catalina.WebResourceSet; +import org.apache.catalina.Wrapper; +import org.apache.catalina.loader.WebappLoader; +import org.apache.catalina.session.StandardManager; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.Tomcat.FixContextListener; +import org.apache.catalina.util.LifecycleBase; +import org.apache.catalina.util.SessionConfig; +import org.apache.catalina.webresources.AbstractResourceSet; +import org.apache.catalina.webresources.EmptyResource; +import org.apache.catalina.webresources.StandardRoot; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tomcat.util.http.Rfc6265CookieProcessor; +import org.apache.tomcat.util.scan.StandardJarScanFilter; + +import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory; +import org.springframework.boot.tomcat.DisableReferenceClearingContextCustomizer; +import org.springframework.boot.tomcat.TomcatContextCustomizer; +import org.springframework.boot.tomcat.TomcatEmbeddedContext; +import org.springframework.boot.tomcat.TomcatEmbeddedWebappClassLoader; +import org.springframework.boot.tomcat.TomcatStarter; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.TomcatWebServerFactory; +import org.springframework.boot.web.error.ErrorPage; +import org.springframework.boot.web.server.Cookie.SameSite; +import org.springframework.boot.web.server.MimeMappings; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ContextPath; +import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier; +import org.springframework.boot.web.server.servlet.DocumentRoot; +import org.springframework.boot.web.server.servlet.ServletContextInitializers; +import org.springframework.boot.web.server.servlet.ServletWebServerSettings; +import org.springframework.boot.web.servlet.ServletContextInitializer; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; + +/** + * {@link ConfigurableServletWebServerFactory} that can be used to create + * {@link TomcatWebServer}s. Can be initialized using Spring's + * {@link ServletContextInitializer}s or Tomcat {@link LifecycleListener}s. + *

    + * Unless explicitly configured otherwise this factory will create containers that listen + * for HTTP requests on port 8080. + * + * @author Phillip Webb + * @author Dave Syer + * @author Brock Mills + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Eddú Meléndez + * @author Christoffer Sawicki + * @author Dawid Antecki + * @author Moritz Halbritter + * @author Scott Frederick + * @since 4.0.0 + * @see #setPort(int) + * @see #setContextLifecycleListeners(Collection) + * @see TomcatWebServer + */ +public class TomcatServletWebServerFactory extends TomcatWebServerFactory + implements ConfigurableTomcatWebServerFactory, ConfigurableServletWebServerFactory, ResourceLoaderAware { + + private static final Log logger = LogFactory.getLog(TomcatServletWebServerFactory.class); + + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + + private static final Set> NO_CLASSES = Collections.emptySet(); + + private final ServletWebServerSettings settings = new ServletWebServerSettings(); + + private ResourceLoader resourceLoader; + + private Set tldSkipPatterns = new LinkedHashSet<>(TldPatterns.DEFAULT_SKIP); + + private final Set tldScanPatterns = new LinkedHashSet<>(TldPatterns.DEFAULT_SCAN); + + /** + * Create a new {@link TomcatServletWebServerFactory} instance. + */ + public TomcatServletWebServerFactory() { + } + + /** + * Create a new {@link TomcatServletWebServerFactory} that listens for requests using + * the specified port. + * @param port the port to listen on + */ + public TomcatServletWebServerFactory(int port) { + super(port); + } + + /** + * Create a new {@link TomcatServletWebServerFactory} with the specified context path + * and port. + * @param contextPath the root context path + * @param port the port to listen on + */ + public TomcatServletWebServerFactory(String contextPath, int port) { + super(port); + this.settings.setContextPath(ContextPath.of(contextPath)); + } + + @Override + public WebServer getWebServer(ServletContextInitializer... initializers) { + Tomcat tomcat = createTomcat(); + prepareContext(tomcat.getHost(), initializers); + return getTomcatWebServer(tomcat); + } + + protected void prepareContext(Host host, ServletContextInitializer[] initializers) { + DocumentRoot documentRoot = new DocumentRoot(logger); + documentRoot.setDirectory(this.settings.getDocumentRoot()); + File documentRootFile = documentRoot.getValidDirectory(); + TomcatEmbeddedContext context = new TomcatEmbeddedContext(); + WebResourceRoot resourceRoot = (documentRootFile != null) ? new LoaderHidingResourceRoot(context) + : new StandardRoot(context); + ignoringNoSuchMethodError(() -> resourceRoot.setReadOnly(true)); + context.setResources(resourceRoot); + String contextPath = this.settings.getContextPath().toString(); + context.setName(contextPath); + context.setDisplayName(this.settings.getDisplayName()); + context.setPath(contextPath); + File docBase = (documentRootFile != null) ? documentRootFile : createTempDir("tomcat-docbase"); + context.setDocBase(docBase.getAbsolutePath()); + context.addLifecycleListener(new FixContextListener()); + ClassLoader parentClassLoader = (this.resourceLoader != null) ? this.resourceLoader.getClassLoader() + : ClassUtils.getDefaultClassLoader(); + context.setParentClassLoader(parentClassLoader); + resetDefaultLocaleMapping(context); + addLocaleMappings(context); + context.setCreateUploadTargets(true); + configureTldPatterns(context); + WebappLoader loader = new WebappLoader(); + loader.setLoaderInstance(new TomcatEmbeddedWebappClassLoader(parentClassLoader)); + loader.setDelegate(true); + context.setLoader(loader); + if (this.settings.isRegisterDefaultServlet()) { + addDefaultServlet(context); + } + if (shouldRegisterJspServlet()) { + addJspServlet(context); + addJasperInitializer(context); + } + context.addLifecycleListener(new StaticResourceConfigurer(context)); + ServletContextInitializers initializersToUse = ServletContextInitializers.from(this.settings, initializers); + host.addChild(context); + configureContext(context, initializersToUse); + postProcessContext(context); + } + + private void ignoringNoSuchMethodError(Runnable method) { + try { + method.run(); + } + catch (NoSuchMethodError ex) { + } + } + + private boolean shouldRegisterJspServlet() { + return this.settings.getJsp() != null && this.settings.getJsp().getRegistered() + && ClassUtils.isPresent(this.settings.getJsp().getClassName(), getClass().getClassLoader()); + } + + /** + * Override Tomcat's default locale mappings to align with other servers. See + * {@code org.apache.catalina.util.CharsetMapperDefault.properties}. + * @param context the context to reset + */ + private void resetDefaultLocaleMapping(TomcatEmbeddedContext context) { + context.addLocaleEncodingMappingParameter(Locale.ENGLISH.toString(), DEFAULT_CHARSET.displayName()); + context.addLocaleEncodingMappingParameter(Locale.FRENCH.toString(), DEFAULT_CHARSET.displayName()); + context.addLocaleEncodingMappingParameter(Locale.JAPANESE.toString(), DEFAULT_CHARSET.displayName()); + } + + private void addLocaleMappings(TomcatEmbeddedContext context) { + this.settings.getLocaleCharsetMappings() + .forEach((locale, charset) -> context.addLocaleEncodingMappingParameter(locale.toString(), + charset.toString())); + } + + private void configureTldPatterns(TomcatEmbeddedContext context) { + StandardJarScanFilter filter = new StandardJarScanFilter(); + filter.setTldSkip(StringUtils.collectionToCommaDelimitedString(this.tldSkipPatterns)); + filter.setTldScan(StringUtils.collectionToCommaDelimitedString(this.tldScanPatterns)); + context.getJarScanner().setJarScanFilter(filter); + } + + private void addDefaultServlet(Context context) { + Wrapper defaultServlet = context.createWrapper(); + defaultServlet.setName("default"); + defaultServlet.setServletClass("org.apache.catalina.servlets.DefaultServlet"); + defaultServlet.addInitParameter("debug", "0"); + defaultServlet.addInitParameter("listings", "false"); + defaultServlet.setLoadOnStartup(1); + // Otherwise the default location of a Spring DispatcherServlet cannot be set + defaultServlet.setOverridable(true); + context.addChild(defaultServlet); + context.addServletMappingDecoded("/", "default"); + } + + private void addJspServlet(Context context) { + Wrapper jspServlet = context.createWrapper(); + jspServlet.setName("jsp"); + jspServlet.setServletClass(this.settings.getJsp().getClassName()); + jspServlet.addInitParameter("fork", "false"); + this.settings.getJsp().getInitParameters().forEach(jspServlet::addInitParameter); + jspServlet.setLoadOnStartup(3); + context.addChild(jspServlet); + context.addServletMappingDecoded("*.jsp", "jsp"); + context.addServletMappingDecoded("*.jspx", "jsp"); + } + + private void addJasperInitializer(TomcatEmbeddedContext context) { + try { + ServletContainerInitializer initializer = (ServletContainerInitializer) ClassUtils + .forName("org.apache.jasper.servlet.JasperInitializer", null) + .getDeclaredConstructor() + .newInstance(); + context.addServletContainerInitializer(initializer, null); + } + catch (Exception ex) { + // Probably not Tomcat 8 + } + } + + /** + * Configure the Tomcat {@link Context}. + * @param context the Tomcat context + * @param initializers initializers to apply + */ + protected void configureContext(Context context, Iterable initializers) { + TomcatStarter starter = new TomcatStarter(initializers); + if (context instanceof TomcatEmbeddedContext embeddedContext) { + embeddedContext.setStarter(starter); + embeddedContext.setFailCtxIfServletStartFails(true); + } + context.addServletContainerInitializer(starter, NO_CLASSES); + for (LifecycleListener lifecycleListener : this.getContextLifecycleListeners()) { + context.addLifecycleListener(lifecycleListener); + } + for (Valve valve : this.getContextValves()) { + context.getPipeline().addValve(valve); + } + for (ErrorPage errorPage : getErrorPages()) { + org.apache.tomcat.util.descriptor.web.ErrorPage tomcatErrorPage = new org.apache.tomcat.util.descriptor.web.ErrorPage(); + tomcatErrorPage.setLocation(errorPage.getPath()); + tomcatErrorPage.setErrorCode(errorPage.getStatusCode()); + tomcatErrorPage.setExceptionType(errorPage.getExceptionName()); + context.addErrorPage(tomcatErrorPage); + } + setMimeMappings(context); + configureSession(context); + configureCookieProcessor(context); + new DisableReferenceClearingContextCustomizer().customize(context); + for (String webListenerClassName : getSettings().getWebListenerClassNames()) { + context.addApplicationListener(webListenerClassName); + } + for (TomcatContextCustomizer customizer : this.getContextCustomizers()) { + customizer.customize(context); + } + } + + private void configureSession(Context context) { + long sessionTimeout = getSessionTimeoutInMinutes(); + context.setSessionTimeout((int) sessionTimeout); + Boolean httpOnly = this.settings.getSession().getCookie().getHttpOnly(); + if (httpOnly != null) { + context.setUseHttpOnly(httpOnly); + } + if (this.settings.getSession().isPersistent()) { + Manager manager = context.getManager(); + if (manager == null) { + manager = new StandardManager(); + context.setManager(manager); + } + configurePersistSession(manager); + } + else { + context.addLifecycleListener(new DisablePersistSessionListener()); + } + } + + private void setMimeMappings(Context context) { + MimeMappings mimeMappings = this.settings.getMimeMappings(); + if (context instanceof TomcatEmbeddedContext embeddedContext) { + embeddedContext.setMimeMappings(mimeMappings); + return; + } + for (MimeMappings.Mapping mapping : mimeMappings) { + context.addMimeMapping(mapping.getExtension(), mapping.getMimeType()); + } + } + + private void configureCookieProcessor(Context context) { + SameSite sessionSameSite = this.settings.getSession().getCookie().getSameSite(); + List suppliers = new ArrayList<>(); + if (sessionSameSite != null) { + suppliers.add(CookieSameSiteSupplier.of(sessionSameSite) + .whenHasName(() -> SessionConfig.getSessionCookieName(context))); + } + if (!CollectionUtils.isEmpty(this.settings.getCookieSameSiteSuppliers())) { + suppliers.addAll(this.settings.getCookieSameSiteSuppliers()); + } + if (!suppliers.isEmpty()) { + context.setCookieProcessor(new SuppliedSameSiteCookieProcessor(suppliers)); + } + } + + private void configurePersistSession(Manager manager) { + Assert.state(manager instanceof StandardManager, + () -> "Unable to persist HTTP session state using manager type " + manager.getClass().getName()); + File dir = this.settings.getSession().getSessionStoreDirectory().getValidDirectory(true); + File file = new File(dir, "SESSIONS.ser"); + ((StandardManager) manager).setPathname(file.getAbsolutePath()); + } + + private long getSessionTimeoutInMinutes() { + Duration sessionTimeout = this.settings.getSession().getTimeout(); + if (isZeroOrLess(sessionTimeout)) { + return 0; + } + return Math.max(sessionTimeout.toMinutes(), 1); + } + + private boolean isZeroOrLess(Duration sessionTimeout) { + return sessionTimeout == null || sessionTimeout.isNegative() || sessionTimeout.isZero(); + } + + /** + * Post process the Tomcat {@link Context} before it's used with the Tomcat Server. + * Subclasses can override this method to apply additional processing to the + * {@link Context}. + * @param context the Tomcat {@link Context} + */ + protected void postProcessContext(Context context) { + } + + /** + * Factory method called to create the {@link TomcatWebServer}. Subclasses can + * override this method to return a different {@link TomcatWebServer} or apply + * additional processing to the Tomcat server. + * @param tomcat the Tomcat server. + * @return a new {@link TomcatWebServer} instance + */ + protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { + return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown()); + } + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + /** + * Returns a mutable set of the patterns that match jars to ignore for TLD scanning. + * @return the set of jars to ignore for TLD scanning + */ + public Set getTldSkipPatterns() { + return this.tldSkipPatterns; + } + + /** + * Set the patterns that match jars to ignore for TLD scanning. See Tomcat's + * catalina.properties for typical values. Defaults to a list drawn from that source. + * @param patterns the jar patterns to skip when scanning for TLDs etc + */ + public void setTldSkipPatterns(Collection patterns) { + Assert.notNull(patterns, "'patterns' must not be null"); + this.tldSkipPatterns = new LinkedHashSet<>(patterns); + } + + /** + * Add patterns that match jars to ignore for TLD scanning. See Tomcat's + * catalina.properties for typical values. + * @param patterns the additional jar patterns to skip when scanning for TLDs etc + */ + public void addTldSkipPatterns(String... patterns) { + Assert.notNull(patterns, "'patterns' must not be null"); + this.tldSkipPatterns.addAll(Arrays.asList(patterns)); + } + + @Override + public ServletWebServerSettings getSettings() { + return this.settings; + } + + /** + * {@link LifecycleListener} to disable persistence in the {@link StandardManager}. A + * {@link LifecycleListener} is used so not to interfere with Tomcat's default manager + * creation logic. + */ + private static final class DisablePersistSessionListener implements LifecycleListener { + + @Override + public void lifecycleEvent(LifecycleEvent event) { + if (event.getType().equals(Lifecycle.START_EVENT)) { + Context context = (Context) event.getLifecycle(); + Manager manager = context.getManager(); + if (manager instanceof StandardManager standardManager) { + standardManager.setPathname(null); + } + } + } + + } + + private final class StaticResourceConfigurer implements LifecycleListener { + + private static final String WEB_APP_MOUNT = "/"; + + private static final String INTERNAL_PATH = "/META-INF/resources"; + + private final Context context; + + private StaticResourceConfigurer(Context context) { + this.context = context; + } + + @Override + public void lifecycleEvent(LifecycleEvent event) { + if (event.getType().equals(Lifecycle.BEFORE_INIT_EVENT)) { + addResourceJars(TomcatServletWebServerFactory.this.getSettings().getStaticResourceUrls()); + } + } + + private void addResourceJars(List resourceJarUrls) { + for (URL url : resourceJarUrls) { + String path = url.getPath(); + if (path.endsWith(".jar") || path.endsWith(".jar!/")) { + String jar = url.toString(); + if (!jar.startsWith("jar:")) { + // A jar file in the file system. Convert to Jar URL. + jar = "jar:" + jar + "!/"; + } + addResourceSet(jar); + } + else { + addResourceSet(url.toString()); + } + } + for (WebResourceSet resources : this.context.getResources().getJarResources()) { + resources.setReadOnly(true); + } + } + + private void addResourceSet(String resource) { + try { + if (isInsideClassicNestedJar(resource)) { + addClassicNestedResourceSet(resource); + return; + } + WebResourceRoot root = this.context.getResources(); + URL url = new URL(resource); + if (isInsideNestedJar(resource)) { + root.addJarResources(new NestedJarResourceSet(url, root, WEB_APP_MOUNT, INTERNAL_PATH)); + } + else { + root.createWebResourceSet(ResourceSetType.RESOURCE_JAR, WEB_APP_MOUNT, url, INTERNAL_PATH); + } + } + catch (Exception ex) { + // Ignore (probably not a directory) + } + } + + private void addClassicNestedResourceSet(String resource) throws MalformedURLException { + // It's a nested jar but we now don't want the suffix because Tomcat + // is going to try and locate it as a root URL (not the resource + // inside it) + URL url = new URL(resource.substring(0, resource.length() - 2)); + this.context.getResources() + .createWebResourceSet(ResourceSetType.RESOURCE_JAR, WEB_APP_MOUNT, url, INTERNAL_PATH); + } + + private boolean isInsideClassicNestedJar(String resource) { + return !isInsideNestedJar(resource) && resource.indexOf("!/") < resource.lastIndexOf("!/"); + } + + private boolean isInsideNestedJar(String resource) { + return resource.startsWith("jar:nested:"); + } + + } + + private static final class LoaderHidingResourceRoot extends StandardRoot { + + private LoaderHidingResourceRoot(TomcatEmbeddedContext context) { + super(context); + } + + @Override + protected WebResourceSet createMainResourceSet() { + return new LoaderHidingWebResourceSet(super.createMainResourceSet()); + } + + } + + private static final class LoaderHidingWebResourceSet extends AbstractResourceSet { + + private final WebResourceSet delegate; + + private final Method initInternal; + + private LoaderHidingWebResourceSet(WebResourceSet delegate) { + this.delegate = delegate; + try { + this.initInternal = LifecycleBase.class.getDeclaredMethod("initInternal"); + this.initInternal.setAccessible(true); + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + @Override + public WebResource getResource(String path) { + if (path.startsWith("/org/springframework/boot")) { + return new EmptyResource(getRoot(), path); + } + return this.delegate.getResource(path); + } + + @Override + public String[] list(String path) { + return this.delegate.list(path); + } + + @Override + public Set listWebAppPaths(String path) { + return this.delegate.listWebAppPaths(path) + .stream() + .filter((webAppPath) -> !webAppPath.startsWith("/org/springframework/boot")) + .collect(Collectors.toSet()); + } + + @Override + public boolean mkdir(String path) { + return this.delegate.mkdir(path); + } + + @Override + public boolean write(String path, InputStream is, boolean overwrite) { + return this.delegate.write(path, is, overwrite); + } + + @Override + public URL getBaseUrl() { + return this.delegate.getBaseUrl(); + } + + @Override + public void setReadOnly(boolean readOnly) { + this.delegate.setReadOnly(readOnly); + } + + @Override + public boolean isReadOnly() { + return this.delegate.isReadOnly(); + } + + @Override + public void gc() { + this.delegate.gc(); + } + + @Override + public void setAllowLinking(boolean allowLinking) { + this.delegate.setAllowLinking(allowLinking); + } + + @Override + public boolean getAllowLinking() { + return this.delegate.getAllowLinking(); + } + + @Override + protected void initInternal() throws LifecycleException { + if (this.delegate instanceof LifecycleBase) { + try { + ReflectionUtils.invokeMethod(this.initInternal, this.delegate); + } + catch (Exception ex) { + throw new LifecycleException(ex); + } + } + } + + } + + /** + * {@link Rfc6265CookieProcessor} that supports {@link CookieSameSiteSupplier + * supplied} {@link SameSite} values. + */ + private static class SuppliedSameSiteCookieProcessor extends Rfc6265CookieProcessor { + + private final List suppliers; + + SuppliedSameSiteCookieProcessor(List suppliers) { + this.suppliers = suppliers; + } + + @Override + public String generateHeader(Cookie cookie, HttpServletRequest request) { + SameSite sameSite = getSameSite(cookie); + String sameSiteValue = (sameSite != null) ? sameSite.attributeValue() : null; + if (sameSiteValue == null) { + return super.generateHeader(cookie, request); + } + Rfc6265CookieProcessor delegate = new Rfc6265CookieProcessor(); + delegate.setSameSiteCookies(sameSiteValue); + return delegate.generateHeader(cookie, request); + } + + private SameSite getSameSite(Cookie cookie) { + for (CookieSameSiteSupplier supplier : this.suppliers) { + SameSite sameSite = supplier.getSameSite(cookie); + if (sameSite != null) { + return sameSite; + } + } + return null; + } + + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/package-info.java b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/package-info.java new file mode 100644 index 000000000000..89e4606b1de5 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Servlet web server implementation backed by Tomcat. + */ +package org.springframework.boot.tomcat.servlet; diff --git a/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..eba24ad24230 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,113 @@ +{ + "groups": [], + "properties": [ + { + "name": "server.tomcat.max-http-post-size", + "type": "org.springframework.util.unit.DataSize", + "deprecation": { + "replacement": "server.tomcat.max-http-form-post-size", + "level": "error" + } + }, + { + "name": "server.tomcat.reject-illegal-header", + "deprecation": { + "level": "error" + } + } + ], + "hints": [ + { + "name": "server.tomcat.accesslog.encoding", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "java.nio.charset.Charset" + } + } + ] + }, + { + "name": "server.tomcat.accesslog.locale", + "providers": [ + { + "name": "handle-as", + "parameters": { + "target": "java.util.Locale" + } + } + ] + }, + { + "name": "server.tomcat.relaxed-path-chars", + "values": [ + { + "value": "<" + }, + { + "value": ">" + }, + { + "value": "[" + }, + { + "value": "\\" + }, + { + "value": "]" + }, + { + "value": "^" + }, + { + "value": "`" + }, + { + "value": "{" + }, + { + "value": "|" + }, + { + "value": "}" + } + ] + }, + { + "name": "server.tomcat.relaxed-query-chars", + "values": [ + { + "value": "<" + }, + { + "value": ">" + }, + { + "value": "[" + }, + { + "value": "\\" + }, + { + "value": "]" + }, + { + "value": "^" + }, + { + "value": "`" + }, + { + "value": "{" + }, + { + "value": "|" + }, + { + "value": "}" + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..b0dbdee158ca --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring.factories @@ -0,0 +1,7 @@ +# Background Preinitializers +org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer=\ +org.springframework.boot.tomcat.autoconfigure.TomcatBackgroundPreinitializer + +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.boot.tomcat.ConnectorStartFailureAnalyzer diff --git a/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..905739422988 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatReactiveManagementChildContextConfiguration +org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatServletManagementChildContextConfiguration diff --git a/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..fff221c071cd --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,5 @@ +org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatReactiveManagementContextAutoConfiguration +org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatServletManagementContextAutoConfiguration +org.springframework.boot.tomcat.autoconfigure.metrics.TomcatMetricsAutoConfiguration +org.springframework.boot.tomcat.autoconfigure.reactive.TomcatReactiveWebServerAutoConfiguration +org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizerTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/CompressionConnectorCustomizerTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizerTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/CompressionConnectorCustomizerTests.java index 0b7b769308dc..c0a4f6ab57d6 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/CompressionConnectorCustomizerTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/CompressionConnectorCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import org.apache.catalina.connector.Connector; import org.apache.coyote.http11.AbstractHttp11Protocol; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java similarity index 99% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java index 235bfde6d288..69b49538ce0f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatAccess.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatAccess.java new file mode 100644 index 000000000000..49cba489091c --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatAccess.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat; + +import java.util.Map; + +import org.apache.catalina.Service; +import org.apache.catalina.connector.Connector; + +/** + * Helper class to provide public access to package-private methods for testing purposes. + * + * @author Andy Wilkinson + */ +public final class TomcatAccess { + + private TomcatAccess() { + + } + + public static Map getServiceConnectors(TomcatWebServer tomcatWebServer) { + return tomcatWebServer.getServiceConnectors(); + } + + public static String getStartedLogMessage(TomcatWebServer tomcatWebServer) { + return tomcatWebServer.getStartedLogMessage(); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedWebappClassLoaderTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoaderTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedWebappClassLoaderTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoaderTests.java index 819bbc04c675..36285bdf3a92 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatEmbeddedWebappClassLoaderTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoaderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat; import java.io.File; import java.io.FileOutputStream; diff --git a/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerPropertiesTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerPropertiesTests.java new file mode 100644 index 000000000000..70a2587a1695 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerPropertiesTests.java @@ -0,0 +1,263 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.core.StandardEngine; +import org.apache.catalina.valves.AccessLogValve; +import org.apache.catalina.valves.RemoteIpValve; +import org.apache.coyote.AbstractProtocol; +import org.apache.tomcat.util.net.AbstractEndpoint; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.context.properties.source.ConfigurationPropertySource; +import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; +import org.springframework.boot.tomcat.TomcatWebServerFactory; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties.Accesslog; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties.UseApr; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link TomcatServerProperties}. + * + * @author Andy Wilkinson + */ +class TomcatServerPropertiesTests { + + private final TomcatServerProperties properties = new TomcatServerProperties(); + + @Test + void testTomcatBinding() { + Map map = new HashMap<>(); + map.put("server.tomcat.accesslog.conditionIf", "foo"); + map.put("server.tomcat.accesslog.conditionUnless", "bar"); + map.put("server.tomcat.accesslog.pattern", "%h %t '%r' %s %b"); + map.put("server.tomcat.accesslog.prefix", "foo"); + map.put("server.tomcat.accesslog.suffix", "-bar.log"); + map.put("server.tomcat.accesslog.encoding", "UTF-8"); + map.put("server.tomcat.accesslog.locale", "en-AU"); + map.put("server.tomcat.accesslog.checkExists", "true"); + map.put("server.tomcat.accesslog.rotate", "false"); + map.put("server.tomcat.accesslog.rename-on-rotate", "true"); + map.put("server.tomcat.accesslog.ipv6Canonical", "true"); + map.put("server.tomcat.accesslog.request-attributes-enabled", "true"); + map.put("server.tomcat.remoteip.protocol-header", "X-Forwarded-Protocol"); + map.put("server.tomcat.remoteip.remote-ip-header", "Remote-Ip"); + map.put("server.tomcat.remoteip.internal-proxies", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); + map.put("server.tomcat.remoteip.trusted-proxies", "proxy1|proxy2|proxy3"); + map.put("server.tomcat.reject-illegal-header", "false"); + map.put("server.tomcat.background-processor-delay", "10"); + map.put("server.tomcat.relaxed-path-chars", "|,<"); + map.put("server.tomcat.relaxed-query-chars", "^ , | "); + map.put("server.tomcat.use-relative-redirects", "true"); + bind(map); + Accesslog accesslog = this.properties.getAccesslog(); + assertThat(accesslog.getConditionIf()).isEqualTo("foo"); + assertThat(accesslog.getConditionUnless()).isEqualTo("bar"); + assertThat(accesslog.getPattern()).isEqualTo("%h %t '%r' %s %b"); + assertThat(accesslog.getPrefix()).isEqualTo("foo"); + assertThat(accesslog.getSuffix()).isEqualTo("-bar.log"); + assertThat(accesslog.getEncoding()).isEqualTo("UTF-8"); + assertThat(accesslog.getLocale()).isEqualTo("en-AU"); + assertThat(accesslog.isCheckExists()).isTrue(); + assertThat(accesslog.isRotate()).isFalse(); + assertThat(accesslog.isRenameOnRotate()).isTrue(); + assertThat(accesslog.isIpv6Canonical()).isTrue(); + assertThat(accesslog.isRequestAttributesEnabled()).isTrue(); + assertThat(this.properties.getRemoteip().getRemoteIpHeader()).isEqualTo("Remote-Ip"); + assertThat(this.properties.getRemoteip().getProtocolHeader()).isEqualTo("X-Forwarded-Protocol"); + assertThat(this.properties.getRemoteip().getInternalProxies()).isEqualTo("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); + assertThat(this.properties.getRemoteip().getTrustedProxies()).isEqualTo("proxy1|proxy2|proxy3"); + assertThat(this.properties.getBackgroundProcessorDelay()).hasSeconds(10); + assertThat(this.properties.getRelaxedPathChars()).containsExactly('|', '<'); + assertThat(this.properties.getRelaxedQueryChars()).containsExactly('^', '|'); + assertThat(this.properties.isUseRelativeRedirects()).isTrue(); + } + + @Test + void testCustomizeTomcatUriEncoding() { + bind("server.tomcat.uri-encoding", "US-ASCII"); + assertThat(this.properties.getUriEncoding()).isEqualTo(StandardCharsets.US_ASCII); + } + + @Test + void testCustomizeTomcatMaxThreads() { + bind("server.tomcat.threads.max", "10"); + assertThat(this.properties.getThreads().getMax()).isEqualTo(10); + } + + @Test + void testCustomizeTomcatKeepAliveTimeout() { + bind("server.tomcat.keep-alive-timeout", "30s"); + assertThat(this.properties.getKeepAliveTimeout()).hasSeconds(30); + } + + @Test + void testCustomizeTomcatKeepAliveTimeoutWithInfinite() { + bind("server.tomcat.keep-alive-timeout", "-1"); + assertThat(this.properties.getKeepAliveTimeout()).hasMillis(-1); + } + + @Test + void testCustomizeTomcatMaxKeepAliveRequests() { + bind("server.tomcat.max-keep-alive-requests", "200"); + assertThat(this.properties.getMaxKeepAliveRequests()).isEqualTo(200); + } + + @Test + void testCustomizeTomcatMaxKeepAliveRequestsWithInfinite() { + bind("server.tomcat.max-keep-alive-requests", "-1"); + assertThat(this.properties.getMaxKeepAliveRequests()).isEqualTo(-1); + } + + @Test + void testCustomizeTomcatMaxParameterCount() { + bind("server.tomcat.max-parameter-count", "100"); + assertThat(this.properties.getMaxParameterCount()).isEqualTo(100); + } + + @Test + void testCustomizeTomcatMinSpareThreads() { + bind("server.tomcat.threads.min-spare", "10"); + assertThat(this.properties.getThreads().getMinSpare()).isEqualTo(10); + } + + @Test + void tomcatAcceptCountMatchesProtocolDefault() throws Exception { + assertThat(this.properties.getAcceptCount()).isEqualTo(getDefaultProtocol().getAcceptCount()); + } + + @Test + void tomcatProcessorCacheMatchesProtocolDefault() throws Exception { + assertThat(this.properties.getProcessorCache()).isEqualTo(getDefaultProtocol().getProcessorCache()); + } + + @Test + void tomcatMaxConnectionsMatchesProtocolDefault() throws Exception { + assertThat(this.properties.getMaxConnections()).isEqualTo(getDefaultProtocol().getMaxConnections()); + } + + @Test + void tomcatMaxThreadsMatchesProtocolDefault() throws Exception { + assertThat(this.properties.getThreads().getMax()).isEqualTo(getDefaultProtocol().getMaxThreads()); + } + + @Test + void tomcatMinSpareThreadsMatchesProtocolDefault() throws Exception { + assertThat(this.properties.getThreads().getMinSpare()).isEqualTo(getDefaultProtocol().getMinSpareThreads()); + } + + @Test + void tomcatMaxHttpPostSizeMatchesConnectorDefault() { + assertThat(this.properties.getMaxHttpFormPostSize().toBytes()) + .isEqualTo(getDefaultConnector().getMaxPostSize()); + } + + @Test + void tomcatMaxParameterCountMatchesConnectorDefault() { + assertThat(this.properties.getMaxParameterCount()).isEqualTo(getDefaultConnector().getMaxParameterCount()); + } + + @Test + void tomcatBackgroundProcessorDelayMatchesEngineDefault() { + assertThat(this.properties.getBackgroundProcessorDelay()) + .hasSeconds((new StandardEngine().getBackgroundProcessorDelay())); + } + + @Test + void tomcatMaxHttpFormPostSizeMatchesConnectorDefault() { + assertThat(this.properties.getMaxHttpFormPostSize().toBytes()) + .isEqualTo(getDefaultConnector().getMaxPostSize()); + } + + @Test + void tomcatUriEncodingMatchesConnectorDefault() { + assertThat(this.properties.getUriEncoding().name()).isEqualTo(getDefaultConnector().getURIEncoding()); + } + + @Test + void tomcatRedirectContextRootMatchesDefault() { + assertThat(this.properties.getRedirectContextRoot()) + .isEqualTo(new StandardContext().getMapperContextRootRedirectEnabled()); + } + + @Test + void tomcatAccessLogRenameOnRotateMatchesDefault() { + assertThat(this.properties.getAccesslog().isRenameOnRotate()) + .isEqualTo(new AccessLogValve().isRenameOnRotate()); + } + + @Test + void tomcatAccessLogRequestAttributesEnabledMatchesDefault() { + assertThat(this.properties.getAccesslog().isRequestAttributesEnabled()) + .isEqualTo(new AccessLogValve().getRequestAttributesEnabled()); + } + + @Test + void tomcatInternalProxiesMatchesDefault() { + assertThat(this.properties.getRemoteip().getInternalProxies()) + .isEqualTo(new RemoteIpValve().getInternalProxies()); + } + + @Test + void tomcatUseRelativeRedirectsDefaultsToFalse() { + assertThat(this.properties.isUseRelativeRedirects()).isFalse(); + } + + @Test + void tomcatMaxKeepAliveRequestsDefault() throws Exception { + AbstractEndpoint endpoint = (AbstractEndpoint) ReflectionTestUtils.getField(getDefaultProtocol(), + "endpoint"); + int defaultMaxKeepAliveRequests = (int) ReflectionTestUtils.getField(endpoint, "maxKeepAliveRequests"); + assertThat(this.properties.getMaxKeepAliveRequests()).isEqualTo(defaultMaxKeepAliveRequests); + } + + @Test + void shouldDefaultAprToNever() { + assertThat(this.properties.getUseApr()).isEqualTo(UseApr.NEVER); + } + + private void bind(String name, String value) { + bind(Collections.singletonMap(name, value)); + } + + private void bind(Map map) { + ConfigurationPropertySource source = new MapConfigurationPropertySource(map); + new Binder(source).bind("server.tomcat", Bindable.ofInstance(this.properties)); + } + + private Connector getDefaultConnector() { + return new Connector(TomcatWebServerFactory.DEFAULT_PROTOCOL); + } + + private AbstractProtocol getDefaultProtocol() throws Exception { + return (AbstractProtocol) Class.forName(TomcatWebServerFactory.DEFAULT_PROTOCOL) + .getDeclaredConstructor() + .newInstance(); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatVirtualThreadsWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatVirtualThreadsWebServerFactoryCustomizerTests.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatVirtualThreadsWebServerFactoryCustomizerTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatVirtualThreadsWebServerFactoryCustomizerTests.java index af1cfaefe3b5..e61893a39ceb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatVirtualThreadsWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatVirtualThreadsWebServerFactoryCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.tomcat.autoconfigure; import java.util.function.Consumer; @@ -23,8 +23,8 @@ import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.JRE; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizerTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizerTests.java index bbabe4492a66..9c0cf2f457a6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.tomcat.autoconfigure; import java.util.Locale; import java.util.function.Consumer; @@ -32,16 +32,16 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; import org.springframework.boot.testsupport.classpath.ClassPathOverrides; import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties.ForwardHeadersStrategy; import org.springframework.mock.env.MockEnvironment; import org.springframework.test.context.support.TestPropertySourceUtils; import org.springframework.util.unit.DataSize; @@ -66,18 +66,19 @@ @DirtiesUrlFactories class TomcatWebServerFactoryCustomizerTests { - private MockEnvironment environment; + private final MockEnvironment environment = new MockEnvironment(); - private ServerProperties serverProperties; + private final ServerProperties serverProperties = new ServerProperties(); + + private final TomcatServerProperties tomcatProperties = new TomcatServerProperties(); private TomcatWebServerFactoryCustomizer customizer; @BeforeEach void setup() { - this.environment = new MockEnvironment(); - this.serverProperties = new ServerProperties(); ConfigurationPropertySources.attach(this.environment); - this.customizer = new TomcatWebServerFactoryCustomizer(this.environment, this.serverProperties); + this.customizer = new TomcatWebServerFactoryCustomizer(this.environment, this.serverProperties, + this.tomcatProperties); } @Test @@ -85,7 +86,7 @@ void defaultsAreConsistent() { customizeAndRunServer((server) -> assertThat( ((AbstractHttp11Protocol) server.getTomcat().getConnector().getProtocolHandler()) .getMaxSwallowSize()) - .isEqualTo(this.serverProperties.getTomcat().getMaxSwallowSize().toBytes())); + .isEqualTo(this.tomcatProperties.getMaxSwallowSize().toBytes())); } @Test @@ -457,7 +458,7 @@ void errorReportValveIsConfiguredToNotReportStackTraces() { @Test void testCustomizeMinSpareThreads() { bind("server.tomcat.threads.min-spare=10"); - assertThat(this.serverProperties.getTomcat().getThreads().getMinSpare()).isEqualTo(10); + assertThat(this.tomcatProperties.getThreads().getMinSpare()).isEqualTo(10); } @Test @@ -517,7 +518,7 @@ void accessLogMaxDaysDefault() { bind("server.tomcat.accesslog.enabled=true"); TomcatServletWebServerFactory factory = customizeAndGetFactory(); assertThat(((AccessLogValve) factory.getEngineValves().iterator().next()).getMaxDays()) - .isEqualTo(this.serverProperties.getTomcat().getAccesslog().getMaxDays()); + .isEqualTo(this.tomcatProperties.getAccesslog().getMaxDays()); } @Test @@ -622,10 +623,20 @@ void configureExecutor() { }); } + @Test + void enableMBeanRegistry() { + bind("server.tomcat.mbeanregistry.enabled=true"); + TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(0); + assertThat(factory.isDisableMBeanRegistry()).isTrue(); + this.customizer.customize(factory); + assertThat(factory.isDisableMBeanRegistry()).isFalse(); + } + private void bind(String... inlinedProperties) { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, inlinedProperties); - new Binder(ConfigurationPropertySources.get(this.environment)).bind("server", - Bindable.ofInstance(this.serverProperties)); + Binder binder = new Binder(ConfigurationPropertySources.get(this.environment)); + binder.bind("server", Bindable.ofInstance(this.serverProperties)); + binder.bind("server.tomcat", Bindable.ofInstance(this.tomcatProperties)); } private void customizeAndRunServer() { diff --git a/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatManagementServerPropertiesTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatManagementServerPropertiesTests.java new file mode 100644 index 000000000000..7a1718ae67be --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/actuate/web/TomcatManagementServerPropertiesTests.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.actuate.web; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link TomcatManagementServerProperties}. + * + * @author Andy Wilkinson + */ +class TomcatManagementServerPropertiesTests { + + @Test + void accessLogsArePrefixedByDefault() { + TomcatManagementServerProperties properties = new TomcatManagementServerProperties(); + assertThat(properties.getAccesslog().getPrefix()).isEqualTo("management_"); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfigurationTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfigurationTests.java index 04a97b058a4c..000c09f448ce 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat; +package org.springframework.boot.tomcat.autoconfigure.metrics; import java.util.Collections; import java.util.concurrent.atomic.AtomicInteger; @@ -26,18 +26,18 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.SpringApplication; -import org.springframework.boot.actuate.metrics.web.tomcat.TomcatMetricsBinder; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.autoconfigure.reactive.TomcatReactiveWebServerAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.tomcat.metrics.TomcatMetricsBinder; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -59,7 +59,7 @@ void autoConfiguresTomcatMetricsWithEmbeddedServletTomcat() { resetTomcatState(); new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(TomcatMetricsAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class)) + TomcatServletWebServerAutoConfiguration.class)) .withUserConfiguration(ServletWebServerConfiguration.class, MeterRegistryConfiguration.class) .withPropertyValues("server.tomcat.mbeanregistry.enabled=true") .run((context) -> { @@ -76,7 +76,7 @@ void autoConfiguresTomcatMetricsWithEmbeddedReactiveTomcat() { resetTomcatState(); new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(TomcatMetricsAutoConfiguration.class, - ReactiveWebServerFactoryAutoConfiguration.class)) + TomcatReactiveWebServerAutoConfiguration.class)) .withUserConfiguration(ReactiveWebServerConfiguration.class, MeterRegistryConfiguration.class) .withPropertyValues("server.tomcat.mbeanregistry.enabled=true") .run((context) -> { diff --git a/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..76fa89ea0fd5 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfigurationTests.java @@ -0,0 +1,227 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.reactive; + +import jakarta.servlet.ServletContext; +import jakarta.websocket.server.ServerContainer; +import org.apache.catalina.Container; +import org.apache.catalina.Context; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.startup.Tomcat; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.tomcat.TomcatContextCustomizer; +import org.springframework.boot.tomcat.TomcatProtocolHandlerCustomizer; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.reactive.AbstractReactiveWebServerAutoConfigurationTests; +import org.springframework.boot.web.server.reactive.context.ReactiveWebServerApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link TomcatReactiveWebServerAutoConfiguration}. + * + * @author Brian Clozel + * @author Raheela Aslam + * @author Madhura Bhave + * @author Scott Frederick + */ +class TomcatReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests { + + TomcatReactiveWebServerAutoConfigurationTests() { + super(TomcatReactiveWebServerAutoConfiguration.class); + } + + @Test + void tomcatConnectorCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(TomcatConnectorCustomizerConfiguration.class).run((context) -> { + TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); + TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer", + TomcatConnectorCustomizer.class); + assertThat(factory.getConnectorCustomizers()).contains(customizer); + then(customizer).should().customize(any(Connector.class)); + }); + } + + @Test + void tomcatConnectorCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatConnectorCustomizerConfiguration.class) + .run((context) -> { + TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); + TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer", + TomcatConnectorCustomizer.class); + assertThat(factory.getConnectorCustomizers()).contains(customizer); + then(customizer).should().customize(any(Connector.class)); + }); + } + + @Test + void tomcatContextCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(TomcatContextCustomizerConfiguration.class).run((context) -> { + TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); + TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class); + assertThat(factory.getContextCustomizers()).contains(customizer); + then(customizer).should().customize(any(Context.class)); + }); + } + + @Test + void tomcatContextCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatContextCustomizerConfiguration.class) + .run((context) -> { + TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); + TomcatContextCustomizer customizer = context.getBean("contextCustomizer", + TomcatContextCustomizer.class); + assertThat(factory.getContextCustomizers()).contains(customizer); + then(customizer).should().customize(any(Context.class)); + }); + } + + @Test + void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(TomcatProtocolHandlerCustomizerConfiguration.class).run((context) -> { + TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); + TomcatProtocolHandlerCustomizer customizer = context.getBean("protocolHandlerCustomizer", + TomcatProtocolHandlerCustomizer.class); + assertThat(factory.getProtocolHandlerCustomizers()).contains(customizer); + then(customizer).should().customize(any()); + }); + } + + @Test + void tomcatProtocolHandlerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration.class) + .run((context) -> { + TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class); + TomcatProtocolHandlerCustomizer customizer = context.getBean("protocolHandlerCustomizer", + TomcatProtocolHandlerCustomizer.class); + assertThat(factory.getProtocolHandlerCustomizers()).contains(customizer); + then(customizer).should().customize(any()); + }); + } + + @Test + void webSocketServerContainerIsAvailableFromServletContext() { + this.serverRunner.run((context) -> { + WebServer webServer = ((ReactiveWebServerApplicationContext) context.getSourceApplicationContext()) + .getWebServer(); + ServletContext servletContext = findContext(((TomcatWebServer) webServer).getTomcat()).getServletContext(); + Object serverContainer = servletContext.getAttribute("jakarta.websocket.server.ServerContainer"); + assertThat(serverContainer).isInstanceOf(ServerContainer.class); + }); + } + + private static Context findContext(Tomcat tomcat) { + for (Container child : tomcat.getHost().findChildren()) { + if (child instanceof Context context) { + return context; + } + } + throw new IllegalStateException("The Host does not contain a Context"); + } + + @Configuration(proxyBeanMethods = false) + static class TomcatConnectorCustomizerConfiguration { + + @Bean + TomcatConnectorCustomizer connectorCustomizer() { + return mock(TomcatConnectorCustomizer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationTomcatConnectorCustomizerConfiguration { + + private final TomcatConnectorCustomizer customizer = mock(TomcatConnectorCustomizer.class); + + @Bean + TomcatConnectorCustomizer connectorCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer tomcatCustomizer() { + return (tomcat) -> tomcat.addConnectorCustomizers(this.customizer); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TomcatContextCustomizerConfiguration { + + @Bean + TomcatContextCustomizer contextCustomizer() { + return mock(TomcatContextCustomizer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationTomcatContextCustomizerConfiguration { + + private final TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class); + + @Bean + TomcatContextCustomizer contextCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer tomcatCustomizer() { + return (tomcat) -> tomcat.addContextCustomizers(this.customizer); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TomcatProtocolHandlerCustomizerConfiguration { + + @Bean + TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() { + return mock(TomcatProtocolHandlerCustomizer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration { + + private final TomcatProtocolHandlerCustomizer customizer = mock(TomcatProtocolHandlerCustomizer.class); + + @Bean + TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer tomcatCustomizer() { + return (tomcat) -> tomcat.addProtocolHandlerCustomizers(this.customizer); + } + + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..d705934002c9 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerAutoConfigurationTests.java @@ -0,0 +1,228 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.autoconfigure.servlet; + +import jakarta.servlet.Filter; +import org.apache.catalina.Context; +import org.apache.catalina.connector.Connector; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.tomcat.TomcatContextCustomizer; +import org.springframework.boot.tomcat.TomcatProtocolHandlerCustomizer; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.servlet.AbstractServletWebServerAutoConfigurationTests; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.ForwardedHeaderFilter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link TomcatServletWebServerAutoConfiguration}. + * + * @author Dave Syer + * @author Phillip Webb + * @author Stephane Nicoll + * @author Raheela Aslam + * @author Madhura Bhave + */ +class TomcatServletWebServerAutoConfigurationTests extends AbstractServletWebServerAutoConfigurationTests { + + TomcatServletWebServerAutoConfigurationTests() { + super(TomcatServletWebServerAutoConfiguration.class); + } + + @Test + void tomcatConnectorCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(TomcatConnectorCustomizerConfiguration.class).run((context) -> { + TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); + TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer", + TomcatConnectorCustomizer.class); + assertThat(factory.getConnectorCustomizers()).contains(customizer); + then(customizer).should().customize(any(Connector.class)); + }); + } + + @Test + void tomcatConnectorCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatConnectorCustomizerConfiguration.class) + .run((context) -> { + TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); + TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer", + TomcatConnectorCustomizer.class); + assertThat(factory.getConnectorCustomizers()).contains(customizer); + then(customizer).should().customize(any(Connector.class)); + }); + } + + @Test + void tomcatContextCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(TomcatContextCustomizerConfiguration.class).run((context) -> { + TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); + TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class); + assertThat(factory.getContextCustomizers()).contains(customizer); + then(customizer).should().customize(any(Context.class)); + }); + } + + @Test + void tomcatContextCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatContextCustomizerConfiguration.class) + .run((context) -> { + TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); + TomcatContextCustomizer customizer = context.getBean("contextCustomizer", + TomcatContextCustomizer.class); + assertThat(factory.getContextCustomizers()).contains(customizer); + then(customizer).should().customize(any(Context.class)); + }); + } + + @Test + void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(TomcatProtocolHandlerCustomizerConfiguration.class).run((context) -> { + TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); + TomcatProtocolHandlerCustomizer customizer = context.getBean("protocolHandlerCustomizer", + TomcatProtocolHandlerCustomizer.class); + assertThat(factory.getProtocolHandlerCustomizers()).contains(customizer); + then(customizer).should().customize(any()); + }); + } + + @Test + void tomcatProtocolHandlerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration.class) + .run((context) -> { + TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class); + TomcatProtocolHandlerCustomizer customizer = context.getBean("protocolHandlerCustomizer", + TomcatProtocolHandlerCustomizer.class); + assertThat(factory.getProtocolHandlerCustomizers()).contains(customizer); + then(customizer).should().customize(any()); + }); + } + + @Test + void whenUsingFrameworkForwardHeadersStrategyAndRelativeRedirectsAreEnabledThenFilterIsConfiguredToUseRelativeRedirects() { + this.serverRunner + .withPropertyValues("server.forward-headers-strategy=framework", + "server.tomcat.use-relative-redirects=true", "server.port=0") + .run((context) -> { + Filter filter = context.getBean(FilterRegistrationBean.class).getFilter(); + assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class); + assertThat(filter).extracting("relativeRedirects").isEqualTo(true); + }); + } + + @Test + void whenUsingFrameworkForwardHeadersStrategyAndNotUsingRelativeRedirectsThenFilterIsNotConfiguredToUseRelativeRedirects() { + this.serverRunner + .withPropertyValues("server.forward-headers-strategy=framework", + "server.tomcat.use-relative-redirects=false", "server.port=0") + .run((context) -> { + Filter filter = context.getBean(FilterRegistrationBean.class).getFilter(); + assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class); + assertThat(filter).extracting("relativeRedirects").isEqualTo(false); + }); + } + + @Configuration(proxyBeanMethods = false) + static class TomcatConnectorCustomizerConfiguration { + + @Bean + TomcatConnectorCustomizer connectorCustomizer() { + return mock(TomcatConnectorCustomizer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationTomcatConnectorCustomizerConfiguration { + + private final TomcatConnectorCustomizer customizer = mock(TomcatConnectorCustomizer.class); + + @Bean + TomcatConnectorCustomizer connectorCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer tomcatCustomizer() { + return (tomcat) -> tomcat.addConnectorCustomizers(this.customizer); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TomcatContextCustomizerConfiguration { + + @Bean + TomcatContextCustomizer contextCustomizer() { + return mock(TomcatContextCustomizer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationTomcatContextCustomizerConfiguration { + + private final TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class); + + @Bean + TomcatContextCustomizer contextCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer tomcatCustomizer() { + return (tomcat) -> tomcat.addContextCustomizers(this.customizer); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TomcatProtocolHandlerCustomizerConfiguration { + + @Bean + TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() { + return mock(TomcatProtocolHandlerCustomizer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration { + + private final TomcatProtocolHandlerCustomizer customizer = mock(TomcatProtocolHandlerCustomizer.class); + + @Bean + TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer tomcatCustomizer() { + return (tomcat) -> tomcat.addProtocolHandlerCustomizers(this.customizer); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/TomcatServletWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerFactoryCustomizerTests.java similarity index 83% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/TomcatServletWebServerFactoryCustomizerTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerFactoryCustomizerTests.java index d19e1b3c1cce..2a39dc33b444 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/TomcatServletWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/servlet/TomcatServletWebServerFactoryCustomizerTests.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.tomcat.autoconfigure.servlet; import org.apache.catalina.Context; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.autoconfigure.TomcatServerProperties; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.mock.env.MockEnvironment; import org.springframework.test.context.support.TestPropertySourceUtils; @@ -38,18 +38,17 @@ */ class TomcatServletWebServerFactoryCustomizerTests { + private final TomcatServerProperties tomcatProperties = new TomcatServerProperties(); + private TomcatServletWebServerFactoryCustomizer customizer; private MockEnvironment environment; - private ServerProperties serverProperties; - @BeforeEach void setup() { this.environment = new MockEnvironment(); - this.serverProperties = new ServerProperties(); ConfigurationPropertySources.attach(this.environment); - this.customizer = new TomcatServletWebServerFactoryCustomizer(this.serverProperties); + this.customizer = new TomcatServletWebServerFactoryCustomizer(this.tomcatProperties); } @Test @@ -74,8 +73,7 @@ private void testCustomTldSkip(String... expectedJars) { @Test void redirectContextRootCanBeConfigured() { bind("server.tomcat.redirect-context-root=false"); - ServerProperties.Tomcat tomcat = this.serverProperties.getTomcat(); - assertThat(tomcat.getRedirectContextRoot()).isFalse(); + assertThat(this.tomcatProperties.getRedirectContextRoot()).isFalse(); TomcatWebServer server = customizeAndGetServer(); Context context = (Context) server.getTomcat().getHost().findChildren()[0]; assertThat(context.getMapperContextRootRedirectEnabled()).isFalse(); @@ -84,7 +82,7 @@ void redirectContextRootCanBeConfigured() { @Test void useRelativeRedirectsCanBeConfigured() { bind("server.tomcat.use-relative-redirects=true"); - assertThat(this.serverProperties.getTomcat().isUseRelativeRedirects()).isTrue(); + assertThat(this.tomcatProperties.isUseRelativeRedirects()).isTrue(); TomcatWebServer server = customizeAndGetServer(); Context context = (Context) server.getTomcat().getHost().findChildren()[0]; assertThat(context.getUseRelativeRedirects()).isTrue(); @@ -92,8 +90,8 @@ void useRelativeRedirectsCanBeConfigured() { private void bind(String... inlinedProperties) { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, inlinedProperties); - new Binder(ConfigurationPropertySources.get(this.environment)).bind("server", - Bindable.ofInstance(this.serverProperties)); + new Binder(ConfigurationPropertySources.get(this.environment)).bind("server.tomcat", + Bindable.ofInstance(this.tomcatProperties)); } private TomcatWebServer customizeAndGetServer() { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinderTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/metrics/TomcatMetricsBinderTests.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinderTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/metrics/TomcatMetricsBinderTests.java index b04d813dfd20..86fb14356bcb 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinderTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/metrics/TomcatMetricsBinderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.tomcat; +package org.springframework.boot.tomcat.metrics; import io.micrometer.core.instrument.MeterRegistry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactoryTests.java similarity index 87% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactoryTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactoryTests.java index e23d69ee1d36..6964ca407741 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat.reactive; import java.net.ConnectException; import java.time.Duration; @@ -38,11 +38,16 @@ import org.junit.jupiter.api.Test; import org.mockito.InOrder; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests; +import org.springframework.boot.tomcat.TomcatAccess; +import org.springframework.boot.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.tomcat.TomcatContextCustomizer; +import org.springframework.boot.tomcat.TomcatProtocolHandlerCustomizer; +import org.springframework.boot.tomcat.TomcatWebServer; import org.springframework.boot.web.server.PortInUseException; import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.WebServerException; +import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactoryTests; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.web.reactive.function.client.WebClient; @@ -74,7 +79,7 @@ void tomcatCustomizers() { TomcatReactiveWebServerFactory factory = getFactory(); TomcatContextCustomizer[] customizers = new TomcatContextCustomizer[4]; Arrays.setAll(customizers, (i) -> mock(TomcatContextCustomizer.class)); - factory.setTomcatContextCustomizers(Arrays.asList(customizers[0], customizers[1])); + factory.setContextCustomizers(Arrays.asList(customizers[0], customizers[1])); factory.addContextCustomizers(customizers[2], customizers[3]); this.webServer = factory.getWebServer(mock(HttpHandler.class)); InOrder ordered = inOrder((Object[]) customizers); @@ -128,8 +133,8 @@ void tomcatListeners() { @Test void setNullConnectorCustomizersShouldThrowException() { TomcatReactiveWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.setTomcatConnectorCustomizers(null)) - .withMessageContaining("'tomcatConnectorCustomizers' must not be null"); + assertThatIllegalArgumentException().isThrownBy(() -> factory.setConnectorCustomizers(null)) + .withMessageContaining("'connectorCustomizers' must not be null"); } @Test @@ -137,14 +142,14 @@ void addNullAddConnectorCustomizersShouldThrowException() { TomcatReactiveWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() .isThrownBy(() -> factory.addConnectorCustomizers((TomcatConnectorCustomizer[]) null)) - .withMessageContaining("'tomcatConnectorCustomizers' must not be null"); + .withMessageContaining("'connectorCustomizers' must not be null"); } @Test void setNullProtocolHandlerCustomizersShouldThrowException() { TomcatReactiveWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.setTomcatProtocolHandlerCustomizers(null)) - .withMessageContaining("'tomcatProtocolHandlerCustomizers' must not be null"); + assertThatIllegalArgumentException().isThrownBy(() -> factory.setProtocolHandlerCustomizers(null)) + .withMessageContaining("'protocolHandlerCustomizers' must not be null"); } @Test @@ -152,7 +157,7 @@ void addNullProtocolHandlerCustomizersShouldThrowException() { TomcatReactiveWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() .isThrownBy(() -> factory.addProtocolHandlerCustomizers((TomcatProtocolHandlerCustomizer[]) null)) - .withMessageContaining("'tomcatProtocolHandlerCustomizers' must not be null"); + .withMessageContaining("'protocolHandlerCustomizers' must not be null"); } @Test @@ -161,7 +166,7 @@ void tomcatConnectorCustomizersShouldBeInvoked() { HttpHandler handler = mock(HttpHandler.class); TomcatConnectorCustomizer[] customizers = new TomcatConnectorCustomizer[4]; Arrays.setAll(customizers, (i) -> mock(TomcatConnectorCustomizer.class)); - factory.setTomcatConnectorCustomizers(Arrays.asList(customizers[0], customizers[1])); + factory.setConnectorCustomizers(Arrays.asList(customizers[0], customizers[1])); factory.addConnectorCustomizers(customizers[2], customizers[3]); this.webServer = factory.getWebServer(handler); InOrder ordered = inOrder((Object[]) customizers); @@ -177,7 +182,7 @@ void tomcatProtocolHandlerCustomizersShouldBeInvoked() { HttpHandler handler = mock(HttpHandler.class); TomcatProtocolHandlerCustomizer>[] customizers = new TomcatProtocolHandlerCustomizer[4]; Arrays.setAll(customizers, (i) -> mock(TomcatProtocolHandlerCustomizer.class)); - factory.setTomcatProtocolHandlerCustomizers(Arrays.asList(customizers[0], customizers[1])); + factory.setProtocolHandlerCustomizers(Arrays.asList(customizers[0], customizers[1])); factory.addProtocolHandlerCustomizers(customizers[2], customizers[3]); this.webServer = factory.getWebServer(handler); InOrder ordered = inOrder((Object[]) customizers); @@ -191,16 +196,17 @@ void tomcatAdditionalConnectors() { TomcatReactiveWebServerFactory factory = getFactory(); Connector[] connectors = new Connector[4]; Arrays.setAll(connectors, (i) -> new Connector()); - factory.addAdditionalTomcatConnectors(connectors); + factory.addAdditionalConnectors(connectors); this.webServer = factory.getWebServer(mock(HttpHandler.class)); - Map connectorsByService = ((TomcatWebServer) this.webServer).getServiceConnectors(); + Map connectorsByService = TomcatAccess + .getServiceConnectors((TomcatWebServer) this.webServer); assertThat(connectorsByService.values().iterator().next()).hasSize(connectors.length + 1); } @Test void addNullAdditionalConnectorsThrows() { TomcatReactiveWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.addAdditionalTomcatConnectors((Connector[]) null)) + assertThatIllegalArgumentException().isThrownBy(() -> factory.addAdditionalConnectors((Connector[]) null)) .withMessageContaining("'connectors' must not be null"); } @@ -227,7 +233,7 @@ void referenceClearingIsDisabled() { @Test void portClashOfPrimaryConnectorResultsInPortInUseException() throws Exception { doWithBlockedPort((port) -> assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> { - AbstractReactiveWebServerFactory factory = getFactory(); + TomcatReactiveWebServerFactory factory = getFactory(); factory.setPort(port); this.webServer = factory.getWebServer(mock(HttpHandler.class)); this.webServer.start(); @@ -284,14 +290,14 @@ private void handleExceptionCausedByBlockedPortOnPrimaryConnector(RuntimeExcepti @Override protected String startedLogMessage() { - return ((TomcatWebServer) this.webServer).getStartedLogMessage(); + return TomcatAccess.getStartedLogMessage((TomcatWebServer) this.webServer); } @Override - protected void addConnector(int port, AbstractReactiveWebServerFactory factory) { + protected void addConnector(int port, ConfigurableReactiveWebServerFactory factory) { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setPort(port); - ((TomcatReactiveWebServerFactory) factory).addAdditionalTomcatConnectors(connector); + ((TomcatReactiveWebServerFactory) factory).addAdditionalConnectors(connector); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TldPatternsTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TldPatternsTests.java similarity index 97% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TldPatternsTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TldPatternsTests.java index 7e5a6bca2452..077746157d18 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TldPatternsTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TldPatternsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat.servlet; import java.io.IOException; import java.io.InputStream; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactoryTests.java similarity index 90% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java rename to spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactoryTests.java index b4d923250d75..8c51e7570d97 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.tomcat; +package org.springframework.boot.tomcat.servlet; import java.io.File; import java.io.IOException; @@ -50,7 +50,6 @@ import org.apache.catalina.LifecycleListener; import org.apache.catalina.LifecycleState; import org.apache.catalina.Service; -import org.apache.catalina.SessionIdGenerator; import org.apache.catalina.Valve; import org.apache.catalina.connector.Connector; import org.apache.catalina.core.AprLifecycleListener; @@ -77,19 +76,25 @@ import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.InOrder; import org.springframework.boot.ssl.DefaultSslBundleRegistry; import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; import org.springframework.boot.testsupport.system.CapturedOutput; +import org.springframework.boot.tomcat.ConnectorStartFailedException; +import org.springframework.boot.tomcat.TomcatAccess; +import org.springframework.boot.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.tomcat.TomcatContextCustomizer; +import org.springframework.boot.tomcat.TomcatEmbeddedContext; +import org.springframework.boot.tomcat.TomcatProtocolHandlerCustomizer; +import org.springframework.boot.tomcat.TomcatWebServer; import org.springframework.boot.web.server.PortInUseException; import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.WebServerException; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests; +import org.springframework.boot.web.server.servlet.AbstractServletWebServerFactoryTests; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.support.PropertiesLoaderUtils; @@ -185,7 +190,7 @@ void tomcatCustomizers() { TomcatServletWebServerFactory factory = getFactory(); TomcatContextCustomizer[] customizers = new TomcatContextCustomizer[4]; Arrays.setAll(customizers, (i) -> mock(TomcatContextCustomizer.class)); - factory.setTomcatContextCustomizers(Arrays.asList(customizers[0], customizers[1])); + factory.setContextCustomizers(Arrays.asList(customizers[0], customizers[1])); factory.addContextCustomizers(customizers[2], customizers[3]); this.webServer = factory.getWebServer(); InOrder ordered = inOrder((Object[]) customizers); @@ -208,7 +213,7 @@ void tomcatConnectorCustomizers() { TomcatServletWebServerFactory factory = getFactory(); TomcatConnectorCustomizer[] customizers = new TomcatConnectorCustomizer[4]; Arrays.setAll(customizers, (i) -> mock(TomcatConnectorCustomizer.class)); - factory.setTomcatConnectorCustomizers(Arrays.asList(customizers[0], customizers[1])); + factory.setConnectorCustomizers(Arrays.asList(customizers[0], customizers[1])); factory.addConnectorCustomizers(customizers[2], customizers[3]); this.webServer = factory.getWebServer(); InOrder ordered = inOrder((Object[]) customizers); @@ -223,7 +228,7 @@ void tomcatProtocolHandlerCustomizersShouldBeInvoked() { TomcatServletWebServerFactory factory = getFactory(); TomcatProtocolHandlerCustomizer>[] customizers = new TomcatProtocolHandlerCustomizer[4]; Arrays.setAll(customizers, (i) -> mock(TomcatProtocolHandlerCustomizer.class)); - factory.setTomcatProtocolHandlerCustomizers(Arrays.asList(customizers[0], customizers[1])); + factory.setProtocolHandlerCustomizers(Arrays.asList(customizers[0], customizers[1])); factory.addProtocolHandlerCustomizers(customizers[2], customizers[3]); this.webServer = factory.getWebServer(); InOrder ordered = inOrder((Object[]) customizers); @@ -239,7 +244,8 @@ void tomcatProtocolHandlerCanBeCustomized() { .setProcessorCache(250); factory.addProtocolHandlerCustomizers(customizer); Tomcat tomcat = getTomcat(factory); - Connector connector = ((TomcatWebServer) this.webServer).getServiceConnectors().get(tomcat.getService())[0]; + Connector connector = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) + .get(tomcat.getService())[0]; AbstractHttp11Protocol protocolHandler = (AbstractHttp11Protocol) connector.getProtocolHandler(); assertThat(protocolHandler.getProcessorCache()).isEqualTo(250); } @@ -253,10 +259,10 @@ void tomcatAdditionalConnectors() { connector.setPort(0); return connector; }); - factory.addAdditionalTomcatConnectors(connectors); + factory.addAdditionalConnectors(connectors); this.webServer = factory.getWebServer(); Map connectorsByService = new HashMap<>( - ((TomcatWebServer) this.webServer).getServiceConnectors()); + TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer)); assertThat(connectorsByService.values().iterator().next()).hasSize(connectors.length + 1); this.webServer.start(); this.webServer.stop(); @@ -270,28 +276,28 @@ void tomcatAdditionalConnectors() { @Test void addNullAdditionalConnectorThrows() { TomcatServletWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.addAdditionalTomcatConnectors((Connector[]) null)) + assertThatIllegalArgumentException().isThrownBy(() -> factory.addAdditionalConnectors((Connector[]) null)) .withMessageContaining("'connectors' must not be null"); } @Test void sessionTimeout() { TomcatServletWebServerFactory factory = getFactory(); - factory.getSession().setTimeout(Duration.ofSeconds(10)); + factory.getSettings().getSession().setTimeout(Duration.ofSeconds(10)); assertTimeout(factory, 1); } @Test void sessionTimeoutInMinutes() { TomcatServletWebServerFactory factory = getFactory(); - factory.getSession().setTimeout(Duration.ofMinutes(1)); + factory.getSettings().getSession().setTimeout(Duration.ofMinutes(1)); assertTimeout(factory, 1); } @Test void noSessionTimeout() { TomcatServletWebServerFactory factory = getFactory(); - factory.getSession().setTimeout(null); + factory.getSettings().getSession().setTimeout(null); assertTimeout(factory, -1); } @@ -307,8 +313,8 @@ void valve() { @Test void setNullTomcatContextCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.setTomcatContextCustomizers(null)) - .withMessageContaining("'tomcatContextCustomizers' must not be null"); + assertThatIllegalArgumentException().isThrownBy(() -> factory.setContextCustomizers(null)) + .withMessageContaining("'contextCustomizers' must not be null"); } @Test @@ -316,14 +322,14 @@ void addNullContextCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() .isThrownBy(() -> factory.addContextCustomizers((TomcatContextCustomizer[]) null)) - .withMessageContaining("'tomcatContextCustomizers' must not be null"); + .withMessageContaining("'contextCustomizers' must not be null"); } @Test void setNullTomcatConnectorCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.setTomcatConnectorCustomizers(null)) - .withMessageContaining("'tomcatConnectorCustomizers' must not be null"); + assertThatIllegalArgumentException().isThrownBy(() -> factory.setConnectorCustomizers(null)) + .withMessageContaining("'connectorCustomizers' must not be null"); } @Test @@ -331,14 +337,14 @@ void addNullConnectorCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() .isThrownBy(() -> factory.addConnectorCustomizers((TomcatConnectorCustomizer[]) null)) - .withMessageContaining("'tomcatConnectorCustomizers' must not be null"); + .withMessageContaining("'connectorCustomizers' must not be null"); } @Test void setNullTomcatProtocolHandlerCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); - assertThatIllegalArgumentException().isThrownBy(() -> factory.setTomcatProtocolHandlerCustomizers(null)) - .withMessageContaining("'tomcatProtocolHandlerCustomizer' must not be null"); + assertThatIllegalArgumentException().isThrownBy(() -> factory.setProtocolHandlerCustomizers(null)) + .withMessageContaining("'protocolHandlerCustomizers' must not be null"); } @Test @@ -346,7 +352,7 @@ void addNullTomcatProtocolHandlerCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() .isThrownBy(() -> factory.addProtocolHandlerCustomizers((TomcatProtocolHandlerCustomizer[]) null)) - .withMessageContaining("'tomcatProtocolHandlerCustomizers' must not be null"); + .withMessageContaining("'protocolHandlerCustomizers' must not be null"); } @Test @@ -354,7 +360,8 @@ void uriEncoding() { TomcatServletWebServerFactory factory = getFactory(); factory.setUriEncoding(StandardCharsets.US_ASCII); Tomcat tomcat = getTomcat(factory); - Connector connector = ((TomcatWebServer) this.webServer).getServiceConnectors().get(tomcat.getService())[0]; + Connector connector = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) + .get(tomcat.getService())[0]; assertThat(connector.getURIEncoding()).isEqualTo("US-ASCII"); } @@ -362,7 +369,8 @@ void uriEncoding() { void defaultUriEncoding() { TomcatServletWebServerFactory factory = getFactory(); Tomcat tomcat = getTomcat(factory); - Connector connector = ((TomcatWebServer) this.webServer).getServiceConnectors().get(tomcat.getService())[0]; + Connector connector = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) + .get(tomcat.getService())[0]; assertThat(connector.getURIEncoding()).isEqualTo("UTF-8"); } @@ -382,10 +390,10 @@ void destroyCalledWithoutStart() { } @Override - protected void addConnector(int port, AbstractServletWebServerFactory factory) { + protected void addConnector(int port, ConfigurableServletWebServerFactory factory) { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setPort(port); - ((TomcatServletWebServerFactory) factory).addAdditionalTomcatConnectors(connector); + ((TomcatServletWebServerFactory) factory).addAdditionalConnectors(connector); } @Test @@ -449,25 +457,6 @@ void defaultLocaleCharsetMappingsAreOverridden() throws IOException { } } - @Test - @Disabled("See https://github.com/apache/tomcat/commit/c3e33b62101c5ee155808dd1932acde0cac65fe3") - void sessionIdGeneratorIsConfiguredWithAttributesFromTheManager() { - System.setProperty("jvmRoute", "test"); - try { - TomcatServletWebServerFactory factory = getFactory(); - this.webServer = factory.getWebServer(); - this.webServer.start(); - } - finally { - System.clearProperty("jvmRoute"); - } - Tomcat tomcat = ((TomcatWebServer) this.webServer).getTomcat(); - Context context = (Context) tomcat.getHost().findChildren()[0]; - SessionIdGenerator sessionIdGenerator = context.getManager().getSessionIdGenerator(); - assertThat(sessionIdGenerator).isInstanceOf(LazySessionIdGenerator.class); - assertThat(sessionIdGenerator.getJvmRoute()).isEqualTo("test"); - } - @Test void tldSkipPatternsShouldBeAppliedToContextJarScanner() { TomcatServletWebServerFactory factory = getFactory(); @@ -497,7 +486,7 @@ void tldScanPatternsShouldBeAppliedToContextJarScanner() { @Test void customTomcatHttpOnlyCookie() { TomcatServletWebServerFactory factory = getFactory(); - factory.getSession().getCookie().setHttpOnly(false); + factory.getSettings().getSession().getCookie().setHttpOnly(false); this.webServer = factory.getWebServer(); this.webServer.start(); Tomcat tomcat = ((TomcatWebServer) this.webServer).getTomcat(); @@ -609,7 +598,7 @@ protected void assertThatSslWithInvalidAliasCallFails(ThrowingCallable call) { @Test void whenServerIsShuttingDownGracefullyThenNewConnectionsCannotBeMade() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + TomcatServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory.getWebServer((context) -> { @@ -634,7 +623,7 @@ void whenServerIsShuttingDownGracefullyThenNewConnectionsCannotBeMade() throws E @Test void whenServerIsShuttingDownARequestOnAnIdleConnectionResultsInConnectionReset() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + TomcatServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory.getWebServer((context) -> { @@ -760,7 +749,7 @@ protected void handleExceptionCausedByBlockedPortOnSecondaryConnector(RuntimeExc @Override protected String startedLogMessage() { - return ((TomcatWebServer) this.webServer).getStartedLogMessage(); + return TomcatAccess.getStartedLogMessage((TomcatWebServer) this.webServer); } private static final class RememberingHostnameVerifier implements HostnameVerifier { diff --git a/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerMvcIntegrationTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerMvcIntegrationTests.java new file mode 100644 index 000000000000..a3b95cf167b3 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerMvcIntegrationTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.servlet; + +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.context.AbstractServletWebServerMvcIntegrationTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Integration tests for {@link ServletWebServerApplicationContext} and + * {@link TomcatWebServer} running Spring MVC. + */ +class TomcatServletWebServerMvcIntegrationTests extends AbstractServletWebServerMvcIntegrationTests { + + protected TomcatServletWebServerMvcIntegrationTests() { + super(TomcatConfig.class); + } + + @Configuration(proxyBeanMethods = false) + static class TomcatConfig { + + @Bean + TomcatServletWebServerFactory webServerFactory() { + return new TomcatServletWebServerFactory(0); + } + + } + +} diff --git a/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerServletContextListenerTests.java b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerServletContextListenerTests.java new file mode 100644 index 000000000000..bd73f828e137 --- /dev/null +++ b/spring-boot-project/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerServletContextListenerTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tomcat.servlet; + +import jakarta.servlet.ServletContextListener; + +import org.springframework.boot.web.server.servlet.AbstractServletWebServerServletContextListenerTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Tests for Tomcat driving {@link ServletContextListener}s correctly. + * + * @author Andy Wilkinson + */ +class TomcatServletWebServerServletContextListenerTests extends AbstractServletWebServerServletContextListenerTests { + + TomcatServletWebServerServletContextListenerTests() { + super(TomcatConfiguration.class); + } + + @Configuration(proxyBeanMethods = false) + static class TomcatConfiguration { + + @Bean + TomcatServletWebServerFactory webServerFactory() { + return new TomcatServletWebServerFactory(0); + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/1.crt b/spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/1.crt similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/1.crt rename to spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/1.crt diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/1.key b/spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/1.key rename to spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/2.crt b/spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/2.crt similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/2.crt rename to spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/2.crt diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/2.key b/spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/2.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/2.key rename to spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/2.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/test.jks b/spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/tomcat/test.jks rename to spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/servlet/test.jks diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/undertow/test.jks b/spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/undertow/test.jks rename to spring-boot-project/spring-boot-tomcat/src/test/resources/org/springframework/boot/tomcat/test.jks diff --git a/spring-boot-project/spring-boot-tools/spring-boot-autoconfigure-processor/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-autoconfigure-processor/build.gradle index df6608b5b643..7b6c70e79d99 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-autoconfigure-processor/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-autoconfigure-processor/build.gradle @@ -25,8 +25,4 @@ description = "Spring Boot AutoConfigure Annotation Processor" dependencies { testImplementation(enforcedPlatform(project(":spring-boot-project:spring-boot-dependencies"))) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("org.assertj:assertj-core") - testImplementation("org.springframework:spring-core") - testImplementation("org.springframework:spring-core-test") - testImplementation("org.junit.jupiter:junit-jupiter") } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/build.gradle index 847c0a8728ff..9f976067678e 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/build.gradle @@ -36,11 +36,4 @@ dependencies { implementation("org.tomlj:tomlj:1.0.0") testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("com.jayway.jsonpath:json-path") - testImplementation("org.assertj:assertj-core") - testImplementation("org.hamcrest:hamcrest") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.skyscreamer:jsonassert") } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java index 043ab03e9eef..11ffbf21cde0 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java @@ -26,7 +26,6 @@ import org.springframework.boot.buildpack.platform.docker.TotalProgressPullListener; import org.springframework.boot.buildpack.platform.docker.TotalProgressPushListener; import org.springframework.boot.buildpack.platform.docker.UpdateListener; -import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration; import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryAuthentication; import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost; import org.springframework.boot.buildpack.platform.docker.transport.DockerEngineException; @@ -64,20 +63,6 @@ public Builder() { this(BuildLog.toSystemOut()); } - /** - * Create a new builder instance. - * @param dockerConfiguration the docker configuration - * @since 2.4.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #Builder(BuilderDockerConfiguration)} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - @SuppressWarnings("removal") - public Builder( - org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration dockerConfiguration) { - this(BuildLog.toSystemOut(), dockerConfiguration); - } - /** * Create a new builder instance. * @param dockerConfiguration the docker configuration @@ -95,33 +80,6 @@ public Builder(BuildLog log) { this(log, new DockerApi(null, BuildLogAdapter.get(log)), null); } - /** - * Create a new builder instance. - * @param log a logger used to record output - * @param dockerConfiguration the docker configuration - * @since 2.4.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #Builder(BuildLog, BuilderDockerConfiguration)} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - @SuppressWarnings("removal") - public Builder(BuildLog log, - org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration dockerConfiguration) { - this(log, adaptDeprecatedConfiguration(dockerConfiguration)); - } - - @SuppressWarnings("removal") - private static BuilderDockerConfiguration adaptDeprecatedConfiguration( - org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration configuration) { - if (configuration == null) { - return null; - } - DockerConnectionConfiguration connection = org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration - .asConnectionConfiguration(configuration.getHost()); - return new BuilderDockerConfiguration(connection, configuration.isBindHostToBuilder(), - configuration.getBuilderRegistryAuthentication(), configuration.getPublishRegistryAuthentication()); - } - /** * Create a new builder instance. * @param log a logger used to record output diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java index 9991c801a2b7..8355940a9908 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java @@ -90,21 +90,6 @@ public DockerApi() { this(HttpTransport.create((DockerConnectionConfiguration) null), DockerLog.toSystemOut()); } - /** - * Create a new {@link DockerApi} instance. - * @param dockerHost the Docker daemon host information - * @since 2.4.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #DockerApi(DockerConnectionConfiguration, DockerLog)} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - @SuppressWarnings("removal") - public DockerApi( - org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration dockerHost) { - this(org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration - .asConnectionConfiguration(dockerHost), DockerLog.toSystemOut()); - } - /** * Create a new {@link DockerApi} instance. * @param connectionConfiguration the connection configuration to use diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfiguration.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfiguration.java deleted file mode 100644 index 6b68beaeacdf..000000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfiguration.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.buildpack.platform.docker.configuration; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Docker configuration options. - * - * @author Wei Jiang - * @author Scott Frederick - * @since 2.4.0 - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link org.springframework.boot.buildpack.platform.build.BuilderDockerConfiguration}. - */ -@Deprecated(since = "3.5.0", forRemoval = true) -@SuppressWarnings("removal") -public final class DockerConfiguration { - - private final DockerHostConfiguration host; - - private final DockerRegistryAuthentication builderAuthentication; - - private final DockerRegistryAuthentication publishAuthentication; - - private final boolean bindHostToBuilder; - - public DockerConfiguration() { - this(null, null, null, false); - } - - private DockerConfiguration(DockerHostConfiguration host, DockerRegistryAuthentication builderAuthentication, - DockerRegistryAuthentication publishAuthentication, boolean bindHostToBuilder) { - this.host = host; - this.builderAuthentication = builderAuthentication; - this.publishAuthentication = publishAuthentication; - this.bindHostToBuilder = bindHostToBuilder; - } - - public DockerHostConfiguration getHost() { - return this.host; - } - - public boolean isBindHostToBuilder() { - return this.bindHostToBuilder; - } - - public DockerRegistryAuthentication getBuilderRegistryAuthentication() { - return this.builderAuthentication; - } - - public DockerRegistryAuthentication getPublishRegistryAuthentication() { - return this.publishAuthentication; - } - - public DockerConfiguration withHost(String address, boolean secure, String certificatePath) { - Assert.notNull(address, "'address' must not be null"); - return new DockerConfiguration(DockerHostConfiguration.forAddress(address, secure, certificatePath), - this.builderAuthentication, this.publishAuthentication, this.bindHostToBuilder); - } - - public DockerConfiguration withContext(String context) { - Assert.notNull(context, "'context' must not be null"); - return new DockerConfiguration(DockerHostConfiguration.forContext(context), this.builderAuthentication, - this.publishAuthentication, this.bindHostToBuilder); - } - - public DockerConfiguration withBindHostToBuilder(boolean bindHostToBuilder) { - return new DockerConfiguration(this.host, this.builderAuthentication, this.publishAuthentication, - bindHostToBuilder); - } - - public DockerConfiguration withBuilderRegistryTokenAuthentication(String token) { - Assert.notNull(token, "'token' must not be null"); - return new DockerConfiguration(this.host, new DockerRegistryTokenAuthentication(token), - this.publishAuthentication, this.bindHostToBuilder); - } - - public DockerConfiguration withBuilderRegistryUserAuthentication(String username, String password, String url, - String email) { - Assert.notNull(username, "'username' must not be null"); - Assert.notNull(password, "'password' must not be null"); - return new DockerConfiguration(this.host, new DockerRegistryUserAuthentication(username, password, url, email), - this.publishAuthentication, this.bindHostToBuilder); - } - - public DockerConfiguration withPublishRegistryTokenAuthentication(String token) { - Assert.notNull(token, "'token' must not be null"); - return new DockerConfiguration(this.host, this.builderAuthentication, - new DockerRegistryTokenAuthentication(token), this.bindHostToBuilder); - } - - public DockerConfiguration withPublishRegistryUserAuthentication(String username, String password, String url, - String email) { - Assert.notNull(username, "'username' must not be null"); - Assert.notNull(password, "'password' must not be null"); - return new DockerConfiguration(this.host, this.builderAuthentication, - new DockerRegistryUserAuthentication(username, password, url, email), this.bindHostToBuilder); - } - - public DockerConfiguration withEmptyPublishRegistryAuthentication() { - return new DockerConfiguration(this.host, this.builderAuthentication, - new DockerRegistryUserAuthentication("", "", "", ""), this.bindHostToBuilder); - } - - /** - * Docker host configuration. - * - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link DockerHostConfiguration} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - public static class DockerHostConfiguration { - - private final String address; - - private final String context; - - private final boolean secure; - - private final String certificatePath; - - public DockerHostConfiguration(String address, String context, boolean secure, String certificatePath) { - this.address = address; - this.context = context; - this.secure = secure; - this.certificatePath = certificatePath; - } - - public String getAddress() { - return this.address; - } - - public String getContext() { - return this.context; - } - - public boolean isSecure() { - return this.secure; - } - - public String getCertificatePath() { - return this.certificatePath; - } - - public static DockerHostConfiguration forAddress(String address) { - return new DockerHostConfiguration(address, null, false, null); - } - - public static DockerHostConfiguration forAddress(String address, boolean secure, String certificatePath) { - return new DockerHostConfiguration(address, null, secure, certificatePath); - } - - static DockerHostConfiguration forContext(String context) { - return new DockerHostConfiguration(null, context, false, null); - } - - /** - * Adapts a {@link DockerHostConfiguration} to a - * {@link DockerConnectionConfiguration}. - * @param configuration the configuration to adapt - * @return the adapted configuration - * @since 3.5.0 - */ - public static DockerConnectionConfiguration asConnectionConfiguration(DockerHostConfiguration configuration) { - if (configuration != null && StringUtils.hasLength(configuration.context)) { - return new DockerConnectionConfiguration.Context(configuration.context); - } - if (configuration != null && StringUtils.hasLength(configuration.address)) { - return new DockerConnectionConfiguration.Host(configuration.address, configuration.secure, - configuration.certificatePath); - } - return null; - } - - } - -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/ResolvedDockerHost.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/ResolvedDockerHost.java index 59637051bd20..1f8fc8103e4c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/ResolvedDockerHost.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/ResolvedDockerHost.java @@ -76,20 +76,6 @@ public boolean isLocalFileReference() { } } - /** - * Create a new {@link ResolvedDockerHost} from the given host configuration. - * @param dockerHostConfiguration the host configuration or {@code null} - * @return the resolved docker host - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #from(DockerConnectionConfiguration)} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - @SuppressWarnings("removal") - public static ResolvedDockerHost from(DockerConfiguration.DockerHostConfiguration dockerHostConfiguration) { - return from(Environment.SYSTEM, - DockerConfiguration.DockerHostConfiguration.asConnectionConfiguration(dockerHostConfiguration)); - } - /** * Create a new {@link ResolvedDockerHost} from the given host configuration. * @param connectionConfiguration the host configuration or {@code null} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransport.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransport.java index a17488ab2882..50f4ed831f84 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransport.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransport.java @@ -99,22 +99,6 @@ public interface HttpTransport { */ Response head(URI uri) throws IOException; - /** - * Create the most suitable {@link HttpTransport} based on the {@link DockerHost}. - * @param dockerHost the Docker host information - * @return a {@link HttpTransport} instance - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #create(DockerConnectionConfiguration)} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - @SuppressWarnings("removal") - static HttpTransport create( - org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration dockerHost) { - ResolvedDockerHost host = ResolvedDockerHost.from(dockerHost); - HttpTransport remote = RemoteHttpClientTransport.createIfPossible(host); - return (remote != null) ? remote : LocalHttpClientTransport.create(host); - } - /** * Create the most suitable {@link HttpTransport} based on the {@link DockerHost}. * @param connectionConfiguration the Docker host information diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfigurationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfigurationTests.java deleted file mode 100644 index 884f105369a7..000000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfigurationTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.buildpack.platform.docker.configuration; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link DockerConfiguration}. - * - * @author Wei Jiang - * @author Scott Frederick - */ -@SuppressWarnings("removal") -class DockerConfigurationTests { - - @Test - void createDockerConfigurationWithDefaults() { - DockerConfiguration configuration = new DockerConfiguration(); - assertThat(configuration.getBuilderRegistryAuthentication()).isNull(); - } - - @Test - void createDockerConfigurationWithUserAuth() { - DockerConfiguration configuration = new DockerConfiguration().withBuilderRegistryUserAuthentication("user", - "secret", "https://docker.example.com", "docker@example.com"); - DockerRegistryAuthentication auth = configuration.getBuilderRegistryAuthentication(); - assertThat(auth).isNotNull(); - assertThat(auth).isInstanceOf(DockerRegistryUserAuthentication.class); - DockerRegistryUserAuthentication userAuth = (DockerRegistryUserAuthentication) auth; - assertThat(userAuth.getUrl()).isEqualTo("https://docker.example.com"); - assertThat(userAuth.getUsername()).isEqualTo("user"); - assertThat(userAuth.getPassword()).isEqualTo("secret"); - assertThat(userAuth.getEmail()).isEqualTo("docker@example.com"); - } - - @Test - void createDockerConfigurationWithTokenAuth() { - DockerConfiguration configuration = new DockerConfiguration().withBuilderRegistryTokenAuthentication("token"); - DockerRegistryAuthentication auth = configuration.getBuilderRegistryAuthentication(); - assertThat(auth).isNotNull(); - assertThat(auth).isInstanceOf(DockerRegistryTokenAuthentication.class); - DockerRegistryTokenAuthentication tokenAuth = (DockerRegistryTokenAuthentication) auth; - assertThat(tokenAuth.getToken()).isEqualTo("token"); - } - -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-cli/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-cli/build.gradle index c1de97e04707..4d63fb72f8c7 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-cli/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-cli/build.gradle @@ -46,20 +46,12 @@ dependencies { implementation("org.springframework.security:spring-security-crypto") intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - intTestImplementation("org.assertj:assertj-core") - intTestImplementation("org.junit.jupiter:junit-jupiter") - intTestImplementation("org.springframework:spring-core") loader(project(":spring-boot-project:spring-boot-tools:spring-boot-loader")) testImplementation(project(":spring-boot-project:spring-boot")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-test")) - testImplementation("org.assertj:assertj-core") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.springframework:spring-test") } tasks.register("fullJar", Jar) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/build.gradle index 0b50a65245df..4252e76b1e88 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/build.gradle @@ -34,13 +34,7 @@ dependencies { testCompileOnly("com.google.code.findbugs:jsr305:3.0.2") testImplementation(enforcedPlatform(project(":spring-boot-project:spring-boot-dependencies"))) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("org.springframework:spring-core-test") testImplementation("jakarta.validation:jakarta.validation-api") - testImplementation("org.assertj:assertj-core") - testImplementation("org.hamcrest:hamcrest-library") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") testImplementation("org.projectlombok:lombok") - testImplementation("org.springframework:spring-core") testImplementation("org.apache.commons:commons-dbcp2") } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java index 8f39e070fdd1..6234b422166b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java @@ -47,7 +47,6 @@ import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; import org.springframework.boot.configurationprocessor.metadata.InvalidConfigurationMetadataException; -import org.springframework.boot.configurationprocessor.metadata.ItemDeprecation; import org.springframework.boot.configurationprocessor.metadata.ItemHint; import org.springframework.boot.configurationprocessor.metadata.ItemIgnore; import org.springframework.boot.configurationprocessor.metadata.ItemMetadata; @@ -346,19 +345,13 @@ private void processEndpoint(AnnotationMirror annotation, TypeElement element) { return; // Can't process that endpoint } String endpointKey = ItemMetadata.newItemMetadataPrefix("management.endpoint.", endpointId); - boolean enabledByDefaultAttribute = (boolean) elementValues.getOrDefault("enableByDefault", true); - String defaultAccess = (!enabledByDefaultAttribute) ? "none" - : (elementValues.getOrDefault("defaultAccess", "unrestricted").toString()).toLowerCase(Locale.ENGLISH); - boolean enabledByDefault = !"none".equals(defaultAccess) && enabledByDefaultAttribute; + String defaultAccess = elementValues.getOrDefault("defaultAccess", "unrestricted") + .toString() + .toLowerCase(Locale.ENGLISH); String type = this.metadataEnv.getTypeUtils().getQualifiedName(element); this.metadataCollector.addIfAbsent(ItemMetadata.newGroup(endpointKey, type, type, null)); ItemMetadata accessProperty = ItemMetadata.newProperty(endpointKey, "access", endpointAccessEnum(), type, null, "Permitted level of access for the %s endpoint.".formatted(endpointId), defaultAccess, null); - this.metadataCollector.add( - ItemMetadata.newProperty(endpointKey, "enabled", Boolean.class.getName(), type, null, - "Whether to enable the %s endpoint.".formatted(endpointId), enabledByDefault, - new ItemDeprecation(null, accessProperty.getName(), "3.4.0")), - (existing) -> checkEnabledValueMatchesExisting(existing, enabledByDefault, type)); this.metadataCollector.add(accessProperty, (existing) -> checkDefaultAccessValueMatchesExisting(existing, defaultAccess, type)); if (hasMainReadOperation(element)) { @@ -367,22 +360,12 @@ private void processEndpoint(AnnotationMirror annotation, TypeElement element) { } } - private void checkEnabledValueMatchesExisting(ItemMetadata existing, boolean enabledByDefault, String sourceType) { - boolean existingDefaultValue = (boolean) existing.getDefaultValue(); - if (enabledByDefault != existingDefaultValue) { - throw new IllegalStateException( - "Existing property '%s' from type %s has a conflicting value. Existing value: %b, new value from type %s: %b" - .formatted(existing.getName(), existing.getSourceType(), existingDefaultValue, sourceType, - enabledByDefault)); - } - } - private void checkDefaultAccessValueMatchesExisting(ItemMetadata existing, String defaultAccess, String sourceType) { String existingDefaultAccess = (String) existing.getDefaultValue(); if (!Objects.equals(defaultAccess, existingDefaultAccess)) { throw new IllegalStateException( - "Existing property '%s' from type %s has a conflicting value. Existing value: %b, new value from type %s: %b" + "Existing property '%s' from type %s has a conflicting value. Existing value: %s, new value from type %s: %s" .formatted(existing.getName(), existing.getSourceType(), existingDefaultAccess, sourceType, defaultAccess)); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/EndpointMetadataGenerationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/EndpointMetadataGenerationTests.java index 0b2549ea0bfa..0cada46bc484 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/EndpointMetadataGenerationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/EndpointMetadataGenerationTests.java @@ -26,7 +26,6 @@ import org.springframework.boot.configurationsample.Access; import org.springframework.boot.configurationsample.endpoint.CamelCaseEndpoint; import org.springframework.boot.configurationsample.endpoint.CustomPropertiesEndpoint; -import org.springframework.boot.configurationsample.endpoint.DisabledEndpoint; import org.springframework.boot.configurationsample.endpoint.EnabledEndpoint; import org.springframework.boot.configurationsample.endpoint.NoAccessEndpoint; import org.springframework.boot.configurationsample.endpoint.ReadOnlyAccessEndpoint; @@ -53,18 +52,8 @@ class EndpointMetadataGenerationTests extends AbstractMetadataGenerationTests { void simpleEndpoint() { ConfigurationMetadata metadata = compile(SimpleEndpoint.class); assertThat(metadata).has(Metadata.withGroup("management.endpoint.simple").fromSource(SimpleEndpoint.class)); - assertThat(metadata).has(enabledFlag("simple", true)); assertThat(metadata).has(access("simple", Access.UNRESTRICTED)); assertThat(metadata).has(cacheTtl("simple")); - assertThat(metadata.getItems()).hasSize(4); - } - - @Test - void disabledEndpoint() { - ConfigurationMetadata metadata = compile(DisabledEndpoint.class); - assertThat(metadata).has(Metadata.withGroup("management.endpoint.disabled").fromSource(DisabledEndpoint.class)); - assertThat(metadata).has(enabledFlag("disabled", false)); - assertThat(metadata).has(access("disabled", Access.NONE)); assertThat(metadata.getItems()).hasSize(3); } @@ -72,18 +61,16 @@ void disabledEndpoint() { void enabledEndpoint() { ConfigurationMetadata metadata = compile(EnabledEndpoint.class); assertThat(metadata).has(Metadata.withGroup("management.endpoint.enabled").fromSource(EnabledEndpoint.class)); - assertThat(metadata).has(enabledFlag("enabled", true)); assertThat(metadata).has(access("enabled", Access.UNRESTRICTED)); - assertThat(metadata.getItems()).hasSize(3); + assertThat(metadata.getItems()).hasSize(2); } @Test void noAccessEndpoint() { ConfigurationMetadata metadata = compile(NoAccessEndpoint.class); assertThat(metadata).has(Metadata.withGroup("management.endpoint.noaccess").fromSource(NoAccessEndpoint.class)); - assertThat(metadata).has(enabledFlag("noaccess", false)); assertThat(metadata).has(access("noaccess", Access.NONE)); - assertThat(metadata.getItems()).hasSize(3); + assertThat(metadata.getItems()).hasSize(2); } @Test @@ -91,9 +78,8 @@ void readOnlyAccessEndpoint() { ConfigurationMetadata metadata = compile(ReadOnlyAccessEndpoint.class); assertThat(metadata) .has(Metadata.withGroup("management.endpoint.readonlyaccess").fromSource(ReadOnlyAccessEndpoint.class)); - assertThat(metadata).has(enabledFlag("readonlyaccess", true)); assertThat(metadata).has(access("readonlyaccess", Access.READ_ONLY)); - assertThat(metadata.getItems()).hasSize(3); + assertThat(metadata.getItems()).hasSize(2); } @Test @@ -101,9 +87,8 @@ void unrestrictedAccessEndpoint() { ConfigurationMetadata metadata = compile(UnrestrictedAccessEndpoint.class); assertThat(metadata).has(Metadata.withGroup("management.endpoint.unrestrictedaccess") .fromSource(UnrestrictedAccessEndpoint.class)); - assertThat(metadata).has(enabledFlag("unrestrictedaccess", true)); assertThat(metadata).has(access("unrestrictedaccess", Access.UNRESTRICTED)); - assertThat(metadata.getItems()).hasSize(3); + assertThat(metadata.getItems()).hasSize(2); } @Test @@ -114,20 +99,18 @@ void customPropertiesEndpoint() { assertThat(metadata).has(Metadata.withProperty("management.endpoint.customprops.name") .ofType(String.class) .withDefaultValue("test")); - assertThat(metadata).has(enabledFlag("customprops", true)); assertThat(metadata).has(access("customprops", Access.UNRESTRICTED)); assertThat(metadata).has(cacheTtl("customprops")); - assertThat(metadata.getItems()).hasSize(5); + assertThat(metadata.getItems()).hasSize(4); } @Test void specificEndpoint() { ConfigurationMetadata metadata = compile(SpecificEndpoint.class); assertThat(metadata).has(Metadata.withGroup("management.endpoint.specific").fromSource(SpecificEndpoint.class)); - assertThat(metadata).has(enabledFlag("specific", true)); - assertThat(metadata).has(access("specific", Access.UNRESTRICTED)); + assertThat(metadata).has(access("specific", Access.READ_ONLY)); assertThat(metadata).has(cacheTtl("specific")); - assertThat(metadata.getItems()).hasSize(4); + assertThat(metadata.getItems()).hasSize(3); } @Test @@ -135,30 +118,27 @@ void camelCaseEndpoint() { ConfigurationMetadata metadata = compile(CamelCaseEndpoint.class); assertThat(metadata) .has(Metadata.withGroup("management.endpoint.pascal-case").fromSource(CamelCaseEndpoint.class)); - assertThat(metadata).has(enabledFlag("PascalCase", "pascal-case", true)); assertThat(metadata).has(defaultAccess("PascalCase", "pascal-case", Access.UNRESTRICTED)); - assertThat(metadata.getItems()).hasSize(3); + assertThat(metadata.getItems()).hasSize(2); } @Test - void incrementalEndpointBuildChangeGeneralEnabledFlag() { + void incrementalEndpointBuildChangeDefaultAccess() { TestProject project = new TestProject(IncrementalEndpoint.class); ConfigurationMetadata metadata = project.compile(); assertThat(metadata) .has(Metadata.withGroup("management.endpoint.incremental").fromSource(IncrementalEndpoint.class)); - assertThat(metadata).has(enabledFlag("incremental", true)); assertThat(metadata).has(access("incremental", Access.UNRESTRICTED)); assertThat(metadata).has(cacheTtl("incremental")); - assertThat(metadata.getItems()).hasSize(4); + assertThat(metadata.getItems()).hasSize(3); project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"", - "id = \"incremental\", enableByDefault = false"); + "id = \"incremental\", defaultAccess = org.springframework.boot.configurationsample.Access.NONE"); metadata = project.compile(); assertThat(metadata) .has(Metadata.withGroup("management.endpoint.incremental").fromSource(IncrementalEndpoint.class)); - assertThat(metadata).has(enabledFlag("incremental", false)); assertThat(metadata).has(access("incremental", Access.NONE)); assertThat(metadata).has(cacheTtl("incremental")); - assertThat(metadata.getItems()).hasSize(4); + assertThat(metadata.getItems()).hasSize(3); } @Test @@ -167,45 +147,40 @@ void incrementalEndpointBuildChangeCacheFlag() { ConfigurationMetadata metadata = project.compile(); assertThat(metadata) .has(Metadata.withGroup("management.endpoint.incremental").fromSource(IncrementalEndpoint.class)); - assertThat(metadata).has(enabledFlag("incremental", true)); assertThat(metadata).has(access("incremental", Access.UNRESTRICTED)); assertThat(metadata).has(cacheTtl("incremental")); - assertThat(metadata.getItems()).hasSize(4); + assertThat(metadata.getItems()).hasSize(3); project.replaceText(IncrementalEndpoint.class, "@OptionalParameter String param", "String param"); metadata = project.compile(); assertThat(metadata) .has(Metadata.withGroup("management.endpoint.incremental").fromSource(IncrementalEndpoint.class)); - assertThat(metadata).has(enabledFlag("incremental", true)); assertThat(metadata).has(access("incremental", Access.UNRESTRICTED)); - assertThat(metadata.getItems()).hasSize(3); + assertThat(metadata.getItems()).hasSize(2); } @Test - void incrementalEndpointBuildEnableSpecificEndpoint() { + void incrementalEndpointBuildChangeAccessOfSpecificEndpoint() { TestProject project = new TestProject(SpecificEndpoint.class); ConfigurationMetadata metadata = project.compile(); assertThat(metadata).has(Metadata.withGroup("management.endpoint.specific").fromSource(SpecificEndpoint.class)); - assertThat(metadata).has(enabledFlag("specific", true)); - assertThat(metadata).has(access("specific", Access.UNRESTRICTED)); + assertThat(metadata).has(access("specific", Access.READ_ONLY)); assertThat(metadata).has(cacheTtl("specific")); - assertThat(metadata.getItems()).hasSize(4); - project.replaceText(SpecificEndpoint.class, "enableByDefault = true", "enableByDefault = false"); + assertThat(metadata.getItems()).hasSize(3); + project.replaceText(SpecificEndpoint.class, "defaultAccess = Access.READ_ONLY", "defaultAccess = Access.NONE"); metadata = project.compile(); assertThat(metadata).has(Metadata.withGroup("management.endpoint.specific").fromSource(SpecificEndpoint.class)); - assertThat(metadata).has(enabledFlag("specific", false)); assertThat(metadata).has(access("specific", Access.NONE)); assertThat(metadata).has(cacheTtl("specific")); - assertThat(metadata.getItems()).hasSize(4); + assertThat(metadata.getItems()).hasSize(3); } @Test void shouldTolerateEndpointWithSameId() { ConfigurationMetadata metadata = compile(SimpleEndpoint.class, SimpleEndpoint2.class); assertThat(metadata).has(Metadata.withGroup("management.endpoint.simple").fromSource(SimpleEndpoint.class)); - assertThat(metadata).has(enabledFlag("simple", "simple", true)); assertThat(metadata).has(defaultAccess("simple", "simple", Access.UNRESTRICTED)); assertThat(metadata).has(cacheTtl("simple")); - assertThat(metadata.getItems()).hasSize(4); + assertThat(metadata.getItems()).hasSize(3); } @Test @@ -214,18 +189,7 @@ void shouldFailIfEndpointWithSameIdButWithConflictingEnabledByDefaultSetting() { .havingRootCause() .isInstanceOf(IllegalStateException.class) .withMessage( - "Existing property 'management.endpoint.simple.enabled' from type org.springframework.boot.configurationsample.endpoint.SimpleEndpoint has a conflicting value. Existing value: true, new value from type org.springframework.boot.configurationsample.endpoint.SimpleEndpoint3: false"); - } - - private Metadata.MetadataItemCondition enabledFlag(String endpointId, Boolean defaultValue) { - return enabledFlag(endpointId, endpointId, defaultValue); - } - - private Metadata.MetadataItemCondition enabledFlag(String endpointId, String endpointSuffix, Boolean defaultValue) { - return Metadata.withEnabledFlag("management.endpoint." + endpointSuffix + ".enabled") - .withDefaultValue(defaultValue) - .withDescription(String.format("Whether to enable the %s endpoint.", endpointId)) - .withDeprecation(null, "management.endpoint.%s.access".formatted(endpointSuffix), "3.4.0"); + "Existing property 'management.endpoint.simple.access' from type org.springframework.boot.configurationsample.endpoint.SimpleEndpoint has a conflicting value. Existing value: unrestricted, new value from type org.springframework.boot.configurationsample.endpoint.SimpleEndpoint3: none"); } private Metadata.MetadataItemCondition access(String endpointId, Access defaultValue) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/Endpoint.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/Endpoint.java index a00de8a68c27..b357037ac965 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/Endpoint.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/Endpoint.java @@ -35,9 +35,6 @@ String id() default ""; - @Deprecated - boolean enableByDefault() default true; - Access defaultAccess() default Access.UNRESTRICTED; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/JmxEndpoint.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/JmxEndpoint.java index b04ce532c85a..97879fe29958 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/JmxEndpoint.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/JmxEndpoint.java @@ -35,9 +35,6 @@ String id() default ""; - @Deprecated - boolean enableByDefault() default true; - Access defaultAccess() default Access.UNRESTRICTED; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/RestControllerEndpoint.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/RestControllerEndpoint.java index f180ee936613..16dcdf293f7c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/RestControllerEndpoint.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/RestControllerEndpoint.java @@ -35,9 +35,6 @@ String id() default ""; - @Deprecated - boolean enableByDefault() default true; - Access defaultAccess() default Access.UNRESTRICTED; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/ServletEndpoint.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/ServletEndpoint.java index c3ad0b8f0708..752c2bd2254e 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/ServletEndpoint.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/ServletEndpoint.java @@ -35,9 +35,6 @@ String id() default ""; - @Deprecated - boolean enableByDefault() default true; - Access defaultAccess() default Access.UNRESTRICTED; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/WebEndpoint.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/WebEndpoint.java index edea0ba997c2..b3bed4f93fd0 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/WebEndpoint.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/WebEndpoint.java @@ -35,9 +35,6 @@ String id() default ""; - @Deprecated - boolean enableByDefault() default true; - Access defaultAccess() default Access.UNRESTRICTED; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/DisabledEndpoint.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/DisabledEndpoint.java deleted file mode 100644 index ba6c316cb2b7..000000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/DisabledEndpoint.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.configurationsample.endpoint; - -import org.springframework.boot.configurationsample.Endpoint; - -/** - * An endpoint that is disabled unless configured explicitly. - * - * @author Stephane Nicoll - */ -@SuppressWarnings({ "deprecation", "removal" }) -@Endpoint(id = "disabled", enableByDefault = false) -public class DisabledEndpoint { - -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/SimpleEndpoint3.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/SimpleEndpoint3.java index 5b3321724acf..10ec5c3af7a4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/SimpleEndpoint3.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/SimpleEndpoint3.java @@ -16,17 +16,17 @@ package org.springframework.boot.configurationsample.endpoint; +import org.springframework.boot.configurationsample.Access; import org.springframework.boot.configurationsample.Endpoint; import org.springframework.boot.configurationsample.ReadOperation; /** * A simple endpoint with no default override, with the same id as {@link SimpleEndpoint}, - * but not enabled by default. + * but with no access by default. * * @author Moritz Halbritter */ -@SuppressWarnings({ "deprecation", "removal" }) -@Endpoint(id = "simple", enableByDefault = false) +@Endpoint(id = "simple", defaultAccess = Access.NONE) public class SimpleEndpoint3 { @ReadOperation diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/SpecificEndpoint.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/SpecificEndpoint.java index 05758c6937c0..806bf3a95f71 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/SpecificEndpoint.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/endpoint/SpecificEndpoint.java @@ -16,6 +16,7 @@ package org.springframework.boot.configurationsample.endpoint; +import org.springframework.boot.configurationsample.Access; import org.springframework.boot.configurationsample.OptionalParameter; import org.springframework.boot.configurationsample.ReadOperation; import org.springframework.boot.configurationsample.WebEndpoint; @@ -26,8 +27,7 @@ * * @author Stephane Nicoll */ -@SuppressWarnings({ "deprecation", "removal" }) -@WebEndpoint(id = "specific", enableByDefault = true) +@WebEndpoint(id = "specific", defaultAccess = Access.READ_ONLY) public class SpecificEndpoint { @ReadOperation diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/build.gradle index 1d75cbf3fef1..9758545b53e5 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/build.gradle @@ -65,13 +65,10 @@ dependencies { testImplementation("net.java.dev.jna:jna-platform") testImplementation("org.apache.commons:commons-compress") testImplementation("org.apache.httpcomponents.client5:httpclient5") - testImplementation("org.assertj:assertj-core") testImplementation("org.graalvm.buildtools:native-gradle-plugin") testImplementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") testImplementation("org.jetbrains.kotlin:kotlin-compiler-runner:$kotlinVersion") testImplementation("org.jetbrains.kotlin:kotlin-daemon-client:$kotlinVersion") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") testImplementation("org.tomlj:tomlj:1.0.0") } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-classic/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-loader-classic/build.gradle index 13d0f96ffc56..c38321f52a15 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-classic/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-classic/build.gradle @@ -25,12 +25,6 @@ dependencies { compileOnly("org.springframework:spring-core") testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("org.assertj:assertj-core") - testImplementation("org.awaitility:awaitility") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.springframework:spring-test") - testImplementation("org.springframework:spring-core-test") testRuntimeOnly("ch.qos.logback:logback-classic") testRuntimeOnly("org.bouncycastle:bcprov-jdk18on:1.78.1") diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-loader/build.gradle index 5fcd983a6b31..cefb5ffa4773 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/build.gradle @@ -25,12 +25,6 @@ dependencies { compileOnly("org.springframework:spring-core") testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("org.assertj:assertj-core") - testImplementation("org.awaitility:awaitility") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mockito:mockito-core") - testImplementation("org.springframework:spring-test") - testImplementation("org.springframework:spring-core-test") testRuntimeOnly("ch.qos.logback:logback-classic") testRuntimeOnly("org.bouncycastle:bcprov-jdk18on:1.78.1") diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/module-info.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/module-info.java index 88171fda2660..b5ad64d79bb4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/module-info.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/module-info.java @@ -15,6 +15,6 @@ */ module sampleApp { - requires spring.context; requires spring.boot; + requires spring.context; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support-docker/src/main/java/org/springframework/boot/testsupport/container/TestImage.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support-docker/src/main/java/org/springframework/boot/testsupport/container/TestImage.java index a95af0616a54..cc670d59329c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support-docker/src/main/java/org/springframework/boot/testsupport/container/TestImage.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support-docker/src/main/java/org/springframework/boot/testsupport/container/TestImage.java @@ -84,17 +84,6 @@ public enum TestImage { CASSANDRA("cassandra", "3.11.10", () -> CassandraContainer.class, (container) -> ((CassandraContainer) container).withStartupTimeout(Duration.ofMinutes(10))), - /** - * A container image suitable for testing Cassandra using the deprecated - * {@link org.testcontainers.containers.CassandraContainer}. - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #CASSANDRA} - */ - @SuppressWarnings("deprecation") - @Deprecated(since = "3.4.0", forRemoval = true) - CASSANDRA_DEPRECATED("cassandra", "3.11.10", () -> org.testcontainers.containers.CassandraContainer.class, - (container) -> ((org.testcontainers.containers.CassandraContainer) container) - .withStartupTimeout(Duration.ofMinutes(10))), - /** * A container image suitable for testing ClickHouse. */ @@ -141,16 +130,6 @@ public enum TestImage { */ CONFLUENT_KAFKA("confluentinc/cp-kafka", "7.4.0", () -> ConfluentKafkaContainer.class), - /** - * A container image suitable for testing Confluent's distribution of Kafka using the - * deprecated {@link org.testcontainers.containers.KafkaContainer}. - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #CONFLUENT_KAFKA} - */ - @SuppressWarnings("deprecation") - @Deprecated(since = "3.4.0", forRemoval = true) - CONFLUENT_KAFKA_DEPRECATED("confluentinc/cp-kafka", "7.4.0", - () -> org.testcontainers.containers.KafkaContainer.class), - /** * A container image suitable for testing LLDAP. */ diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-test-support/build.gradle index b6387157ff90..3c23ead92ef7 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/build.gradle @@ -23,16 +23,26 @@ description = "Spring Boot Testing Support" dependencies { api(platform(project(path: ":spring-boot-project:spring-boot-parent"))) + api("com.jayway.jsonpath:json-path") + api("org.assertj:assertj-core") + api("org.awaitility:awaitility") + api("org.hamcrest:hamcrest-core") + api("org.hamcrest:hamcrest-library") + api("org.junit.jupiter:junit-jupiter") + api("org.mockito:mockito-core") + api("org.mockito:mockito-junit-jupiter") + api("org.skyscreamer:jsonassert") + api("org.springframework:spring-core") + api("org.springframework:spring-test") + api("org.springframework:spring-core-test") compileOnly("org.apache.cassandra:java-driver-core") { exclude(group: "org.slf4j", module: "jcl-over-slf4j") } compileOnly("jakarta.servlet:jakarta.servlet-api") compileOnly("junit:junit") - compileOnly("org.junit.jupiter:junit-jupiter") compileOnly("org.junit.platform:junit-platform-engine") compileOnly("org.junit.platform:junit-platform-launcher") - compileOnly("org.mockito:mockito-core") compileOnly("org.springframework:spring-context") compileOnly("org.springframework.data:spring-data-redis") @@ -45,17 +55,9 @@ dependencies { implementation("org.apache.maven.resolver:maven-resolver-transport-http") { exclude group: "org.slf4j", module: "jcl-over-slf4j" } - implementation("org.assertj:assertj-core") - implementation("org.hamcrest:hamcrest-core") - implementation("org.hamcrest:hamcrest-library") - implementation("org.springframework:spring-core") - implementation("org.springframework:spring-test") - implementation("org.springframework:spring-core-test") testImplementation("jakarta.servlet:jakarta.servlet-api") - testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.springframework:spring-context") testRuntimeOnly("org.hibernate.validator:hibernate-validator") - testRuntimeOnly("org.mockito:mockito-core") } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/resources/Resources.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/resources/Resources.java index d5e5677ab790..dbb0b1cf4b32 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/resources/Resources.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/resources/Resources.java @@ -54,8 +54,7 @@ class Resources { this.root = root; } - Resources addPackage(Package root, String[] resourceNames) { - String packageName = root.getName(); + Resources addPackage(String packageName, String[] resourceNames) { Set unmatchedNames = new HashSet<>(Arrays.asList(resourceNames)); withPathsForPackage(packageName, (packagePath) -> { for (String resourceName : resourceNames) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/resources/ResourcesExtension.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/resources/ResourcesExtension.java index 97522c923c97..eb411ebcd8fa 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/resources/ResourcesExtension.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/resources/ResourcesExtension.java @@ -66,7 +66,7 @@ public void beforeEach(ExtensionContext context) throws Exception { .forEach((resource) -> resources.addResource(resource.name(), resource.content(), resource.additional())); resourceDirectoriesOf(testMethod).forEach((directory) -> resources.addDirectory(directory.value())); packageResourcesOf(testMethod, context).forEach((withPackageResources) -> resources - .addPackage(testMethod.getDeclaringClass().getPackage(), withPackageResources.value())); + .addPackage(testMethod.getDeclaringClass().getPackage().getName(), withPackageResources.value())); ResourcesClassLoader classLoader = new ResourcesClassLoader(context.getRequiredTestClass().getClassLoader(), resources); store.put(TCCL_KEY, Thread.currentThread().getContextClassLoader()); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/test/java/org/springframework/boot/testsupport/classpath/resources/ResourcesTests.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/test/java/org/springframework/boot/testsupport/classpath/resources/ResourcesTests.java index f2010d81b409..72b464c8dc2c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/test/java/org/springframework/boot/testsupport/classpath/resources/ResourcesTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/test/java/org/springframework/boot/testsupport/classpath/resources/ResourcesTests.java @@ -74,7 +74,8 @@ void whenAddResourceAndResourceAlreadyExistsThenResourcesIsOverwritten() { @Test void whenAddPackageThenNamedResourcesFromPackageAreCreatedAndCanBeFound() { - this.resources.addPackage(getClass().getPackage(), new String[] { "resource-1.txt", "sub/resource-3.txt" }); + this.resources.addPackage(getClass().getPackage().getName(), + new String[] { "resource-1.txt", "sub/resource-3.txt" }); assertThat(this.root.resolve("resource-1.txt")).hasContent("one"); assertThat(this.root.resolve("resource-2.txt")).doesNotExist(); assertThat(this.root.resolve("sub/resource-3.txt")).hasContent("three"); @@ -96,7 +97,7 @@ void whenAddResourceAndDeleteThenResourceDoesNotExistAndCannotBeFound() { @Test void whenAddPackageAndDeleteThenResourcesDoNotExistAndCannotBeFound() { - this.resources.addPackage(getClass().getPackage(), + this.resources.addPackage(getClass().getPackage().getName(), new String[] { "resource-1.txt", "resource-2.txt", "sub/resource-3.txt" }); assertThat(this.root.resolve("resource-1.txt")).hasContent("one"); assertThat(this.root.resolve("resource-2.txt")).hasContent("two"); diff --git a/spring-boot-project/spring-boot-tracing/build.gradle b/spring-boot-project/spring-boot-tracing/build.gradle new file mode 100644 index 000000000000..8b07d43a92c2 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/build.gradle @@ -0,0 +1,69 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Tracing" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-observation")) + api("io.micrometer:micrometer-tracing") { + exclude(group: "aopalliance", module: "aopalliance") + } + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("io.micrometer:micrometer-core") + optional("io.micrometer:micrometer-tracing-bridge-brave") + optional("io.micrometer:micrometer-tracing-bridge-otel") + optional("io.opentelemetry:opentelemetry-exporter-zipkin") + optional("io.opentelemetry:opentelemetry-exporter-otlp") + optional("io.prometheus:prometheus-metrics-tracer-common") + optional("io.zipkin.reporter2:zipkin-reporter-brave") + optional("org.aspectj:aspectjweaver") + optional("org.junit.platform:junit-platform-launcher") + optional("org.testcontainers:grafana") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-opentelemetry")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-zipkin")) + testImplementation("com.squareup.okhttp3:mockwebserver") + testImplementation("io.micrometer:micrometer-registry-prometheus") + testImplementation("io.opentelemetry:opentelemetry-exporter-common") + testImplementation("io.prometheus:prometheus-metrics-exposition-formats") + testImplementation("org.eclipse.jetty.ee10:jetty-ee10-webapp") + testImplementation("org.eclipse.jetty.http2:jetty-http2-server") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("io.grpc:grpc-api:1.72.0") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/docker/compose/otlp/GrafanaOpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 85% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/docker/compose/otlp/GrafanaOpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java index ffbcbb8e2e9d..8f0650b3d349 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/GrafanaOpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/docker/compose/otlp/GrafanaOpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.tracing.docker.compose.otlp; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails; +import org.springframework.boot.tracing.autoconfigure.otlp.Transport; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/docker/compose/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 85% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/docker/compose/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java index e3518a3fc36b..d12c5a689492 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/docker/compose/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.tracing.docker.compose.otlp; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails; +import org.springframework.boot.tracing.autoconfigure.otlp.Transport; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/testcontainers/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java similarity index 86% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/testcontainers/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java index 054f05536d3e..64fc1f82c348 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/testcontainers/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.tracing.testcontainers.otlp; import org.junit.jupiter.api.Test; import org.testcontainers.grafana.LgtmStackContainer; @@ -22,12 +22,12 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingAutoConfiguration; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails; +import org.springframework.boot.tracing.autoconfigure.otlp.Transport; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/testcontainers/otlp/OpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java similarity index 87% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/testcontainers/otlp/OpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java index c53bdcec5e1d..af568017c50e 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/dockerTest/java/org/springframework/boot/tracing/testcontainers/otlp/OpenTelemetryTracingContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.tracing.testcontainers.otlp; import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; @@ -22,12 +22,12 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingAutoConfiguration; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails; +import org.springframework.boot.tracing.autoconfigure.otlp.Transport; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; diff --git a/spring-boot-project/spring-boot-tracing/src/dockerTest/resources/org/springframework/boot/tracing/docker/compose/otlp/otlp-compose.yaml b/spring-boot-project/spring-boot-tracing/src/dockerTest/resources/org/springframework/boot/tracing/docker/compose/otlp/otlp-compose.yaml new file mode 100644 index 000000000000..86e05475417d --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/dockerTest/resources/org/springframework/boot/tracing/docker/compose/otlp/otlp-compose.yaml @@ -0,0 +1,6 @@ +services: + otlp: + image: '{imageName}' + ports: + - '4317' + - '4318' diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/BraveAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/BraveAutoConfiguration.java index f1926a7a9f05..8d7ac0f7cb1c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/BraveAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; @@ -41,13 +41,13 @@ import io.micrometer.tracing.exporter.SpanReporter; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation.PropagationType; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.IncompatibleConfigurationException; +import org.springframework.boot.tracing.autoconfigure.TracingProperties.Propagation.PropagationType; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; @@ -60,7 +60,7 @@ * @author Moritz Halbritter * @author Marcin Grzejszczak * @author Jonatan Ivanov - * @since 3.0.0 + * @since 4.0.0 */ @AutoConfiguration(before = { MicrometerTracingAutoConfiguration.class, NoopTracerAutoConfiguration.class }) @ConditionalOnClass({ Tracer.class, BraveTracer.class }) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BravePropagationConfigurations.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/BravePropagationConfigurations.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BravePropagationConfigurations.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/BravePropagationConfigurations.java index b158ff74aa03..76ccaf815d63 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BravePropagationConfigurations.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/BravePropagationConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; @@ -33,10 +33,10 @@ import io.micrometer.tracing.brave.bridge.BraveBaggageManager; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Baggage.Correlation; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.tracing.autoconfigure.TracingProperties.Baggage.Correlation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/CompositePropagationFactory.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/CompositePropagationFactory.java index ab14c12f34a5..ebaa8b9f5e5b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/CompositePropagationFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.Collection; import java.util.Collections; @@ -30,7 +30,7 @@ import io.micrometer.tracing.BaggageManager; import io.micrometer.tracing.brave.bridge.W3CPropagation; -import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation.PropagationType; +import org.springframework.boot.tracing.autoconfigure.TracingProperties.Propagation.PropagationType; /** * {@link brave.propagation.Propagation.Factory Propagation factory} which supports diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagator.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/CompositeTextMapPropagator.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagator.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/CompositeTextMapPropagator.java index 1278fef2130c..401b9b98b92f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagator.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/CompositeTextMapPropagator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.ArrayList; import java.util.Collection; @@ -33,7 +33,7 @@ import io.opentelemetry.context.propagation.TextMapSetter; import io.opentelemetry.extension.trace.propagation.B3Propagator; -import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation.PropagationType; +import org.springframework.boot.tracing.autoconfigure.TracingProperties.Propagation.PropagationType; /** * {@link TextMapPropagator} which supports multiple tracing formats. It is able to diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/ConditionalOnEnabledTracing.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/ConditionalOnEnabledTracing.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/ConditionalOnEnabledTracing.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/ConditionalOnEnabledTracing.java index 54f7a66f1e02..193efd1d5b00 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/ConditionalOnEnabledTracing.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/ConditionalOnEnabledTracing.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -33,7 +33,7 @@ * property takes precedence over the global property. * * @author Moritz Halbritter - * @since 3.0.0 + * @since 4.0.0 */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) @@ -44,7 +44,6 @@ /** * Name of the tracing exporter. * @return the name of the tracing exporter - * @since 3.4.0 */ String value() default ""; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/LocalBaggageFields.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/LocalBaggageFields.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/LocalBaggageFields.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/LocalBaggageFields.java index 8430bff94540..bda70251de8c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/LocalBaggageFields.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/LocalBaggageFields.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.ArrayList; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/LogCorrelationEnvironmentPostProcessor.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/LogCorrelationEnvironmentPostProcessor.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/LogCorrelationEnvironmentPostProcessor.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/LogCorrelationEnvironmentPostProcessor.java index 42832a481fa6..49ed683b4918 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/LogCorrelationEnvironmentPostProcessor.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/LogCorrelationEnvironmentPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/MicrometerTracingAutoConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/MicrometerTracingAutoConfiguration.java index 02f6be84f1e3..b4a8db76201f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/MicrometerTracingAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import io.micrometer.common.annotation.ValueExpressionResolver; import io.micrometer.tracing.Tracer; @@ -27,6 +27,7 @@ import io.micrometer.tracing.handler.DefaultTracingObservationHandler; import io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler; import io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler; +import io.micrometer.tracing.handler.TracingObservationHandler; import io.micrometer.tracing.propagation.Propagator; import org.aspectj.weaver.Advice; @@ -37,6 +38,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.observation.autoconfigure.ObservationHandlerGroup; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -45,16 +47,16 @@ import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.SimpleEvaluationContext; +import org.springframework.util.ClassUtils; /** * {@link EnableAutoConfiguration Auto-configuration} for the Micrometer Tracing API. * * @author Moritz Halbritter * @author Jonatan Ivanov - * @since 3.0.0 + * @since 4.0.0 */ @AutoConfiguration -@ConditionalOnClass(Tracer.class) @ConditionalOnBean(Tracer.class) public class MicrometerTracingAutoConfiguration { @@ -75,6 +77,13 @@ public class MicrometerTracingAutoConfiguration { */ public static final int SENDER_TRACING_OBSERVATION_HANDLER_ORDER = 2000; + @Bean + public ObservationHandlerGroup tracingObservationHandlerGroup(Tracer tracer) { + return ClassUtils.isPresent("io.micrometer.core.instrument.MeterRegistry", null) + ? new TracingAndMeterObservationHandlerGroup(tracer) + : ObservationHandlerGroup.of(TracingObservationHandler.class); + } + @Bean @ConditionalOnMissingBean @Order(DEFAULT_TRACING_OBSERVATION_HANDLER_ORDER) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/NoopTracerAutoConfiguration.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/NoopTracerAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/NoopTracerAutoConfiguration.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/NoopTracerAutoConfiguration.java index 349906091d62..dc3d7a4fea98 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/NoopTracerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/NoopTracerAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import io.micrometer.tracing.Tracer; @@ -29,7 +29,7 @@ * {@link Tracer}. * * @author Moritz Halbritter - * @since 3.2.1 + * @since 4.0.0 */ @AutoConfiguration(before = MicrometerTracingAutoConfiguration.class) @ConditionalOnClass(Tracer.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OnEnabledTracingCondition.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OnEnabledTracingCondition.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OnEnabledTracingCondition.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OnEnabledTracingCondition.java index 5fac0ac66f3f..ece2182be33b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OnEnabledTracingCondition.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OnEnabledTracingCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.Map; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublisherBeansApplicationListener.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublisherBeansApplicationListener.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublisherBeansApplicationListener.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublisherBeansApplicationListener.java index 02a3a887c028..4dfe312d2753 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublisherBeansApplicationListener.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublisherBeansApplicationListener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -48,7 +48,7 @@ * {@link ApplicationStartingEvent} isn't called early enough or isn't fired. * * @author Phillip Webb - * @since 3.4.0 + * @since 4.0.0 * @see OpenTelemetryEventPublisherBeansTestExecutionListener */ public class OpenTelemetryEventPublisherBeansApplicationListener implements GenericApplicationListener { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublisherBeansTestExecutionListener.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublisherBeansTestExecutionListener.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublisherBeansTestExecutionListener.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublisherBeansTestExecutionListener.java index 9d7415e4b5be..b4c585f93731 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublisherBeansTestExecutionListener.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublisherBeansTestExecutionListener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import org.junit.platform.launcher.TestExecutionListener; import org.junit.platform.launcher.TestIdentifier; @@ -25,7 +25,7 @@ * early as possible. * * @author Phillip Webb - * @since 3.4.0 + * @since 4.0.0 * @see OpenTelemetryEventPublisherBeansApplicationListener */ public class OpenTelemetryEventPublisherBeansTestExecutionListener implements TestExecutionListener { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryPropagationConfigurations.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryPropagationConfigurations.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryPropagationConfigurations.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryPropagationConfigurations.java index bb2eeafcb79e..04263ca0019c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryPropagationConfigurations.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryPropagationConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryTracingAutoConfiguration.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryTracingAutoConfiguration.java similarity index 99% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryTracingAutoConfiguration.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryTracingAutoConfiguration.java index b93db5724f56..e52ee6df1d67 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryTracingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryTracingAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; @@ -64,7 +64,7 @@ * @author Moritz Halbritter * @author Marcin Grzejszczak * @author Yanming Zhou - * @since 3.4.0 + * @since 4.0.0 */ @AutoConfiguration(before = { MicrometerTracingAutoConfiguration.class, NoopTracerAutoConfiguration.class }) @ConditionalOnClass({ OtelTracer.class, SdkTracerProvider.class, OpenTelemetry.class }) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SdkTracerProviderBuilderCustomizer.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SdkTracerProviderBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SdkTracerProviderBuilderCustomizer.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SdkTracerProviderBuilderCustomizer.java index ab1d5dc02d03..74cc5e0f9ccd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SdkTracerProviderBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SdkTracerProviderBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; @@ -24,7 +24,7 @@ * that is used to create the auto-configured {@link SdkTracerProvider}. * * @author Yanming Zhou - * @since 3.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface SdkTracerProviderBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanExporters.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SpanExporters.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanExporters.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SpanExporters.java index bf28606c55ee..681715000bc6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanExporters.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SpanExporters.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.Arrays; import java.util.Collection; @@ -30,7 +30,7 @@ * A collection of {@link SpanExporter span exporters}. * * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ @FunctionalInterface public interface SpanExporters extends Iterable { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanProcessors.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SpanProcessors.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanProcessors.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SpanProcessors.java index 77dbb56fa5c8..8e73c3c04c3a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanProcessors.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/SpanProcessors.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.Arrays; import java.util.Collection; @@ -30,7 +30,7 @@ * A collection of {@link SpanProcessor span processors}. * * @author Moritz Halbritter - * @since 3.2.0 + * @since 4.0.0 */ @FunctionalInterface public interface SpanProcessors extends Iterable { diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/TracingAndMeterObservationHandlerGroup.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/TracingAndMeterObservationHandlerGroup.java new file mode 100644 index 000000000000..f475f66ed202 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/TracingAndMeterObservationHandlerGroup.java @@ -0,0 +1,92 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tracing.autoconfigure; + +import java.util.ArrayList; +import java.util.List; + +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; +import io.micrometer.observation.ObservationRegistry.ObservationConfig; +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; +import io.micrometer.tracing.handler.TracingObservationHandler; + +import org.springframework.boot.observation.autoconfigure.ObservationHandlerGroup; + +/** + * {@link ObservationHandlerGroup} that considers both {@link TracingObservationHandler} + * and {@link MeterObservationHandler} types as members. This group takes precedence over + * any regular {@link MeterObservationHandler} group in order to use ensure + * {@link TracingAwareMeterObservationHandler} wrapping is applied during registration. + * + * @author Phillip Webb + */ +class TracingAndMeterObservationHandlerGroup implements ObservationHandlerGroup { + + private final Tracer tracer; + + TracingAndMeterObservationHandlerGroup(Tracer tracer) { + this.tracer = tracer; + } + + @Override + public boolean isMember(ObservationHandler handler) { + return MeterObservationHandler.class.isInstance(handler) || TracingObservationHandler.class.isInstance(handler); + } + + @Override + public int compareTo(ObservationHandlerGroup other) { + if (other instanceof TracingAndMeterObservationHandlerGroup) { + return 0; + } + return MeterObservationHandler.class.isAssignableFrom(other.handlerType()) ? -1 : 1; + } + + @Override + public void registerMembers(ObservationConfig config, List> members) { + List> tracingHandlers = new ArrayList<>(members.size()); + List> metricsHandlers = new ArrayList<>(members.size()); + for (ObservationHandler member : members) { + if (member instanceof MeterObservationHandler meterObservationHandler + && !(member instanceof TracingAwareMeterObservationHandler)) { + metricsHandlers.add(new TracingAwareMeterObservationHandler<>(meterObservationHandler, this.tracer)); + } + else { + tracingHandlers.add(member); + } + } + registerHandlers(config, tracingHandlers); + registerHandlers(config, metricsHandlers); + } + + private void registerHandlers(ObservationConfig config, List> handlers) { + if (handlers.size() == 1) { + config.observationHandler(handlers.get(0)); + } + else if (!handlers.isEmpty()) { + config.observationHandler(new FirstMatchingCompositeObservationHandler(handlers)); + } + } + + @Override + public Class handlerType() { + return TracingObservationHandler.class; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/TracingProperties.java similarity index 99% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/TracingProperties.java index e5b0ae93add5..6032f2456234 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/TracingProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -27,7 +27,7 @@ * * @author Moritz Halbritter * @author Jonatan Ivanov - * @since 3.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.tracing") public class TracingProperties { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpGrpcSpanExporterBuilderCustomizer.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpGrpcSpanExporterBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpGrpcSpanExporterBuilderCustomizer.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpGrpcSpanExporterBuilderCustomizer.java index 314f7155acdc..78393e2b3aa4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpGrpcSpanExporterBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpGrpcSpanExporterBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; +package org.springframework.boot.tracing.autoconfigure.otlp; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; @@ -23,7 +23,7 @@ * {@link OtlpGrpcSpanExporterBuilder} whilst retaining default auto-configuration. * * @author Dmytro Nosan - * @since 3.5.0 + * @since 4.0.0 */ @FunctionalInterface public interface OtlpGrpcSpanExporterBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpHttpSpanExporterBuilderCustomizer.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpHttpSpanExporterBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpHttpSpanExporterBuilderCustomizer.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpHttpSpanExporterBuilderCustomizer.java index c39d67c24d3e..87a36272cbf4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpHttpSpanExporterBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpHttpSpanExporterBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; +package org.springframework.boot.tracing.autoconfigure.otlp; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; @@ -23,7 +23,7 @@ * {@link OtlpHttpSpanExporterBuilder} whilst retaining default auto-configuration. * * @author Dmytro Nosan - * @since 3.5.0 + * @since 4.0.0 */ @FunctionalInterface public interface OtlpHttpSpanExporterBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfiguration.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfiguration.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfiguration.java index 8e8c498cda80..741701942320 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; +package org.springframework.boot.tracing.autoconfigure.otlp; import io.micrometer.tracing.otel.bridge.OtelTracer; import io.opentelemetry.api.OpenTelemetry; @@ -44,7 +44,7 @@ * @author Jonatan Ivanov * @author Moritz Halbritter * @author Eddú Meléndez - * @since 3.4.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ OtelTracer.class, SdkTracerProvider.class, OpenTelemetry.class, OtlpHttpSpanExporter.class }) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingConfigurations.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingConfigurations.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingConfigurations.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingConfigurations.java index 21647c0098af..130f5b639372 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingConfigurations.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; +package org.springframework.boot.tracing.autoconfigure.otlp; import java.util.Locale; @@ -25,10 +25,10 @@ import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.tracing.autoconfigure.ConditionalOnEnabledTracing; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.Assert; diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingConnectionDetails.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingConnectionDetails.java new file mode 100644 index 000000000000..baf303e075d0 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingConnectionDetails.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tracing.autoconfigure.otlp; + +import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; + +/** + * Details required to establish a connection to an OpenTelemetry service. + * + * @author Eddú Meléndez + * @author Moritz Halbritter + * @since 4.0.0 + */ +public interface OtlpTracingConnectionDetails extends ConnectionDetails { + + /** + * Address to where tracing will be published. + * @param transport the transport to use + * @return the address to where tracing will be published + */ + String getUrl(Transport transport); + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingProperties.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingProperties.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingProperties.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingProperties.java index 6471b04615a3..32ce8e47f25a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingProperties.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; +package org.springframework.boot.tracing.autoconfigure.otlp; import java.time.Duration; import java.util.HashMap; @@ -26,7 +26,7 @@ * Configuration properties for exporting traces using OTLP. * * @author Jonatan Ivanov - * @since 3.4.0 + * @since 4.0.0 */ @ConfigurationProperties("management.otlp.tracing") public class OtlpTracingProperties { diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/Transport.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/Transport.java new file mode 100644 index 000000000000..cf1f033688ce --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/Transport.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tracing.autoconfigure.otlp; + +/** + * Transport used to send OTLP data. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +public enum Transport { + + /** + * HTTP transport. + */ + HTTP, + + /** + * gRPC transport. + */ + GRPC + +} diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/package-info.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/package-info.java new file mode 100644 index 000000000000..a7ada8ccb932 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/otlp/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for exporting traces with OTLP. + */ +package org.springframework.boot.tracing.autoconfigure.otlp; diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/package-info.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/package-info.java new file mode 100644 index 000000000000..4eafbeba0b31 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Micrometer Tracing. + */ +package org.springframework.boot.tracing.autoconfigure; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfiguration.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/prometheus/PrometheusExemplarsAutoConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfiguration.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/prometheus/PrometheusExemplarsAutoConfiguration.java index cbb38a1ba0d5..d91334dcac45 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/prometheus/PrometheusExemplarsAutoConfiguration.java @@ -14,20 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.prometheus; +package org.springframework.boot.tracing.autoconfigure.prometheus; import io.micrometer.tracing.Span; import io.micrometer.tracing.Tracer; import io.prometheus.metrics.tracer.common.SpanContext; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.tracing.autoconfigure.MicrometerTracingAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.util.function.SingletonSupplier; @@ -36,9 +35,10 @@ * Micrometer Tracing. * * @author Jonatan Ivanov - * @since 3.0.0 + * @since 4.0.0 */ -@AutoConfiguration(before = PrometheusMetricsExportAutoConfiguration.class, +@AutoConfiguration( + beforeName = "org.springframework.boot.metrics.autoconfigure.export.prometheus.PrometheusMetricsExportAutoConfiguration", after = MicrometerTracingAutoConfiguration.class) @ConditionalOnBean(Tracer.class) @ConditionalOnClass({ Tracer.class, SpanContext.class }) diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/prometheus/package-info.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/prometheus/package-info.java new file mode 100644 index 000000000000..32d9aca7d25d --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/prometheus/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Prometheus Exemplars with Micrometer Tracing. + */ +package org.springframework.boot.tracing.autoconfigure.prometheus; diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinTracingAutoConfiguration.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinTracingAutoConfiguration.java new file mode 100644 index 000000000000..64fb16e0e027 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinTracingAutoConfiguration.java @@ -0,0 +1,102 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tracing.autoconfigure.zipkin; + +import brave.Tag; +import brave.Tags; +import brave.handler.MutableSpan; +import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; +import zipkin2.Span; +import zipkin2.reporter.BytesEncoder; +import zipkin2.reporter.BytesMessageSender; +import zipkin2.reporter.Encoding; +import zipkin2.reporter.SpanBytesEncoder; +import zipkin2.reporter.brave.AsyncZipkinSpanHandler; +import zipkin2.reporter.brave.MutableSpanBytesEncoder; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.tracing.autoconfigure.ConditionalOnEnabledTracing; +import org.springframework.boot.tracing.autoconfigure.zipkin.ZipkinTracingAutoConfiguration.BraveConfiguration; +import org.springframework.boot.tracing.autoconfigure.zipkin.ZipkinTracingAutoConfiguration.OpenTelemetryConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Zipkin tracing. + * + * @author Moritz Halbritter + * @author Stefan Bratanov + * @author Wick Dynex + * @author Phillip Webb + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass(Encoding.class) +@Import({ BraveConfiguration.class, OpenTelemetryConfiguration.class }) +public class ZipkinTracingAutoConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(AsyncZipkinSpanHandler.class) + static class BraveConfiguration { + + @Bean + @ConditionalOnMissingBean(value = MutableSpan.class, parameterizedContainer = BytesEncoder.class) + BytesEncoder mutableSpanBytesEncoder(Encoding encoding, + ObjectProvider> throwableTagProvider) { + Tag throwableTag = throwableTagProvider.getIfAvailable(() -> Tags.ERROR); + return MutableSpanBytesEncoder.create(encoding, throwableTag); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(BytesMessageSender.class) + @ConditionalOnEnabledTracing("zipkin") + AsyncZipkinSpanHandler asyncZipkinSpanHandler(BytesMessageSender sender, + BytesEncoder mutableSpanBytesEncoder) { + return AsyncZipkinSpanHandler.newBuilder(sender).build(mutableSpanBytesEncoder); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ ZipkinSpanExporter.class, Span.class }) + static class OpenTelemetryConfiguration { + + @Bean + @ConditionalOnBean(Encoding.class) + @ConditionalOnMissingBean(value = Span.class, parameterizedContainer = BytesEncoder.class) + BytesEncoder spanBytesEncoder(Encoding encoding) { + return SpanBytesEncoder.forEncoding(encoding); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(BytesMessageSender.class) + @ConditionalOnEnabledTracing("zipkin") + ZipkinSpanExporter zipkinSpanExporter(BytesMessageSender sender, BytesEncoder spanBytesEncoder) { + return ZipkinSpanExporter.builder().setSender(sender).setEncoder(spanBytesEncoder).build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/zipkin/package-info.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/zipkin/package-info.java new file mode 100644 index 000000000000..2087014ed24f --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/autoconfigure/zipkin/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for tracing with Zipkin. + */ +package org.springframework.boot.tracing.autoconfigure.zipkin; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/docker/compose/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactory.java similarity index 87% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/docker/compose/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactory.java index 44521f75a5a3..0f86e09987e6 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/docker/compose/otlp/OpenTelemetryTracingDockerComposeConnectionDetailsFactory.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.otlp; +package org.springframework.boot.tracing.docker.compose.otlp; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails; +import org.springframework.boot.tracing.autoconfigure.otlp.Transport; /** * {@link DockerComposeConnectionDetailsFactory} to create @@ -41,7 +41,7 @@ class OpenTelemetryTracingDockerComposeConnectionDetailsFactory OpenTelemetryTracingDockerComposeConnectionDetailsFactory() { super(OPENTELEMETRY_IMAGE_NAMES, - "org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration"); + "org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingAutoConfiguration"); } @Override diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/docker/compose/otlp/package-info.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/docker/compose/otlp/package-info.java new file mode 100644 index 000000000000..acea16df215b --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/docker/compose/otlp/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose OpenTelemetry tracing service connections. + */ +package org.springframework.boot.tracing.docker.compose.otlp; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory.java similarity index 85% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory.java index 51ef144757d2..5c904b6a2763 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.tracing.testcontainers.otlp; import org.testcontainers.grafana.LgtmStackContainer; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails; +import org.springframework.boot.tracing.autoconfigure.otlp.Transport; /** * {@link ContainerConnectionDetailsFactory} to create @@ -36,8 +36,7 @@ class GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory extends ContainerConnectionDetailsFactory { GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory() { - super(ANY_CONNECTION_NAME, - "org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration"); + super(ANY_CONNECTION_NAME, "org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingAutoConfiguration"); } @Override diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryTracingContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/OpenTelemetryTracingContainerConnectionDetailsFactory.java similarity index 87% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryTracingContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/OpenTelemetryTracingContainerConnectionDetailsFactory.java index ed2d03e95abb..f9265023b4f5 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/otlp/OpenTelemetryTracingContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/OpenTelemetryTracingContainerConnectionDetailsFactory.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.otlp; +package org.springframework.boot.tracing.testcontainers.otlp; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.Transport; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConnectionDetails; +import org.springframework.boot.tracing.autoconfigure.otlp.Transport; /** * {@link ContainerConnectionDetailsFactory} to create @@ -42,7 +42,7 @@ class OpenTelemetryTracingContainerConnectionDetailsFactory OpenTelemetryTracingContainerConnectionDetailsFactory() { super("otel/opentelemetry-collector-contrib", - "org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfiguration"); + "org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingAutoConfiguration"); } @Override diff --git a/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/package-info.java b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/package-info.java new file mode 100644 index 000000000000..da5445c75cc3 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/java/org/springframework/boot/tracing/testcontainers/otlp/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Testcontainers OpenTelemetry tracing service connections. + */ +package org.springframework.boot.tracing.testcontainers.otlp; diff --git a/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..331ac5c777a8 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,35 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.otlp.tracing.export.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of tracing is enabled to export OTLP traces." + }, + { + "name": "management.tracing.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of tracing is enabled to export and propagate traces.", + "defaultValue": true + }, + { + "name": "management.tracing.propagation.consume", + "defaultValue": [ + "W3C", + "B3", + "B3_MULTI" + ] + }, + { + "name": "management.tracing.propagation.produce", + "defaultValue": [ + "W3C" + ] + }, + { + "name": "management.zipkin.tracing.export.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of tracing is enabled to export Zipkin traces." + } + ] +} diff --git a/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener b/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener new file mode 100644 index 000000000000..ae578b68dce1 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener @@ -0,0 +1 @@ +org.springframework.boot.tracing.autoconfigure.OpenTelemetryEventPublisherBeansTestExecutionListener diff --git a/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..bf812ffd8403 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/spring.factories @@ -0,0 +1,15 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.tracing.docker.compose.otlp.OpenTelemetryTracingDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.tracing.testcontainers.otlp.GrafanaOpenTelemetryTracingContainerConnectionDetailsFactory,\ +org.springframework.boot.tracing.testcontainers.otlp.OpenTelemetryTracingContainerConnectionDetailsFactory + +# Application Listeners +org.springframework.context.ApplicationListener=\ +org.springframework.boot.tracing.autoconfigure.OpenTelemetryEventPublisherBeansApplicationListener + +# Environment Post Processors +org.springframework.boot.env.EnvironmentPostProcessor=\ +org.springframework.boot.tracing.autoconfigure.LogCorrelationEnvironmentPostProcessor + + diff --git a/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..bf38a6315d0d --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,7 @@ +org.springframework.boot.tracing.autoconfigure.BraveAutoConfiguration +org.springframework.boot.tracing.autoconfigure.MicrometerTracingAutoConfiguration +org.springframework.boot.tracing.autoconfigure.NoopTracerAutoConfiguration +org.springframework.boot.tracing.autoconfigure.OpenTelemetryTracingAutoConfiguration +org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingAutoConfiguration +org.springframework.boot.tracing.autoconfigure.prometheus.PrometheusExemplarsAutoConfiguration +org.springframework.boot.tracing.autoconfigure.zipkin.ZipkinTracingAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BaggagePropagationIntegrationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/BaggagePropagationIntegrationTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BaggagePropagationIntegrationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/BaggagePropagationIntegrationTests.java index ddd64d9e6372..ac85407d5ddf 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BaggagePropagationIntegrationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/BaggagePropagationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.function.Supplier; @@ -30,8 +30,8 @@ import org.junit.jupiter.params.provider.EnumSource; import org.slf4j.MDC; -import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ForkedClassPath; import org.springframework.context.ApplicationContext; @@ -173,8 +173,8 @@ public ApplicationContextRunner get() { @Override public ApplicationContextRunner get() { return new ApplicationContextRunner().withInitializer(new OtelApplicationContextInitializer()) - .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class, - org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, + org.springframework.boot.tracing.autoconfigure.OpenTelemetryTracingAutoConfiguration.class)) .withPropertyValues("management.tracing.baggage.remote-fields=x-vcap-request-id,country-code,bp", "management.tracing.baggage.correlation.fields=country-code,bp"); } @@ -199,8 +199,8 @@ public ApplicationContextRunner get() { @Override public ApplicationContextRunner get() { return new ApplicationContextRunner().withInitializer(new OtelApplicationContextInitializer()) - .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class, - org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, + org.springframework.boot.tracing.autoconfigure.OpenTelemetryTracingAutoConfiguration.class)) .withPropertyValues("management.tracing.propagation.type=W3C", "management.tracing.baggage.remote-fields=x-vcap-request-id,country-code,bp", "management.tracing.baggage.correlation.fields=country-code,bp"); @@ -239,8 +239,8 @@ public ApplicationContextRunner get() { @Override public ApplicationContextRunner get() { return new ApplicationContextRunner().withInitializer(new OtelApplicationContextInitializer()) - .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class, - org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, + org.springframework.boot.tracing.autoconfigure.OpenTelemetryTracingAutoConfiguration.class)) .withPropertyValues("management.tracing.propagation.type=B3", "management.tracing.baggage.remote-fields=x-vcap-request-id,country-code,bp", "management.tracing.baggage.correlation.fields=country-code,bp"); @@ -253,8 +253,8 @@ public ApplicationContextRunner get() { @Override public ApplicationContextRunner get() { return new ApplicationContextRunner().withInitializer(new OtelApplicationContextInitializer()) - .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class, - org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, + org.springframework.boot.tracing.autoconfigure.OpenTelemetryTracingAutoConfiguration.class)) .withPropertyValues("management.tracing.propagation.type=B3_MULTI", "management.tracing.baggage.remote-fields=x-vcap-request-id,country-code,bp", "management.tracing.baggage.correlation.fields=country-code,bp"); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/BraveAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/BraveAutoConfigurationTests.java index 5574a41cfa67..c718082fbf35 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/BraveAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.Collections; import java.util.HashMap; @@ -50,12 +50,12 @@ import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfigurationTests.SpanHandlerConfiguration.AdditionalSpanHandler; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.context.properties.IncompatibleConfigurationException; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.tracing.autoconfigure.BraveAutoConfigurationTests.SpanHandlerConfiguration.AdditionalSpanHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactoryTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/CompositePropagationFactoryTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactoryTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/CompositePropagationFactoryTests.java index 9645d53ad40f..c8157a2ffa8f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactoryTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/CompositePropagationFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.Collections; import java.util.HashMap; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagatorTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/CompositeTextMapPropagatorTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagatorTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/CompositeTextMapPropagatorTests.java index e64bc5313071..7fed5a471665 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositeTextMapPropagatorTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/CompositeTextMapPropagatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.Collection; import java.util.Collections; @@ -34,8 +34,8 @@ import org.mockito.InOrder; import org.mockito.Mockito; -import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation; -import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation.PropagationType; +import org.springframework.boot.tracing.autoconfigure.TracingProperties.Propagation; +import org.springframework.boot.tracing.autoconfigure.TracingProperties.Propagation.PropagationType; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/LocalBaggageFieldsTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/LocalBaggageFieldsTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/LocalBaggageFieldsTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/LocalBaggageFieldsTests.java index 8986b79ecd5a..ffa515a5b901 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/LocalBaggageFieldsTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/LocalBaggageFieldsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import brave.baggage.BaggageField; import brave.baggage.BaggagePropagation; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/LogCorrelationEnvironmentPostProcessorTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/LogCorrelationEnvironmentPostProcessorTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/LogCorrelationEnvironmentPostProcessorTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/LogCorrelationEnvironmentPostProcessorTests.java index 596fd218f502..818bb7617a0b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/LogCorrelationEnvironmentPostProcessorTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/LogCorrelationEnvironmentPostProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/MicrometerTracingAutoConfigurationTests.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/MicrometerTracingAutoConfigurationTests.java index 4cb67093fa90..bd096ab08b1f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/MicrometerTracingAutoConfigurationTests.java @@ -14,12 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; import io.micrometer.common.annotation.ValueExpressionResolver; import io.micrometer.common.annotation.ValueResolver; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.ObservationHandler; import io.micrometer.tracing.Tracer; import io.micrometer.tracing.annotation.DefaultNewSpanParser; import io.micrometer.tracing.annotation.ImperativeMethodInvocationProcessor; @@ -36,6 +38,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.observation.autoconfigure.ObservationHandlerGroup; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -179,6 +182,31 @@ void shouldConfigureSpanTagAnnotationHandler() { }); } + @Test + void shouldCreateTracingAndMeterObservationHandlerGroupWhenHasTracing() { + this.contextRunner.withUserConfiguration(TracerConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(ObservationHandlerGroup.class); + ObservationHandlerGroup group = context.getBean(ObservationHandlerGroup.class); + assertThat(group).isInstanceOf(TracingAndMeterObservationHandlerGroup.class); + assertThat(group.isMember(mock(ObservationHandler.class))).isFalse(); + assertThat(group.isMember(mock(TracingObservationHandler.class))).isTrue(); + assertThat(group.isMember(mock(MeterObservationHandler.class))).isTrue(); + }); + } + + @Test + void shouldCreateTracingObservationHandlerGroupWhenMetricsIsNotOnClassPath() { + this.contextRunner.withUserConfiguration(TracerConfiguration.class) + .withClassLoader(new FilteredClassLoader("io.micrometer.core")) + .run((context) -> { + assertThat(context).hasSingleBean(ObservationHandlerGroup.class); + ObservationHandlerGroup group = context.getBean(ObservationHandlerGroup.class); + assertThat(group).isNotInstanceOf(TracingAndMeterObservationHandlerGroup.class); + assertThat(group.isMember(mock(ObservationHandler.class))).isFalse(); + assertThat(group.isMember(mock(TracingObservationHandler.class))).isTrue(); + }); + } + @Configuration(proxyBeanMethods = false) private static final class TracerConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/NoopTracerAutoConfigurationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/NoopTracerAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/NoopTracerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/NoopTracerAutoConfigurationTests.java index 688b4788e3ff..91538570de4f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/NoopTracerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/NoopTracerAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import io.micrometer.tracing.Tracer; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OnEnabledTracingConditionTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OnEnabledTracingConditionTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OnEnabledTracingConditionTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OnEnabledTracingConditionTests.java index 415c3f364f56..25e78def554e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OnEnabledTracingConditionTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OnEnabledTracingConditionTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublishingContextWrapperBeansTestExecutionListenerIntegrationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublishingContextWrapperBeansTestExecutionListenerIntegrationTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublishingContextWrapperBeansTestExecutionListenerIntegrationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublishingContextWrapperBeansTestExecutionListenerIntegrationTests.java index d136fe14e730..87cfe11b5e56 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryEventPublishingContextWrapperBeansTestExecutionListenerIntegrationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryEventPublishingContextWrapperBeansTestExecutionListenerIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.lang.reflect.Method; import java.util.List; @@ -23,8 +23,8 @@ import io.opentelemetry.context.ContextStorage; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryEventPublisherBeansApplicationListener.Wrapper.Storage; import org.springframework.boot.testsupport.classpath.ForkedClassPath; +import org.springframework.boot.tracing.autoconfigure.OpenTelemetryEventPublisherBeansApplicationListener.Wrapper.Storage; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryTracingAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryTracingAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryTracingAutoConfigurationTests.java index a923acc502fa..8a93cb011090 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryTracingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/OpenTelemetryTracingAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -60,9 +60,8 @@ import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mockito; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.context.annotation.Configurations; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ForkedClassPath; @@ -90,7 +89,7 @@ class OpenTelemetryTracingAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( - org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryAutoConfiguration.class, + org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration.class, OpenTelemetryTracingAutoConfiguration.class)); @Test @@ -381,13 +380,6 @@ void shouldPublishEventsWhenContextStorageIsInitializedEarly() { }); } - @Test - @SuppressWarnings("removal") - void shouldUseReplacementForDeprecatedVersion() { - Class[] classes = Configurations.getClasses(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)); - assertThat(classes).containsExactly(OpenTelemetryTracingAutoConfiguration.class); - } - private void initializeOpenTelemetry(ConfigurableApplicationContext context) { context.addApplicationListener(new OpenTelemetryEventPublisherBeansApplicationListener()); Span.current(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanExportersTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/SpanExportersTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanExportersTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/SpanExportersTests.java index cbc76a556bfd..ff622a615e60 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanExportersTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/SpanExportersTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanProcessorsTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/SpanProcessorsTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanProcessorsTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/SpanProcessorsTests.java index 5a25bb8f9da2..219fa192588f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/SpanProcessorsTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/SpanProcessorsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/TracingAndMeterObservationHandlerGroupTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/TracingAndMeterObservationHandlerGroupTests.java new file mode 100644 index 000000000000..180ccd8882b4 --- /dev/null +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/TracingAndMeterObservationHandlerGroupTests.java @@ -0,0 +1,118 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.tracing.autoconfigure; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; +import io.micrometer.observation.ObservationRegistry.ObservationConfig; +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; +import io.micrometer.tracing.handler.TracingObservationHandler; +import org.assertj.core.extractor.Extractors; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import org.springframework.boot.observation.autoconfigure.ObservationHandlerGroup; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; + +/** + * Tests for {@link TracingAndMeterObservationHandlerGroup}. + * + * @author Phillip Webb + */ +class TracingAndMeterObservationHandlerGroupTests { + + @Test + void compareToSortsBeforeMeterObservationHandlerGroup() { + ObservationHandlerGroup meterGroup = ObservationHandlerGroup.of(MeterObservationHandler.class); + TracingAndMeterObservationHandlerGroup tracingAndMeterGroup = new TracingAndMeterObservationHandlerGroup( + mock(Tracer.class)); + assertThat(sort(meterGroup, tracingAndMeterGroup)).containsExactly(tracingAndMeterGroup, meterGroup); + assertThat(sort(tracingAndMeterGroup, meterGroup)).containsExactly(tracingAndMeterGroup, meterGroup); + } + + @Test + void isMemberAcceptsMeterObservationHandlerOrTracingObservationHandler() { + TracingAndMeterObservationHandlerGroup group = new TracingAndMeterObservationHandlerGroup(mock(Tracer.class)); + assertThat(group.isMember(mock(ObservationHandler.class))).isFalse(); + assertThat(group.isMember(mock(MeterObservationHandler.class))).isTrue(); + assertThat(group.isMember(mock(TracingObservationHandler.class))).isTrue(); + } + + @Test + @SuppressWarnings("unchecked") + void registerMembersWrapsMeterObservationHandlersAndRegistersDistinctGroups() { + Tracer tracer = mock(Tracer.class); + TracingAndMeterObservationHandlerGroup group = new TracingAndMeterObservationHandlerGroup(tracer); + TracingObservationHandler tracingHandler1 = mock(TracingObservationHandler.class); + TracingObservationHandler tracingHandler2 = mock(TracingObservationHandler.class); + MeterObservationHandler meterHandler1 = mock(MeterObservationHandler.class); + MeterObservationHandler meterHandler2 = mock(MeterObservationHandler.class); + ObservationConfig config = mock(ObservationConfig.class); + List> members = List.of(tracingHandler1, meterHandler1, tracingHandler2, meterHandler2); + group.registerMembers(config, members); + ArgumentCaptor> handlerCaptor = ArgumentCaptor.captor(); + then(config).should(times(2)).observationHandler(handlerCaptor.capture()); + List> actualComposites = handlerCaptor.getAllValues(); + assertThat(actualComposites).hasSize(2); + ObservationHandler tracingComposite = actualComposites.get(0); + assertThat(tracingComposite).isInstanceOf(FirstMatchingCompositeObservationHandler.class); + List> tracingHandlers = (List>) Extractors.byName("handlers") + .apply(tracingComposite); + assertThat(tracingHandlers).containsExactly(tracingHandler1, tracingHandler2); + ObservationHandler metricsComposite = actualComposites.get(1); + assertThat(metricsComposite).isInstanceOf(FirstMatchingCompositeObservationHandler.class); + List> metricsHandlers = (List>) Extractors.byName("handlers") + .apply(metricsComposite); + assertThat(metricsHandlers).hasSize(2); + assertThat(metricsHandlers).extracting("delegate").containsExactly(meterHandler1, meterHandler2); + } + + @Test + void registerMembersOnlyUsesCompositeWhenMoreThanOneHandler() { + Tracer tracer = mock(Tracer.class); + TracingAndMeterObservationHandlerGroup group = new TracingAndMeterObservationHandlerGroup(tracer); + TracingObservationHandler tracingHandler1 = mock(TracingObservationHandler.class); + TracingObservationHandler tracingHandler2 = mock(TracingObservationHandler.class); + MeterObservationHandler meterHandler = mock(MeterObservationHandler.class); + ObservationConfig config = mock(ObservationConfig.class); + List> members = List.of(tracingHandler1, meterHandler, tracingHandler2); + group.registerMembers(config, members); + ArgumentCaptor> handlerCaptor = ArgumentCaptor.captor(); + then(config).should(times(2)).observationHandler(handlerCaptor.capture()); + List> actualComposites = handlerCaptor.getAllValues(); + assertThat(actualComposites).hasSize(2); + assertThat(actualComposites.get(0)).isInstanceOf(FirstMatchingCompositeObservationHandler.class); + assertThat(actualComposites.get(1)).isInstanceOf(TracingAwareMeterObservationHandler.class); + } + + private List sort(ObservationHandlerGroup... groups) { + List list = new ArrayList<>(List.of(groups)); + Collections.sort(list); + return list; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingPropertiesTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/TracingPropertiesTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingPropertiesTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/TracingPropertiesTests.java index ab0abe4ca13c..a873c97582d3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingPropertiesTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/TracingPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing; +package org.springframework.boot.tracing.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfigurationIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfigurationIntegrationTests.java index a72d7793aa31..02c5b3efdafc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; +package org.springframework.boot.tracing.autoconfigure.otlp; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -46,12 +46,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.opentelemetry.OpenTelemetryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingAutoConfigurationIntegrationTests.MockGrpcServer.RecordedGrpcRequest; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.tracing.autoconfigure.MicrometerTracingAutoConfiguration; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingAutoConfigurationIntegrationTests.MockGrpcServer.RecordedGrpcRequest; import static org.assertj.core.api.Assertions.assertThat; @@ -65,8 +65,8 @@ class OtlpTracingAutoConfigurationIntegrationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withPropertyValues("management.tracing.sampling.probability=1.0") .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, - MicrometerTracingAutoConfiguration.class, OpenTelemetryAutoConfiguration.class, - org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration.class, + MicrometerTracingAutoConfiguration.class, OpenTelemetrySdkAutoConfiguration.class, + org.springframework.boot.tracing.autoconfigure.OpenTelemetryTracingAutoConfiguration.class, OtlpTracingAutoConfiguration.class)); private final MockWebServer mockWebServer = new MockWebServer(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfigurationTests.java index 247e508489a1..05e7cdb6f5e9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpTracingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/otlp/OtlpTracingAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.otlp; +package org.springframework.boot.tracing.autoconfigure.otlp; import java.time.Duration; import java.util.List; @@ -29,10 +29,10 @@ import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConfigurations.ConnectionDetails.PropertiesOtlpTracingConnectionDetails; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.tracing.autoconfigure.otlp.OtlpTracingConfigurations.ConnectionDetails.PropertiesOtlpTracingConnectionDetails; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/LazyTracingSpanContextTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/prometheus/LazyTracingSpanContextTests.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/LazyTracingSpanContextTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/prometheus/LazyTracingSpanContextTests.java index 8246025664a0..d2f53dc59a64 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/LazyTracingSpanContextTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/prometheus/LazyTracingSpanContextTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.prometheus; +package org.springframework.boot.tracing.autoconfigure.prometheus; import io.micrometer.tracing.Span; import io.micrometer.tracing.TraceContext; @@ -23,7 +23,7 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.tracing.prometheus.PrometheusExemplarsAutoConfiguration.LazyTracingSpanContext; +import org.springframework.boot.tracing.autoconfigure.prometheus.PrometheusExemplarsAutoConfiguration.LazyTracingSpanContext; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfigurationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/prometheus/PrometheusExemplarsAutoConfigurationTests.java similarity index 78% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/prometheus/PrometheusExemplarsAutoConfigurationTests.java index 6aaefe6c5706..c3f542dee354 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/prometheus/PrometheusExemplarsAutoConfigurationTests.java @@ -14,27 +14,31 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.prometheus; +package org.springframework.boot.tracing.autoconfigure.prometheus; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import io.micrometer.prometheusmetrics.PrometheusMeterRegistry; +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.tracer.common.SpanContext; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.export.prometheus.PrometheusMetricsExportAutoConfiguration; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.tracing.autoconfigure.BraveAutoConfiguration; +import org.springframework.boot.tracing.autoconfigure.MicrometerTracingAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; @@ -57,10 +61,11 @@ class PrometheusExemplarsAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withPropertyValues("management.tracing.sampling.probability=1.0", - "management.metrics.distribution.percentiles-histogram.all=true") - .with(MetricsRun.limitedTo(PrometheusMetricsExportAutoConfiguration.class)) + "management.metrics.distribution.percentiles-histogram.all=true", + "management.metrics.use-global-registry=false") .withConfiguration( - AutoConfigurations.of(PrometheusExemplarsAutoConfiguration.class, ObservationAutoConfiguration.class, + AutoConfigurations.of(MetricsAutoConfiguration.class, PrometheusMetricsExportAutoConfiguration.class, + PrometheusExemplarsAutoConfiguration.class, ObservationAutoConfiguration.class, BraveAutoConfiguration.class, MicrometerTracingAutoConfiguration.class)); @Test @@ -85,8 +90,9 @@ void shouldSupplyCustomBeans() { @Test void prometheusOpenMetricsOutputWithoutExemplarsOnHistogramCount() { - this.contextRunner.withPropertyValues( - "management.prometheus.metrics.export.properties.io.prometheus.exporter.exemplarsOnAllMetricTypes=false") + this.contextRunner.withUserConfiguration(TracingConfiguration.class) + .withPropertyValues( + "management.prometheus.metrics.export.properties.io.prometheus.exporter.exemplarsOnAllMetricTypes=false") .run((context) -> { assertThat(context).hasSingleBean(SpanContext.class); ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); @@ -112,7 +118,7 @@ void prometheusOpenMetricsOutputWithoutExemplarsOnHistogramCount() { @Test void prometheusOpenMetricsOutputShouldContainExemplars() { - this.contextRunner.run((context) -> { + this.contextRunner.withUserConfiguration(TracingConfiguration.class).run((context) -> { assertThat(context).hasSingleBean(SpanContext.class); ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); Observation.start("test.observation", observationRegistry).stop(); @@ -157,4 +163,16 @@ SpanContext customSpanContext() { private record TraceInfo(String traceId, String spanId) { } + @Configuration(proxyBeanMethods = false) + static class TracingConfiguration { + + @Bean + TracingAwareMeterObservationHandler tracingAwareMeterObservationHandler( + MeterRegistry meterRegistry, Tracer tracer) { + DefaultMeterObservationHandler delegate = new DefaultMeterObservationHandler(meterRegistry); + return new TracingAwareMeterObservationHandler<>(delegate, tracer); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/DefaultEncodingConfiguration.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/DefaultEncodingConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/DefaultEncodingConfiguration.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/DefaultEncodingConfiguration.java index 4939f6b04045..dec77ece27b4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/DefaultEncodingConfiguration.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/DefaultEncodingConfiguration.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.tracing.autoconfigure.zipkin; import zipkin2.reporter.Encoding; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.zipkin.autoconfigure.ZipkinAutoConfiguration; import org.springframework.context.annotation.Bean; /** diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/NoopSender.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/NoopSender.java index 5031fb37e4ba..fe88e69e001a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/NoopSender.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.tracing.autoconfigure.zipkin; import java.io.IOException; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinConfigurationsBraveConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinConfigurationsBraveConfigurationTests.java index 084451619940..8d200c0d71e3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinConfigurationsBraveConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.tracing.autoconfigure.zipkin; import java.nio.charset.StandardCharsets; @@ -28,10 +28,10 @@ import zipkin2.reporter.Encoding; import zipkin2.reporter.brave.AsyncZipkinSpanHandler; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.tracing.autoconfigure.zipkin.ZipkinTracingAutoConfiguration.BraveConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java rename to spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java index 58b5f30e6f26..c90698e3a0af 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java +++ b/spring-boot-project/spring-boot-tracing/src/test/java/org/springframework/boot/tracing/autoconfigure/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.tracing.autoconfigure.zipkin; import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; import org.junit.jupiter.api.Test; @@ -23,10 +23,10 @@ import zipkin2.reporter.BytesMessageSender; import zipkin2.reporter.Encoding; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.tracing.autoconfigure.zipkin.ZipkinTracingAutoConfiguration.OpenTelemetryConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -42,6 +42,15 @@ class ZipkinConfigurationsOpenTelemetryConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(DefaultEncodingConfiguration.class, OpenTelemetryConfiguration.class)); + @Test + void backsOffWithoutEncoding() { + new ApplicationContextRunner().withUserConfiguration(OpenTelemetryConfiguration.class).run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context).doesNotHaveBean(ZipkinSpanExporter.class); + assertThat(context).doesNotHaveBean(BytesEncoder.class); + }); + } + @Test void shouldSupplyBeans() { this.contextRunner.withUserConfiguration(SenderConfiguration.class, CustomEncoderConfiguration.class) diff --git a/spring-boot-project/spring-boot-tx/build.gradle b/spring-boot-project/spring-boot-tx/build.gradle new file mode 100644 index 000000000000..8018cfe53beb --- /dev/null +++ b/spring-boot-project/spring-boot-tx/build.gradle @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Transaction" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-tx") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("jakarta.transaction:jakarta.transaction-api") + optional("org.springframework:spring-aspects") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("com.github.h-thurow:simple-jndi") + testImplementation("com.zaxxer:HikariCP") + testImplementation("jakarta.persistence:jakarta.persistence-api") + testImplementation("org.hibernate.orm:hibernate-core") + testImplementation("org.hsqldb:hsqldb") + testImplementation("org.springframework:spring-jdbc") + testImplementation("org.springframework:spring-orm") + + testRuntimeOnly(project(":spring-boot-project:spring-boot-reactor")) + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly(project(":spring-boot-project:spring-boot-reactor")) +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/ExecutionListenersTransactionManagerCustomizer.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/ExecutionListenersTransactionManagerCustomizer.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/ExecutionListenersTransactionManagerCustomizer.java rename to spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/ExecutionListenersTransactionManagerCustomizer.java index 001f18065a75..b952a7fafedc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/ExecutionListenersTransactionManagerCustomizer.java +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/ExecutionListenersTransactionManagerCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/dao/PersistenceExceptionTranslationAutoConfiguration.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/PersistenceExceptionTranslationAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/dao/PersistenceExceptionTranslationAutoConfiguration.java rename to spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/PersistenceExceptionTranslationAutoConfiguration.java index 58e3210b3394..85ab210e3b02 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/dao/PersistenceExceptionTranslationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/PersistenceExceptionTranslationAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.dao; +package org.springframework.boot.transaction.autoconfigure; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -32,7 +32,7 @@ * @author Andy Wilkinson * @author Stephane Nicoll * @author Madhura Bhave - * @since 1.2.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(PersistenceExceptionTranslationPostProcessor.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionAutoConfiguration.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionAutoConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionAutoConfiguration.java rename to spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionAutoConfiguration.java index a5228c18fb5c..40dc8ceb9a30 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import org.springframework.boot.LazyInitializationExcludeFilter; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -40,7 +40,7 @@ * Auto-configuration} for Spring transaction. * * @author Stephane Nicoll - * @since 1.3.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(PlatformTransactionManager.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizationAutoConfiguration.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizationAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizationAutoConfiguration.java rename to spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizationAutoConfiguration.java index 67dd1dfbbb23..91e6c6cbe775 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizationAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -30,7 +30,7 @@ * Auto-configuration for the customization of a {@link TransactionManager}. * * @author Andy Wilkinson - * @since 3.2.0 + * @since 4.0.0 */ @ConditionalOnClass(PlatformTransactionManager.class) @AutoConfiguration(before = TransactionAutoConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizer.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizer.java rename to spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizer.java index c6fb89b6510a..e163e7d50f9e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizer.java +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import org.springframework.transaction.TransactionManager; @@ -25,7 +25,7 @@ * * @param the transaction manager type * @author Andy Wilkinson - * @since 3.2.0 + * @since 4.0.0 */ public interface TransactionManagerCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizers.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizers.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizers.java rename to spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizers.java index 1abb1cd46216..fb4073f77b8e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizers.java +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizers.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import java.util.ArrayList; import java.util.Collection; @@ -29,7 +29,7 @@ * * @author Phillip Webb * @author Andy Wilkinson - * @since 1.5.0 + * @since 4.0.0 */ public final class TransactionManagerCustomizers { @@ -42,7 +42,6 @@ private TransactionManagerCustomizers(List> customizers) { return new TransactionManagerCustomizers( diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java rename to spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionProperties.java index d2414e66bd48..f25b45baf549 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/TransactionProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -29,7 +29,7 @@ * * @author Kazuki Shimizu * @author Phillip Webb - * @since 1.5.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.transaction") public class TransactionProperties implements TransactionManagerCustomizer { diff --git a/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/package-info.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/package-info.java new file mode 100644 index 000000000000..039d1b392b25 --- /dev/null +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for transaction support. + */ +package org.springframework.boot.transaction.autoconfigure; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/JndiJtaConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java rename to spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/JndiJtaConfiguration.java index 177aafd0de66..5849699b742e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/JndiJtaConfiguration.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction.jta; +package org.springframework.boot.transaction.jta.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnJndi; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizers; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.jta.JtaTransactionManager; diff --git a/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/JtaAutoConfiguration.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/JtaAutoConfiguration.java new file mode 100644 index 000000000000..91df422fd081 --- /dev/null +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/JtaAutoConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.transaction.jta.autoconfigure; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for JTA. + * + * @author Josh Long + * @author Phillip Webb + * @author Nishant Raut + * @since 4.0.0 + */ +@AutoConfiguration( + before = { TransactionAutoConfiguration.class, TransactionManagerCustomizationAutoConfiguration.class }) +@ConditionalOnClass(jakarta.transaction.Transaction.class) +@ConditionalOnBooleanProperty(name = "spring.jta.enabled", matchIfMissing = true) +@Import(JndiJtaConfiguration.class) +public class JtaAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/package-info.java b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/package-info.java new file mode 100644 index 000000000000..268ff7f8ea1a --- /dev/null +++ b/spring-boot-project/spring-boot-tx/src/main/java/org/springframework/boot/transaction/jta/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JTA. + */ +package org.springframework.boot.transaction.jta.autoconfigure; diff --git a/spring-boot-project/spring-boot-tx/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-tx/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..eff1f2bb286e --- /dev/null +++ b/spring-boot-project/spring-boot-tx/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,16 @@ +{ + "properties": [ + { + "name": "spring.dao.exceptiontranslation.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable the PersistenceExceptionTranslationPostProcessor.", + "defaultValue": true + }, + { + "name": "spring.jta.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable JTA support.", + "defaultValue": true + } + ] +} diff --git a/spring-boot-project/spring-boot-tx/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-tx/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..c5b3ed79eeef --- /dev/null +++ b/spring-boot-project/spring-boot-tx/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.transaction.autoconfigure.PersistenceExceptionTranslationAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration +org.springframework.boot.transaction.autoconfigure.TransactionManagerCustomizationAutoConfiguration +org.springframework.boot.transaction.jta.autoconfigure.JtaAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/ExecutionListenersTransactionManagerCustomizerTests.java b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/ExecutionListenersTransactionManagerCustomizerTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/ExecutionListenersTransactionManagerCustomizerTests.java rename to spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/ExecutionListenersTransactionManagerCustomizerTests.java index e044c32cc7f1..6b5e2112d8d4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/ExecutionListenersTransactionManagerCustomizerTests.java +++ b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/ExecutionListenersTransactionManagerCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import java.util.List; diff --git a/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/PersistenceExceptionTranslationAutoConfigurationTests.java b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/PersistenceExceptionTranslationAutoConfigurationTests.java new file mode 100644 index 000000000000..8115fb06cbd9 --- /dev/null +++ b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/PersistenceExceptionTranslationAutoConfigurationTests.java @@ -0,0 +1,245 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.transaction.autoconfigure; + +import java.io.Serializable; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.HashMap; +import java.util.Map; + +import javax.sql.DataSource; + +import com.zaxxer.hikari.HikariDataSource; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.stereotype.Repository; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +/** + * Tests for {@link PersistenceExceptionTranslationAutoConfiguration} + * + * @author Andy Wilkinson + * @author Stephane Nicoll + */ +class PersistenceExceptionTranslationAutoConfigurationTests { + + private AnnotationConfigApplicationContext context; + + @AfterEach + void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + void exceptionTranslationPostProcessorUsesCglibByDefault() { + this.context = new AnnotationConfigApplicationContext(PersistenceExceptionTranslationAutoConfiguration.class); + Map beans = this.context + .getBeansOfType(PersistenceExceptionTranslationPostProcessor.class); + assertThat(beans).hasSize(1); + assertThat(beans.values().iterator().next().isProxyTargetClass()).isTrue(); + } + + @Test + void exceptionTranslationPostProcessorCanBeConfiguredToUseJdkProxy() { + this.context = new AnnotationConfigApplicationContext(); + TestPropertyValues.of("spring.aop.proxy-target-class=false").applyTo(this.context); + this.context.register(PersistenceExceptionTranslationAutoConfiguration.class); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(PersistenceExceptionTranslationPostProcessor.class); + assertThat(beans).hasSize(1); + assertThat(beans.values().iterator().next().isProxyTargetClass()).isFalse(); + } + + @Test + void exceptionTranslationPostProcessorCanBeDisabled() { + this.context = new AnnotationConfigApplicationContext(); + TestPropertyValues.of("spring.dao.exceptiontranslation.enabled=false").applyTo(this.context); + this.context.register(PersistenceExceptionTranslationAutoConfiguration.class); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(PersistenceExceptionTranslationPostProcessor.class); + assertThat(beans).isEmpty(); + } + + @Test + @WithMetaInfPersistenceXmlResource + void persistOfNullThrowsIllegalArgumentExceptionWithoutExceptionTranslation() { + this.context = new AnnotationConfigApplicationContext(JpaConfiguration.class, TestConfiguration.class); + assertThatIllegalArgumentException().isThrownBy(() -> this.context.getBean(TestRepository.class).doSomething()); + } + + @Test + @WithMetaInfPersistenceXmlResource + void persistOfNullThrowsInvalidDataAccessApiUsageExceptionWithExceptionTranslation() { + this.context = new AnnotationConfigApplicationContext(JpaConfiguration.class, TestConfiguration.class, + PersistenceExceptionTranslationAutoConfiguration.class); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) + .isThrownBy(() -> this.context.getBean(TestRepository.class).doSomething()); + } + + @Configuration(proxyBeanMethods = false) + static class TestConfiguration { + + @Bean + TestRepository testRepository(EntityManagerFactory entityManagerFactory) { + return new TestRepository(entityManagerFactory.createEntityManager()); + } + + } + + @Repository + static class TestRepository { + + private final EntityManager entityManager; + + TestRepository(EntityManager entityManager) { + this.entityManager = entityManager; + } + + void doSomething() { + this.entityManager.persist(null); + } + + } + + @Configuration(proxyBeanMethods = false) + static class JpaConfiguration { + + @Bean + DataSource dataSource() { + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setDriverClassName("org.hsqldb.jdbc.JDBCDriver"); + dataSource.setJdbcUrl("jdbc:hsqldb:mem:tx"); + dataSource.setUsername("sa"); + return dataSource; + } + + @Bean + LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource) { + LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); + localContainerEntityManagerFactoryBean.setDataSource(dataSource); + localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + localContainerEntityManagerFactoryBean.setJpaPropertyMap(configureJpaProperties()); + return localContainerEntityManagerFactoryBean; + } + + private static Map configureJpaProperties() { + Map properties = new HashMap<>(); + properties.put("configured", "manually"); + properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); + return properties; + } + + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @WithResource(name = "META-INF/persistence.xml", + content = """ + + + + org.springframework.boot.transaction.autoconfigure.PersistenceExceptionTranslationAutoConfigurationTests$City + true + + + """) + @interface WithMetaInfPersistenceXmlResource { + + } + + @Entity + public static class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + @Column(nullable = false) + private String country; + + @Column(nullable = false) + private String map; + + protected City() { + } + + City(String name, String state, String country, String map) { + this.name = name; + this.state = state; + this.country = country; + this.map = map; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionAutoConfigurationTests.java b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionAutoConfigurationTests.java index 4ec7422a6341..6e20b56a48c3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionAutoConfigurationTests.java @@ -14,19 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import java.util.UUID; import javax.sql.DataSource; +import com.zaxxer.hikari.HikariDataSource; import org.junit.jupiter.api.Test; import org.springframework.boot.LazyInitializationExcludeFilter; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.AdviceMode; import org.springframework.context.annotation.Bean; @@ -82,8 +80,6 @@ void whenThereIsASingleReactiveTransactionManagerATransactionalOperatorIsAutoCon @Test void whenThereAreBothReactiveAndPlatformTransactionManagersATemplateAndAnOperatorAreAutoConfigured() { this.contextRunner - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class, - DataSourceTransactionManagerAutoConfiguration.class)) .withUserConfiguration(SinglePlatformTransactionManagerConfiguration.class, SingleReactiveTransactionManagerConfiguration.class) .withPropertyValues("spring.datasource.url:jdbc:h2:mem:" + UUID.randomUUID()) @@ -277,11 +273,11 @@ DataSourceTransactionManager transactionManager(DataSource dataSource) { @Bean DataSource dataSource() { - return DataSourceBuilder.create() - .driverClassName("org.hsqldb.jdbc.JDBCDriver") - .url("jdbc:hsqldb:mem:tx") - .username("sa") - .build(); + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setDriverClassName("org.hsqldb.jdbc.JDBCDriver"); + dataSource.setJdbcUrl("jdbc:hsqldb:mem:tx"); + dataSource.setUsername("sa"); + return dataSource; } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizationAutoConfigurationTests.java b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizationAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizationAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizationAutoConfigurationTests.java index d3157fe10e33..088373eb4f55 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizationAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import java.util.Collections; @@ -40,7 +40,7 @@ class TransactionManagerCustomizationAutoConfigurationTests { @Test void autoConfiguresTransactionManagerCustomizers() { - this.contextRunner.run((context) -> { + this.contextRunner.withPropertyValues("spring.transaction.default-timeout=30s").run((context) -> { TransactionManagerCustomizers customizers = context.getBean(TransactionManagerCustomizers.class); assertThat(customizers).extracting("customizers") .asInstanceOf(InstanceOfAssertFactories.LIST) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizersTests.java b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizersTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizersTests.java rename to spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizersTests.java index d3a3f1fe5d67..4be055269cfd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/TransactionManagerCustomizersTests.java +++ b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/autoconfigure/TransactionManagerCustomizersTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction; +package org.springframework.boot.transaction.autoconfigure; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/jta/autoconfigure/JtaAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java rename to spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/jta/autoconfigure/JtaAutoConfigurationTests.java index 88b87ebac34f..db57859c636a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-tx/src/test/java/org/springframework/boot/transaction/jta/autoconfigure/JtaAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.transaction.jta; +package org.springframework.boot.transaction.jta.autoconfigure; import java.util.Arrays; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/jndi.properties b/spring-boot-project/spring-boot-tx/src/test/resources/jndi.properties similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/jndi.properties rename to spring-boot-project/spring-boot-tx/src/test/resources/jndi.properties diff --git a/spring-boot-project/spring-boot-tx/src/test/resources/simple-jndi b/spring-boot-project/spring-boot-tx/src/test/resources/simple-jndi new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/spring-boot-project/spring-boot-undertow/build.gradle b/spring-boot-project/spring-boot-undertow/build.gradle new file mode 100644 index 000000000000..3b6e4cf1ca88 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/build.gradle @@ -0,0 +1,55 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Undertow" + +dependencies { + api(project(":spring-boot-project:spring-boot-web-server")) + api("io.undertow:undertow-servlet") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional("io.undertow:undertow-websockets-jsr") + optional("org.springframework:spring-webflux") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation("org.apache.httpcomponents.client5:httpclient5") + testImplementation("org.apache.tomcat.embed:tomcat-embed-jasper") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("io.projectreactor:reactor-test") + testRuntimeOnly("io.projectreactor.netty:reactor-netty-http") + testRuntimeOnly("org.eclipse.jetty:jetty-client") + testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client") + testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client-transport") + testRuntimeOnly("org.springframework:spring-webmvc") +} + +test { + jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/AccessLogHttpHandlerFactory.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/AccessLogHttpHandlerFactory.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/AccessLogHttpHandlerFactory.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/AccessLogHttpHandlerFactory.java index ddb3a17321b2..7663bb21641e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/AccessLogHttpHandlerFactory.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/AccessLogHttpHandlerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow; import java.io.Closeable; import java.io.File; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/CompressionHttpHandlerFactory.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/CompressionHttpHandlerFactory.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/CompressionHttpHandlerFactory.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/CompressionHttpHandlerFactory.java index e56a4824d290..21ac8256dd16 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/CompressionHttpHandlerFactory.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/CompressionHttpHandlerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/ConfigurableUndertowWebServerFactory.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/ConfigurableUndertowWebServerFactory.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/ConfigurableUndertowWebServerFactory.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/ConfigurableUndertowWebServerFactory.java index 07584a722dd4..e30a9af24505 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/ConfigurableUndertowWebServerFactory.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/ConfigurableUndertowWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow; import java.io.File; import java.util.Collection; @@ -27,9 +27,7 @@ * {@link ConfigurableWebServerFactory} for Undertow-specific features. * * @author Brian Clozel - * @since 2.0.0 - * @see UndertowServletWebServerFactory - * @see UndertowReactiveWebServerFactory + * @since 4.0.0 */ public interface ConfigurableUndertowWebServerFactory extends ConfigurableWebServerFactory { @@ -37,7 +35,7 @@ public interface ConfigurableUndertowWebServerFactory extends ConfigurableWebSer * Set {@link UndertowBuilderCustomizer}s that should be applied to the Undertow * {@link Builder}. Calling this method will replace any existing customizers. * @param customizers the customizers to set - * @since 2.3.0 + * @since 4.0.0 */ void setBuilderCustomizers(Collection customizers); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/HttpHandlerFactory.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/HttpHandlerFactory.java similarity index 91% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/HttpHandlerFactory.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/HttpHandlerFactory.java index 51736c934da1..3ff96a373c9c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/HttpHandlerFactory.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/HttpHandlerFactory.java @@ -14,13 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow; import java.io.Closeable; import io.undertow.server.HttpHandler; import io.undertow.server.handlers.GracefulShutdownHandler; +import org.springframework.boot.undertow.servlet.UndertowServletWebServer; + /** * Factory used by {@link UndertowServletWebServer} to add {@link HttpHandler * HttpHandlers}. Instances returned from this factory may optionally implement the @@ -31,7 +33,7 @@ * * * @author Phillip Webb - * @since 2.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface HttpHandlerFactory { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/SslBuilderCustomizer.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/SslBuilderCustomizer.java index 3cb77107cc3a..d52d936ba977 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/SslBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow; import java.net.InetAddress; import java.util.Map; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowBuilderCustomizer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowBuilderCustomizer.java similarity index 87% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowBuilderCustomizer.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowBuilderCustomizer.java index 6d321200b303..e79ae7a4acd1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowBuilderCustomizer.java @@ -14,15 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow; import io.undertow.Undertow.Builder; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; + /** * Callback interface that can be used to customize an Undertow {@link Builder}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 * @see UndertowServletWebServerFactory */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServer.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServer.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServer.java index 34c70f95f89e..84edb62ccddc 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServer.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow; import java.io.Closeable; import java.io.IOException; @@ -47,7 +47,7 @@ /** * {@link WebServer} that can be used to control an Undertow web server. Usually this - * class should be created using the {@link UndertowReactiveWebServerFactory} and not + * class should be created using a {@link ConfigurableUndertowWebServerFactory} and not * directly. * * @author Ivan Sopov @@ -55,7 +55,7 @@ * @author Eddú Meléndez * @author Christoph Dreis * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ public class UndertowWebServer implements WebServer { @@ -93,7 +93,7 @@ public UndertowWebServer(Undertow.Builder builder, boolean autoStart) { * @param builder the builder * @param httpHandlerFactories the handler factories * @param autoStart if the server should be started - * @since 2.3.0 + * @since 4.0.0 */ public UndertowWebServer(Undertow.Builder builder, Iterable httpHandlerFactories, boolean autoStart) { @@ -117,7 +117,7 @@ public void start() throws WebServerException { } this.undertow.start(); this.started = true; - String message = getStartLogMessage(); + String message = getStartedLogMessage(); logger.info(message); } catch (Exception ex) { @@ -302,7 +302,7 @@ public int getPort() { * Returns the {@link Undertow Undertow server}. Returns {@code null} until the server * has been started. * @return the Undertow server or {@code null} if the server hasn't been started yet - * @since 3.3.0 + * @since 4.0.0 */ public Undertow getUndertow() { return this.undertow; @@ -342,7 +342,7 @@ private void notifyGracefulCallback(boolean success) { } } - protected String getStartLogMessage() { + protected String getStartedLogMessage() { return "Undertow started on " + getPortsDescription(); } diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServerFactory.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServerFactory.java new file mode 100644 index 000000000000..e3f6ed95796a --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/UndertowWebServerFactory.java @@ -0,0 +1,234 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow; + +import java.io.File; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +import io.undertow.Handlers; +import io.undertow.Undertow; +import io.undertow.Undertow.Builder; +import io.undertow.UndertowOptions; + +import org.springframework.boot.ssl.SslBundle; +import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.Compression; +import org.springframework.boot.web.server.Http2; +import org.springframework.boot.web.server.Shutdown; +import org.springframework.boot.web.server.Ssl; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Base class for factories that produce an {@link UndertowWebServer}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public abstract class UndertowWebServerFactory extends AbstractConfigurableWebServerFactory + implements ConfigurableUndertowWebServerFactory { + + private Set builderCustomizers = new LinkedHashSet<>(); + + private Integer bufferSize; + + private Integer ioThreads; + + private Integer workerThreads; + + private Boolean directBuffers; + + private File accessLogDirectory; + + private String accessLogPattern; + + private String accessLogPrefix; + + private String accessLogSuffix; + + private boolean accessLogEnabled; + + private boolean accessLogRotate = true; + + private boolean useForwardHeaders; + + protected UndertowWebServerFactory() { + } + + protected UndertowWebServerFactory(int port) { + super(port); + } + + public Collection getBuilderCustomizers() { + return this.builderCustomizers; + } + + @Override + public void setBuilderCustomizers(Collection customizers) { + Assert.notNull(customizers, "'customizers' must not be null"); + this.builderCustomizers = new LinkedHashSet<>(customizers); + } + + @Override + public void addBuilderCustomizers(UndertowBuilderCustomizer... customizers) { + Assert.notNull(customizers, "'customizers' must not be null"); + this.builderCustomizers.addAll(Arrays.asList(customizers)); + } + + @Override + public void setBufferSize(Integer bufferSize) { + this.bufferSize = bufferSize; + } + + @Override + public void setIoThreads(Integer ioThreads) { + this.ioThreads = ioThreads; + } + + @Override + public void setWorkerThreads(Integer workerThreads) { + this.workerThreads = workerThreads; + } + + @Override + public void setUseDirectBuffers(Boolean directBuffers) { + this.directBuffers = directBuffers; + } + + @Override + public void setAccessLogDirectory(File accessLogDirectory) { + this.accessLogDirectory = accessLogDirectory; + } + + @Override + public void setAccessLogPattern(String accessLogPattern) { + this.accessLogPattern = accessLogPattern; + } + + @Override + public void setAccessLogPrefix(String accessLogPrefix) { + this.accessLogPrefix = accessLogPrefix; + } + + public String getAccessLogPrefix() { + return this.accessLogPrefix; + } + + @Override + public void setAccessLogSuffix(String accessLogSuffix) { + this.accessLogSuffix = accessLogSuffix; + } + + @Override + public void setAccessLogEnabled(boolean accessLogEnabled) { + this.accessLogEnabled = accessLogEnabled; + } + + public boolean isAccessLogEnabled() { + return this.accessLogEnabled; + } + + @Override + public void setAccessLogRotate(boolean accessLogRotate) { + this.accessLogRotate = accessLogRotate; + } + + @Override + public void setUseForwardHeaders(boolean useForwardHeaders) { + this.useForwardHeaders = useForwardHeaders; + } + + public boolean isUseForwardHeaders() { + return this.useForwardHeaders; + } + + public Builder createBuilder(AbstractConfigurableWebServerFactory factory, Supplier sslBundleSupplier, + Supplier> serverNameSslBundlesSupplier) { + InetAddress address = factory.getAddress(); + int port = factory.getPort(); + Builder builder = Undertow.builder(); + if (this.bufferSize != null) { + builder.setBufferSize(this.bufferSize); + } + if (this.ioThreads != null) { + builder.setIoThreads(this.ioThreads); + } + if (this.workerThreads != null) { + builder.setWorkerThreads(this.workerThreads); + } + if (this.directBuffers != null) { + builder.setDirectBuffers(this.directBuffers); + } + Http2 http2 = factory.getHttp2(); + if (http2 != null) { + builder.setServerOption(UndertowOptions.ENABLE_HTTP2, http2.isEnabled()); + } + Ssl ssl = factory.getSsl(); + if (Ssl.isEnabled(ssl)) { + new SslBuilderCustomizer(factory.getPort(), address, ssl.getClientAuth(), sslBundleSupplier.get(), + serverNameSslBundlesSupplier.get()) + .customize(builder); + } + else { + builder.addHttpListener(port, (address != null) ? address.getHostAddress() : "0.0.0.0"); + } + builder.setServerOption(UndertowOptions.SHUTDOWN_TIMEOUT, 0); + for (UndertowBuilderCustomizer customizer : this.builderCustomizers) { + customizer.customize(builder); + } + return builder; + } + + public List createHttpHandlerFactories(AbstractConfigurableWebServerFactory webServerFactory, + HttpHandlerFactory... initialHttpHandlerFactories) { + List factories = createHttpHandlerFactories(webServerFactory.getCompression(), + this.useForwardHeaders, webServerFactory.getServerHeader(), webServerFactory.getShutdown(), + initialHttpHandlerFactories); + if (isAccessLogEnabled()) { + factories.add(new AccessLogHttpHandlerFactory(this.accessLogDirectory, this.accessLogPattern, + this.accessLogPrefix, this.accessLogSuffix, this.accessLogRotate)); + } + return factories; + } + + static List createHttpHandlerFactories(Compression compression, boolean useForwardHeaders, + String serverHeader, Shutdown shutdown, HttpHandlerFactory... initialHttpHandlerFactories) { + List factories = new ArrayList<>(Arrays.asList(initialHttpHandlerFactories)); + if (compression != null && compression.getEnabled()) { + factories.add(new CompressionHttpHandlerFactory(compression)); + } + if (useForwardHeaders) { + factories.add(Handlers::proxyPeerAddress); + } + if (StringUtils.hasText(serverHeader)) { + factories.add((next) -> Handlers.header(next, "Server", serverHeader)); + } + if (shutdown == Shutdown.GRACEFUL) { + factories.add(Handlers::gracefulShutdown); + } + return factories; + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowServerProperties.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowServerProperties.java new file mode 100644 index 000000000000..9aecceb62348 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowServerProperties.java @@ -0,0 +1,405 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure; + +import java.io.File; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.LinkedHashMap; +import java.util.Map; + +import io.undertow.UndertowOptions; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.unit.DataSize; + +/** + * Undertow server properties. + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Ivan Sopov + * @author Marcos Barbero + * @author Eddú Meléndez + * @author Quinten De Swaef + * @author Venil Noronha + * @author Aurélien Leboulanger + * @author Brian Clozel + * @author Olivier Lamy + * @author Chentao Qu + * @author Artsiom Yudovin + * @author Andrew McGhie + * @author Rafiullah Hamedy + * @author Dirk Deyne + * @author HaiTao Zhang + * @author Victor Mandujano + * @author Chris Bono + * @author Parviz Rozikov + * @author Florian Storz + * @author Michael Weidmann + * @author Lasse Wulff + * @since 4.0.0 + */ +@ConfigurationProperties("server.undertow") +public class UndertowServerProperties { + + /** + * Maximum size of the HTTP post content. When the value is -1, the default, the size + * is unlimited. + */ + private DataSize maxHttpPostSize = DataSize.ofBytes(-1); + + /** + * Size of each buffer. The default is derived from the maximum amount of memory that + * is available to the JVM. + */ + private DataSize bufferSize; + + /** + * Whether to allocate buffers outside the Java heap. The default is derived from the + * maximum amount of memory that is available to the JVM. + */ + private Boolean directBuffers; + + /** + * Whether servlet filters should be initialized on startup. + */ + private boolean eagerFilterInit = true; + + /** + * Maximum number of query or path parameters that are allowed. This limit exists to + * prevent hash collision based DOS attacks. + */ + private int maxParameters = UndertowOptions.DEFAULT_MAX_PARAMETERS; + + /** + * Maximum number of headers that are allowed. This limit exists to prevent hash + * collision based DOS attacks. + */ + private int maxHeaders = UndertowOptions.DEFAULT_MAX_HEADERS; + + /** + * Maximum number of cookies that are allowed. This limit exists to prevent hash + * collision based DOS attacks. + */ + private int maxCookies = 200; + + /** + * Whether encoded slash characters (%2F) should be decoded. Decoding can cause + * security problems if a front-end proxy does not perform the same decoding. Only + * enable this if you have a legacy application that requires it. When set, + * server.undertow.allow-encoded-slash has no effect. + */ + private Boolean decodeSlash; + + /** + * Whether the URL should be decoded. When disabled, percent-encoded characters in the + * URL will be left as-is. + */ + private boolean decodeUrl = true; + + /** + * Charset used to decode URLs. + */ + private Charset urlCharset = StandardCharsets.UTF_8; + + /** + * Whether the 'Connection: keep-alive' header should be added to all responses, even + * if not required by the HTTP specification. + */ + private boolean alwaysSetKeepAlive = true; + + /** + * Amount of time a connection can sit idle without processing a request, before it is + * closed by the server. + */ + private Duration noRequestTimeout; + + /** + * Whether to preserve the path of a request when it is forwarded. + */ + private boolean preservePathOnForward = false; + + private final Accesslog accesslog = new Accesslog(); + + /** + * Thread related configuration. + */ + private final Threads threads = new Threads(); + + private final Options options = new Options(); + + public DataSize getMaxHttpPostSize() { + return this.maxHttpPostSize; + } + + public void setMaxHttpPostSize(DataSize maxHttpPostSize) { + this.maxHttpPostSize = maxHttpPostSize; + } + + public DataSize getBufferSize() { + return this.bufferSize; + } + + public void setBufferSize(DataSize bufferSize) { + this.bufferSize = bufferSize; + } + + public Boolean getDirectBuffers() { + return this.directBuffers; + } + + public void setDirectBuffers(Boolean directBuffers) { + this.directBuffers = directBuffers; + } + + public boolean isEagerFilterInit() { + return this.eagerFilterInit; + } + + public void setEagerFilterInit(boolean eagerFilterInit) { + this.eagerFilterInit = eagerFilterInit; + } + + public int getMaxParameters() { + return this.maxParameters; + } + + public void setMaxParameters(Integer maxParameters) { + this.maxParameters = maxParameters; + } + + public int getMaxHeaders() { + return this.maxHeaders; + } + + public void setMaxHeaders(int maxHeaders) { + this.maxHeaders = maxHeaders; + } + + public Integer getMaxCookies() { + return this.maxCookies; + } + + public void setMaxCookies(Integer maxCookies) { + this.maxCookies = maxCookies; + } + + public Boolean getDecodeSlash() { + return this.decodeSlash; + } + + public void setDecodeSlash(Boolean decodeSlash) { + this.decodeSlash = decodeSlash; + } + + public boolean isDecodeUrl() { + return this.decodeUrl; + } + + public void setDecodeUrl(Boolean decodeUrl) { + this.decodeUrl = decodeUrl; + } + + public Charset getUrlCharset() { + return this.urlCharset; + } + + public void setUrlCharset(Charset urlCharset) { + this.urlCharset = urlCharset; + } + + public boolean isAlwaysSetKeepAlive() { + return this.alwaysSetKeepAlive; + } + + public void setAlwaysSetKeepAlive(boolean alwaysSetKeepAlive) { + this.alwaysSetKeepAlive = alwaysSetKeepAlive; + } + + public Duration getNoRequestTimeout() { + return this.noRequestTimeout; + } + + public void setNoRequestTimeout(Duration noRequestTimeout) { + this.noRequestTimeout = noRequestTimeout; + } + + public boolean isPreservePathOnForward() { + return this.preservePathOnForward; + } + + public void setPreservePathOnForward(boolean preservePathOnForward) { + this.preservePathOnForward = preservePathOnForward; + } + + public UndertowServerProperties.Accesslog getAccesslog() { + return this.accesslog; + } + + public UndertowServerProperties.Threads getThreads() { + return this.threads; + } + + public UndertowServerProperties.Options getOptions() { + return this.options; + } + + /** + * Undertow access log properties. + */ + public static class Accesslog { + + /** + * Whether to enable the access log. + */ + private boolean enabled = false; + + /** + * Format pattern for access logs. + */ + private String pattern = "common"; + + /** + * Log file name prefix. + */ + protected String prefix = "access_log."; + + /** + * Log file name suffix. + */ + private String suffix = "log"; + + /** + * Undertow access log directory. + */ + private File dir = new File("logs"); + + /** + * Whether to enable access log rotation. + */ + private boolean rotate = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getPattern() { + return this.pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return this.suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public File getDir() { + return this.dir; + } + + public void setDir(File dir) { + this.dir = dir; + } + + public boolean isRotate() { + return this.rotate; + } + + public void setRotate(boolean rotate) { + this.rotate = rotate; + } + + } + + /** + * Undertow thread properties. + */ + public static class Threads { + + /** + * Number of I/O threads to create for the worker. The default is derived from the + * number of available processors. + */ + private Integer io; + + /** + * Number of worker threads. The default is 8 times the number of I/O threads. + */ + private Integer worker; + + public Integer getIo() { + return this.io; + } + + public void setIo(Integer io) { + this.io = io; + } + + public Integer getWorker() { + return this.worker; + } + + public void setWorker(Integer worker) { + this.worker = worker; + } + + } + + public static class Options { + + /** + * Socket options as defined in org.xnio.Options. + */ + private final Map socket = new LinkedHashMap<>(); + + /** + * Server options as defined in io.undertow.UndertowOptions. + */ + private final Map server = new LinkedHashMap<>(); + + public Map getServer() { + return this.server; + } + + public Map getSocket() { + return this.socket; + } + + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerConfiguration.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerConfiguration.java new file mode 100644 index 000000000000..0d62db92d32e --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; +import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; +import org.springframework.boot.autoconfigure.thread.Threading; +import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.core.task.VirtualThreadTaskExecutor; + +/** + * {@link Configuration Configuration} for an Undertow-based reactive or servlet web + * server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@ConditionalOnNotWarDeployment +@Configuration(proxyBeanMethods = false) +public class UndertowWebServerConfiguration { + + @Bean + UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment, + ServerProperties serverProperties, UndertowServerProperties undertowProperties) { + return new UndertowWebServerFactoryCustomizer(environment, serverProperties, undertowProperties); + } + + @Bean + @ConditionalOnThreading(Threading.VIRTUAL) + UndertowDeploymentInfoCustomizer virtualThreadsUndertowDeploymentInfoCustomizer() { + return (deploymentInfo) -> deploymentInfo.setExecutor(new VirtualThreadTaskExecutor("undertow-")); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizer.java similarity index 77% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizer.java index 1cfb0ff6f73a..d05fa0b6ca3b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.undertow.autoconfigure; import java.lang.reflect.Modifier; import java.nio.charset.Charset; @@ -29,13 +29,12 @@ import org.xnio.Option; import org.xnio.Options; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties.Undertow; -import org.springframework.boot.autoconfigure.web.ServerProperties.Undertow.Accesslog; import org.springframework.boot.cloud.CloudPlatform; import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.embedded.undertow.ConfigurableUndertowWebServerFactory; +import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory; +import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties.Accesslog; import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.core.Ordered; import org.springframework.core.env.Environment; import org.springframework.util.Assert; @@ -54,7 +53,7 @@ * @author Arstiom Yudovin * @author Rafiullah Hamedy * @author HaiTao Zhang - * @since 2.0.0 + * @since 4.0.0 */ public class UndertowWebServerFactoryCustomizer implements WebServerFactoryCustomizer, Ordered { @@ -63,9 +62,13 @@ public class UndertowWebServerFactoryCustomizer private final ServerProperties serverProperties; - public UndertowWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) { + private final UndertowServerProperties undertowProperties; + + public UndertowWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties, + UndertowServerProperties undertowProperties) { this.environment = environment; this.serverProperties = serverProperties; + this.undertowProperties = undertowProperties; } @Override @@ -88,35 +91,38 @@ public void customize(ConfigurableUndertowWebServerFactory factory) { private void mapUndertowProperties(ConfigurableUndertowWebServerFactory factory, ServerOptions serverOptions) { PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - Undertow properties = this.serverProperties.getUndertow(); - map.from(properties::getBufferSize).whenNonNull().asInt(DataSize::toBytes).to(factory::setBufferSize); - ServerProperties.Undertow.Threads threadProperties = properties.getThreads(); + map.from(this.undertowProperties::getBufferSize) + .whenNonNull() + .asInt(DataSize::toBytes) + .to(factory::setBufferSize); + UndertowServerProperties.Threads threadProperties = this.undertowProperties.getThreads(); map.from(threadProperties::getIo).to(factory::setIoThreads); map.from(threadProperties::getWorker).to(factory::setWorkerThreads); - map.from(properties::getDirectBuffers).to(factory::setUseDirectBuffers); - map.from(properties::getMaxHttpPostSize) + map.from(this.undertowProperties::getDirectBuffers).to(factory::setUseDirectBuffers); + map.from(this.undertowProperties::getMaxHttpPostSize) .as(DataSize::toBytes) .when(this::isPositive) .to(serverOptions.option(UndertowOptions.MAX_ENTITY_SIZE)); - map.from(properties::getMaxParameters).to(serverOptions.option(UndertowOptions.MAX_PARAMETERS)); - map.from(properties::getMaxHeaders).to(serverOptions.option(UndertowOptions.MAX_HEADERS)); - map.from(properties::getMaxCookies).to(serverOptions.option(UndertowOptions.MAX_COOKIES)); - mapSlashProperties(properties, serverOptions); - map.from(properties::isDecodeUrl).to(serverOptions.option(UndertowOptions.DECODE_URL)); - map.from(properties::getUrlCharset).as(Charset::name).to(serverOptions.option(UndertowOptions.URL_CHARSET)); - map.from(properties::isAlwaysSetKeepAlive).to(serverOptions.option(UndertowOptions.ALWAYS_SET_KEEP_ALIVE)); - map.from(properties::getNoRequestTimeout) + map.from(this.undertowProperties::getMaxParameters).to(serverOptions.option(UndertowOptions.MAX_PARAMETERS)); + map.from(this.undertowProperties::getMaxHeaders).to(serverOptions.option(UndertowOptions.MAX_HEADERS)); + map.from(this.undertowProperties::getMaxCookies).to(serverOptions.option(UndertowOptions.MAX_COOKIES)); + mapSlashProperty(this.undertowProperties, serverOptions); + map.from(this.undertowProperties::isDecodeUrl).to(serverOptions.option(UndertowOptions.DECODE_URL)); + map.from(this.undertowProperties::getUrlCharset) + .as(Charset::name) + .to(serverOptions.option(UndertowOptions.URL_CHARSET)); + map.from(this.undertowProperties::isAlwaysSetKeepAlive) + .to(serverOptions.option(UndertowOptions.ALWAYS_SET_KEEP_ALIVE)); + map.from(this.undertowProperties::getNoRequestTimeout) .asInt(Duration::toMillis) .to(serverOptions.option(UndertowOptions.NO_REQUEST_TIMEOUT)); - map.from(properties.getOptions()::getServer).to(serverOptions.forEach(serverOptions::option)); + map.from(this.undertowProperties.getOptions()::getServer).to(serverOptions.forEach(serverOptions::option)); SocketOptions socketOptions = new SocketOptions(factory); - map.from(properties.getOptions()::getSocket).to(socketOptions.forEach(socketOptions::option)); + map.from(this.undertowProperties.getOptions()::getSocket).to(socketOptions.forEach(socketOptions::option)); } - @SuppressWarnings({ "deprecation", "removal" }) - private void mapSlashProperties(Undertow properties, ServerOptions serverOptions) { + private void mapSlashProperty(UndertowServerProperties properties, ServerOptions serverOptions) { PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(properties::isAllowEncodedSlash).to(serverOptions.option(UndertowOptions.ALLOW_ENCODED_SLASH)); map.from(properties::getDecodeSlash).to(serverOptions.option(UndertowOptions.DECODE_SLASH)); } @@ -126,7 +132,7 @@ private boolean isPositive(Number value) { } private void mapAccessLogProperties(ConfigurableUndertowWebServerFactory factory) { - Accesslog properties = this.serverProperties.getUndertow().getAccesslog(); + Accesslog properties = this.undertowProperties.getAccesslog(); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); map.from(properties::isEnabled).to(factory::setAccessLogEnabled); map.from(properties::getDir).to(factory::setAccessLogDirectory); diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowAccessLogCustomizer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowAccessLogCustomizer.java new file mode 100644 index 000000000000..765738842c43 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowAccessLogCustomizer.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.actuate.web; + +import java.util.function.Function; + +import org.springframework.boot.actuate.autoconfigure.web.server.AccessLogCustomizer; +import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory; + +/** + * {@link AccessLogCustomizer} for Undertow. + * + * @param the type of factory that can be customized + * @author Andy Wilkinson + */ +class UndertowAccessLogCustomizer extends AccessLogCustomizer { + + private final Function accessLogPrefixExtractor; + + UndertowAccessLogCustomizer(UndertowManagementServerProperties properties, + Function accessLogPrefixExtractor) { + super(properties.getAccesslog().getPrefix()); + this.accessLogPrefixExtractor = accessLogPrefixExtractor; + } + + @Override + public void customize(T factory) { + factory.setAccessLogPrefix(customizePrefix(this.accessLogPrefixExtractor.apply(factory))); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerProperties.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerProperties.java new file mode 100644 index 000000000000..c5f674c5a086 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerProperties.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.actuate.web; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Properties for an Undertow-based management server. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +@ConfigurationProperties("management.server.undertow") +public class UndertowManagementServerProperties { + + private final Accesslog accesslog = new Accesslog(); + + public Accesslog getAccesslog() { + return this.accesslog; + } + + public static class Accesslog { + + /** + * Management log file name prefix. + */ + private String prefix = "management_"; + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowReactiveManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowReactiveManagementChildContextConfiguration.java new file mode 100644 index 000000000000..cafef5f1ef84 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowReactiveManagementChildContextConfiguration.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.actuate.web; + +import io.undertow.Undertow; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.undertow.autoconfigure.reactive.UndertowReactiveWebServerAutoConfiguration; +import org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for + * Undertow-based reactive web endpoint infrastructure when a separate management context + * running on a different port is required. + * + * @author Andy Wilkinson + */ +@ConditionalOnClass(Undertow.class) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@EnableConfigurationProperties(UndertowManagementServerProperties.class) +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +class UndertowReactiveManagementChildContextConfiguration { + + @Bean + static ManagementContextFactory reactiveWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, + UndertowReactiveWebServerAutoConfiguration.class); + } + + @Bean + UndertowAccessLogCustomizer undertowManagementAccessLogCustomizer( + UndertowManagementServerProperties properties) { + return new UndertowAccessLogCustomizer<>(properties, UndertowReactiveWebServerFactory::getAccessLogPrefix); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowReactiveManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowReactiveManagementContextAutoConfiguration.java new file mode 100644 index 000000000000..233916ec6a6c --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowReactiveManagementContextAutoConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.actuate.web; + +import io.undertow.Undertow; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.undertow.autoconfigure.reactive.UndertowReactiveWebServerAutoConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * Auto-configuration for an Undertow-based reactive management context. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ Undertow.class, ManagementContextFactory.class }) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) +public class UndertowReactiveManagementContextAutoConfiguration { + + @Bean + static ManagementContextFactory reactiveWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class, + UndertowReactiveWebServerAutoConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowServletManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowServletManagementChildContextConfiguration.java new file mode 100644 index 000000000000..88b6cb8e118b --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowServletManagementChildContextConfiguration.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.actuate.web; + +import io.undertow.Undertow; + +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for + * Undertow-based servlet web endpoint infrastructure when a separate management context + * running on a different port is required. + * + * @author Andy Wilkinson + */ +@ConditionalOnClass(Undertow.class) +@ConditionalOnWebApplication(type = Type.SERVLET) +@EnableConfigurationProperties(UndertowManagementServerProperties.class) +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +class UndertowServletManagementChildContextConfiguration { + + @Bean + UndertowAccessLogCustomizer undertowManagementAccessLogCustomizer( + UndertowManagementServerProperties properties) { + return new UndertowAccessLogCustomizer<>(properties, UndertowServletWebServerFactory::getAccessLogPrefix); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowServletManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowServletManagementContextAutoConfiguration.java new file mode 100644 index 000000000000..5bc4eb18d125 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowServletManagementContextAutoConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.actuate.web; + +import io.undertow.Undertow; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.undertow.autoconfigure.servlet.UndertowServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; + +/** + * Auto-configuration for an Undertow-based servlet management context. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ Undertow.class, ManagementContextFactory.class }) +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnManagementPort(ManagementPortType.DIFFERENT) +public class UndertowServletManagementContextAutoConfiguration { + + @Bean + static ManagementContextFactory servletWebChildContextFactory() { + return new ManagementContextFactory(WebApplicationType.SERVLET, ServletWebServerFactory.class, + UndertowServletWebServerAutoConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/package-info.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/package-info.java new file mode 100644 index 000000000000..7401644e6286 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/actuate/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator Undertow actuator web concerns. + */ +package org.springframework.boot.undertow.autoconfigure.actuate.web; diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/package-info.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/package-info.java new file mode 100644 index 000000000000..cc63f9a246ee --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a servlet or reactive web server using + * Undertow. + */ +package org.springframework.boot.undertow.autoconfigure; diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfiguration.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfiguration.java new file mode 100644 index 000000000000..f9c03f585701 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfiguration.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.reactive; + +import io.undertow.Undertow; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties; +import org.springframework.boot.undertow.autoconfigure.UndertowWebServerConfiguration; +import org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory; +import org.springframework.boot.web.server.autoconfigure.reactive.ReactiveWebServerConfiguration; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.http.ReactiveHttpInputMessage; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for an Undertow-based reactive web + * server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ReactiveHttpInputMessage.class, Undertow.class }) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +@EnableConfigurationProperties(UndertowServerProperties.class) +@Import({ UndertowWebServerConfiguration.class, ReactiveWebServerConfiguration.class }) +public class UndertowReactiveWebServerAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(ReactiveWebServerFactory.class) + UndertowReactiveWebServerFactory undertowReactiveWebServerFactory( + ObjectProvider builderCustomizers) { + UndertowReactiveWebServerFactory factory = new UndertowReactiveWebServerFactory(); + factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList()); + return factory; + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..9378b2cfed16 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a reactive web server using Undertow. + */ +package org.springframework.boot.undertow.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfiguration.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfiguration.java new file mode 100644 index 000000000000..bf5fc5e53e4d --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfiguration.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.servlet; + +import io.undertow.Undertow; +import io.undertow.websockets.jsr.Bootstrap; +import jakarta.servlet.ServletRequest; +import org.xnio.SslClientAuthMode; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.autoconfigure.condition.SearchStrategy; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties; +import org.springframework.boot.undertow.autoconfigure.UndertowWebServerConfiguration; +import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.autoconfigure.servlet.ServletWebServerConfiguration; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for an Undertow-based servlet web + * server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ServletRequest.class, Undertow.class, SslClientAuthMode.class }) +@ConditionalOnWebApplication(type = Type.SERVLET) +@EnableConfigurationProperties(UndertowServerProperties.class) +@Import({ UndertowWebServerConfiguration.class, ServletWebServerConfiguration.class }) +public class UndertowServletWebServerAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT) + UndertowServletWebServerFactory undertowServletWebServerFactory( + ObjectProvider deploymentInfoCustomizers, + ObjectProvider builderCustomizers) { + UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(); + factory.getDeploymentInfoCustomizers().addAll(deploymentInfoCustomizers.orderedStream().toList()); + factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList()); + return factory; + } + + @Bean + UndertowServletWebServerFactoryCustomizer undertowServletWebServerFactoryCustomizer( + UndertowServerProperties undertowProperties) { + return new UndertowServletWebServerFactoryCustomizer(undertowProperties); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(Bootstrap.class) + static class UndertowWebSocketConfiguration { + + @Bean + @ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer") + WebSocketUndertowServletWebServerFactoryCustomizer websocketServletWebServerCustomizer() { + return new WebSocketUndertowServletWebServerFactoryCustomizer(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..c354bff57956 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizer.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.servlet; + +import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; + +/** + * {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} to Undertow + * Servlet web servers. + * + * @author Andy Wilkinson + */ +class UndertowServletWebServerFactoryCustomizer implements WebServerFactoryCustomizer { + + private final UndertowServerProperties undertowProperties; + + UndertowServletWebServerFactoryCustomizer(UndertowServerProperties undertowProperties) { + this.undertowProperties = undertowProperties; + } + + @Override + public void customize(UndertowServletWebServerFactory factory) { + factory.setEagerFilterInit(this.undertowProperties.isEagerFilterInit()); + factory.setPreservePathOnForward(this.undertowProperties.isPreservePathOnForward()); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/WebSocketUndertowServletWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/WebSocketUndertowServletWebServerFactoryCustomizer.java new file mode 100644 index 000000000000..3db28703f37d --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/WebSocketUndertowServletWebServerFactoryCustomizer.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.servlet; + +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.websockets.jsr.WebSocketDeploymentInfo; + +import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.core.Ordered; + +/** + * WebSocket customizer for {@link UndertowServletWebServerFactory}. + * + * @author Phillip Webb + * @since 4.0.0 + */ +public class WebSocketUndertowServletWebServerFactoryCustomizer + implements WebServerFactoryCustomizer, Ordered { + + @Override + public void customize(UndertowServletWebServerFactory factory) { + WebsocketDeploymentInfoCustomizer customizer = new WebsocketDeploymentInfoCustomizer(); + factory.addDeploymentInfoCustomizers(customizer); + } + + @Override + public int getOrder() { + return 0; + } + + private static final class WebsocketDeploymentInfoCustomizer implements UndertowDeploymentInfoCustomizer { + + @Override + public void customize(DeploymentInfo deploymentInfo) { + WebSocketDeploymentInfo info = new WebSocketDeploymentInfo(); + deploymentInfo.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, info); + } + + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..9539702d0d14 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a servlet web server using Undertow. + */ +package org.springframework.boot.undertow.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/package-info.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/package-info.java new file mode 100644 index 000000000000..cff413d94848 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive and servlet web server implementations backed by Undertow. + * + * @see org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory + * @see org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory + */ +package org.springframework.boot.undertow; diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactory.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactory.java new file mode 100644 index 000000000000..1186df74cf34 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactory.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.reactive; + +import java.util.List; + +import io.undertow.Undertow; + +import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory; +import org.springframework.boot.undertow.HttpHandlerFactory; +import org.springframework.boot.undertow.UndertowWebServer; +import org.springframework.boot.undertow.UndertowWebServerFactory; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.http.server.reactive.UndertowHttpHandlerAdapter; + +/** + * {@link ReactiveWebServerFactory} that can be used to create {@link UndertowWebServer}s. + * + * @author Brian Clozel + * @author Scott Frederick + * @since 4.0.0 + */ +public class UndertowReactiveWebServerFactory extends UndertowWebServerFactory + implements ConfigurableUndertowWebServerFactory, ConfigurableReactiveWebServerFactory { + + /** + * Create a new {@link UndertowReactiveWebServerFactory} instance. + */ + public UndertowReactiveWebServerFactory() { + } + + /** + * Create a new {@link UndertowReactiveWebServerFactory} that listens for requests + * using the specified port. + * @param port the port to listen on + */ + public UndertowReactiveWebServerFactory(int port) { + super(port); + } + + @Override + public WebServer getWebServer(org.springframework.http.server.reactive.HttpHandler httpHandler) { + Undertow.Builder builder = createBuilder(this, this::getSslBundle, this::getServerNameSslBundles); + List httpHandlerFactories = createHttpHandlerFactories(this, + (next) -> new UndertowHttpHandlerAdapter(httpHandler)); + return new UndertowWebServer(builder, httpHandlerFactories, getPort() >= 0); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/package-info.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/package-info.java new file mode 100644 index 000000000000..33979942ccda --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive web server implementation backed by Undertow. + */ +package org.springframework.boot.undertow.reactive; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/CompositeResourceManager.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/CompositeResourceManager.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/CompositeResourceManager.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/CompositeResourceManager.java index 9921e5909c92..c99681bcc1a2 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/CompositeResourceManager.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/CompositeResourceManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import java.io.IOException; import java.util.Arrays; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/DeploymentManagerHttpHandlerFactory.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/DeploymentManagerHttpHandlerFactory.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/DeploymentManagerHttpHandlerFactory.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/DeploymentManagerHttpHandlerFactory.java index 58bd09fcd703..2175b70214f6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/DeploymentManagerHttpHandlerFactory.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/DeploymentManagerHttpHandlerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import java.io.Closeable; import java.io.IOException; @@ -24,6 +24,7 @@ import io.undertow.servlet.api.DeploymentManager; import jakarta.servlet.ServletException; +import org.springframework.boot.undertow.HttpHandlerFactory; import org.springframework.util.Assert; /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/FileSessionPersistence.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/FileSessionPersistence.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/FileSessionPersistence.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/FileSessionPersistence.java index bc13bcc5cdcd..c30d38dfca73 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/FileSessionPersistence.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/FileSessionPersistence.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import java.io.File; import java.io.FileInputStream; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/JarResourceManager.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/JarResourceManager.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/JarResourceManager.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/JarResourceManager.java index 8db3afdc0c4a..5fb6c7a61351 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/JarResourceManager.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/JarResourceManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import java.io.File; import java.io.IOException; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowDeploymentInfoCustomizer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowDeploymentInfoCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowDeploymentInfoCustomizer.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowDeploymentInfoCustomizer.java index 21a30fd6b8e3..194f6d0a8431 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowDeploymentInfoCustomizer.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowDeploymentInfoCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import io.undertow.servlet.api.DeploymentInfo; @@ -22,7 +22,7 @@ * Callback interface that can be used to customize an Undertow {@link DeploymentInfo}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 * @see UndertowServletWebServerFactory */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServer.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServer.java similarity index 89% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServer.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServer.java index 933a96d674a4..94f511bafcd6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServer.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServer.java @@ -14,13 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import io.undertow.Handlers; import io.undertow.Undertow.Builder; import io.undertow.server.HttpHandler; import io.undertow.servlet.api.DeploymentManager; +import org.springframework.boot.undertow.HttpHandlerFactory; +import org.springframework.boot.undertow.UndertowWebServer; import org.springframework.boot.web.server.WebServer; import org.springframework.util.StringUtils; @@ -34,7 +36,7 @@ * @author Eddú Meléndez * @author Christoph Dreis * @author Kristine Jetzke - * @since 2.0.0 + * @since 4.0.0 * @see UndertowServletWebServerFactory */ public class UndertowServletWebServer extends UndertowWebServer { @@ -49,7 +51,7 @@ public class UndertowServletWebServer extends UndertowWebServer { * @param httpHandlerFactories the handler factories * @param contextPath the root context path * @param autoStart if the server should be started - * @since 2.3.0 + * @since 4.0.0 */ public UndertowServletWebServer(Builder builder, Iterable httpHandlerFactories, String contextPath, boolean autoStart) { @@ -77,9 +79,9 @@ protected HttpHandler createHttpHandler() { } @Override - protected String getStartLogMessage() { + protected String getStartedLogMessage() { String contextPath = StringUtils.hasText(this.contextPath) ? this.contextPath : "/"; - StringBuilder message = new StringBuilder(super.getStartLogMessage()); + StringBuilder message = new StringBuilder(super.getStartedLogMessage()); message.append(" with context path '"); message.append(contextPath); message.append("'"); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactory.java similarity index 82% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java rename to spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactory.java index bd80197f372c..0698d38e2dd3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import java.io.File; import java.io.IOException; @@ -59,16 +59,24 @@ import jakarta.servlet.ServletContainerInitializer; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.undertow.HttpHandlerFactory; +import org.springframework.boot.undertow.UndertowWebServerFactory; +import org.springframework.boot.web.error.ErrorPage; import org.springframework.boot.web.server.Cookie.SameSite; -import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.MimeMappings.Mapping; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ContextPath; +import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier; +import org.springframework.boot.web.server.servlet.DocumentRoot; +import org.springframework.boot.web.server.servlet.ServletContextInitializers; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerSettings; import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; -import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; @@ -86,17 +94,19 @@ * @author Marcos Barbero * @author Eddú Meléndez * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 * @see UndertowServletWebServer */ -public class UndertowServletWebServerFactory extends AbstractServletWebServerFactory - implements ConfigurableUndertowWebServerFactory, ResourceLoaderAware { +public class UndertowServletWebServerFactory extends UndertowWebServerFactory + implements ConfigurableServletWebServerFactory, ResourceLoaderAware { + + private static final Log logger = LogFactory.getLog(UndertowServletWebServerFactory.class); private static final Pattern ENCODED_SLASH = Pattern.compile("%2F", Pattern.LITERAL); private static final Set> NO_CLASSES = Collections.emptySet(); - private final UndertowWebServerFactoryDelegate delegate = new UndertowWebServerFactoryDelegate(); + private final ServletWebServerSettings settings = new ServletWebServerSettings(); private Set deploymentInfoCustomizers = new LinkedHashSet<>(); @@ -110,7 +120,7 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac * Create a new {@link UndertowServletWebServerFactory} instance. */ public UndertowServletWebServerFactory() { - getJsp().setRegistered(false); + getSettings().getJsp().setRegistered(false); } /** @@ -120,7 +130,7 @@ public UndertowServletWebServerFactory() { */ public UndertowServletWebServerFactory(int port) { super(port); - getJsp().setRegistered(false); + getSettings().getJsp().setRegistered(false); } /** @@ -130,94 +140,18 @@ public UndertowServletWebServerFactory(int port) { * @param port the port to listen on */ public UndertowServletWebServerFactory(String contextPath, int port) { - super(contextPath, port); - getJsp().setRegistered(false); - } - - @Override - public void setBuilderCustomizers(Collection customizers) { - this.delegate.setBuilderCustomizers(customizers); - } - - @Override - public void addBuilderCustomizers(UndertowBuilderCustomizer... customizers) { - this.delegate.addBuilderCustomizers(customizers); + super(port); + getSettings().setContextPath(ContextPath.of(contextPath)); + getSettings().getJsp().setRegistered(false); } /** - * Returns a mutable collection of the {@link UndertowBuilderCustomizer}s that will be - * applied to the Undertow {@link Builder}. + * Returns a mutable collection of the {@link UndertowDeploymentInfoCustomizer}s that + * will be applied to the Undertow {@link DeploymentInfo}. * @return the customizers that will be applied */ - public Collection getBuilderCustomizers() { - return this.delegate.getBuilderCustomizers(); - } - - @Override - public void setBufferSize(Integer bufferSize) { - this.delegate.setBufferSize(bufferSize); - } - - @Override - public void setIoThreads(Integer ioThreads) { - this.delegate.setIoThreads(ioThreads); - } - - @Override - public void setWorkerThreads(Integer workerThreads) { - this.delegate.setWorkerThreads(workerThreads); - } - - @Override - public void setUseDirectBuffers(Boolean directBuffers) { - this.delegate.setUseDirectBuffers(directBuffers); - } - - @Override - public void setAccessLogDirectory(File accessLogDirectory) { - this.delegate.setAccessLogDirectory(accessLogDirectory); - } - - @Override - public void setAccessLogPattern(String accessLogPattern) { - this.delegate.setAccessLogPattern(accessLogPattern); - } - - @Override - public void setAccessLogPrefix(String accessLogPrefix) { - this.delegate.setAccessLogPrefix(accessLogPrefix); - } - - public String getAccessLogPrefix() { - return this.delegate.getAccessLogPrefix(); - } - - @Override - public void setAccessLogSuffix(String accessLogSuffix) { - this.delegate.setAccessLogSuffix(accessLogSuffix); - } - - @Override - public void setAccessLogEnabled(boolean accessLogEnabled) { - this.delegate.setAccessLogEnabled(accessLogEnabled); - } - - public boolean isAccessLogEnabled() { - return this.delegate.isAccessLogEnabled(); - } - - @Override - public void setAccessLogRotate(boolean accessLogRotate) { - this.delegate.setAccessLogRotate(accessLogRotate); - } - - @Override - public void setUseForwardHeaders(boolean useForwardHeaders) { - this.delegate.setUseForwardHeaders(useForwardHeaders); - } - - protected final boolean isUseForwardHeaders() { - return this.delegate.isUseForwardHeaders(); + public Collection getDeploymentInfoCustomizers() { + return this.deploymentInfoCustomizers; } /** @@ -241,15 +175,6 @@ public void addDeploymentInfoCustomizers(UndertowDeploymentInfoCustomizer... cus this.deploymentInfoCustomizers.addAll(Arrays.asList(customizers)); } - /** - * Returns a mutable collection of the {@link UndertowDeploymentInfoCustomizer}s that - * will be applied to the Undertow {@link DeploymentInfo}. - * @return the customizers that will be applied - */ - public Collection getDeploymentInfoCustomizers() { - return this.deploymentInfoCustomizers; - } - @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; @@ -258,7 +183,6 @@ public void setResourceLoader(ResourceLoader resourceLoader) { /** * Return if filters should be eagerly initialized. * @return {@code true} if filters are eagerly initialized, otherwise {@code false}. - * @since 2.4.0 */ public boolean isEagerFilterInit() { return this.eagerFilterInit; @@ -268,7 +192,6 @@ public boolean isEagerFilterInit() { * Set whether filters should be eagerly initialized. * @param eagerFilterInit {@code true} if filters are eagerly initialized, otherwise * {@code false}. - * @since 2.4.0 */ public void setEagerFilterInit(boolean eagerFilterInit) { this.eagerFilterInit = eagerFilterInit; @@ -278,7 +201,6 @@ public void setEagerFilterInit(boolean eagerFilterInit) { * Return whether the request path should be preserved on forward. * @return {@code true} if the path should be preserved when a request is forwarded, * otherwise {@code false}. - * @since 2.4.0 */ public boolean isPreservePathOnForward() { return this.preservePathOnForward; @@ -288,7 +210,6 @@ public boolean isPreservePathOnForward() { * Set whether the request path should be preserved on forward. * @param preservePathOnForward {@code true} if the path should be preserved when a * request is forwarded, otherwise {@code false}. - * @since 2.4.0 */ public void setPreservePathOnForward(boolean preservePathOnForward) { this.preservePathOnForward = preservePathOnForward; @@ -296,7 +217,7 @@ public void setPreservePathOnForward(boolean preservePathOnForward) { @Override public WebServer getWebServer(ServletContextInitializer... initializers) { - Builder builder = this.delegate.createBuilder(this, this::getSslBundle, this::getServerNameSslBundles); + Builder builder = createBuilder(this, this::getSslBundle, this::getServerNameSslBundles); DeploymentManager manager = createManager(initializers); return getUndertowWebServer(builder, manager, getPort()); } @@ -305,10 +226,10 @@ private DeploymentManager createManager(ServletContextInitializer... initializer DeploymentInfo deployment = Servlets.deployment(); registerServletContainerInitializerToDriveServletContextInitializers(deployment, initializers); deployment.setClassLoader(getServletClassLoader()); - deployment.setContextPath(getContextPath()); - deployment.setDisplayName(getDisplayName()); + deployment.setContextPath(getSettings().getContextPath().toString()); + deployment.setDisplayName(getSettings().getDisplayName()); deployment.setDeploymentName("spring-boot"); - if (isRegisterDefaultServlet()) { + if (getSettings().isRegisterDefaultServlet()) { deployment.addServlet(Servlets.servlet("default", DefaultServlet.class)); } configureErrorPages(deployment); @@ -322,8 +243,8 @@ private DeploymentManager createManager(ServletContextInitializer... initializer for (UndertowDeploymentInfoCustomizer customizer : this.deploymentInfoCustomizers) { customizer.customize(deployment); } - if (getSession().isPersistent()) { - File dir = getValidSessionStoreDir(); + if (getSettings().getSession().isPersistent()) { + File dir = getSettings().getSession().getSessionStoreDirectory().getValidDirectory(true); deployment.setSessionPersistenceManager(new FileSessionPersistence(dir)); } addLocaleMappings(deployment); @@ -333,14 +254,14 @@ private DeploymentManager createManager(ServletContextInitializer... initializer removeSuperfluousMimeMappings(managerDeployment, deployment); } SessionManager sessionManager = manager.getDeployment().getSessionManager(); - Duration timeoutDuration = getSession().getTimeout(); + Duration timeoutDuration = getSettings().getSession().getTimeout(); int sessionTimeout = (isZeroOrLess(timeoutDuration) ? -1 : (int) timeoutDuration.getSeconds()); sessionManager.setDefaultSessionTimeout(sessionTimeout); return manager; } private void configureWebListeners(DeploymentInfo deployment) { - for (String className : getWebListenerClassNames()) { + for (String className : getSettings().getWebListenerClassNames()) { try { deployment.addListener(new ListenerInfo(loadWebListenerClass(className))); } @@ -360,13 +281,13 @@ private boolean isZeroOrLess(Duration timeoutDuration) { } private void addLocaleMappings(DeploymentInfo deployment) { - getLocaleCharsetMappings() + getSettings().getLocaleCharsetMappings() .forEach((locale, charset) -> deployment.addLocaleCharsetMapping(locale.toString(), charset.toString())); } private void registerServletContainerInitializerToDriveServletContextInitializers(DeploymentInfo deployment, ServletContextInitializer... initializers) { - ServletContextInitializer[] mergedInitializers = mergeInitializers(initializers); + ServletContextInitializers mergedInitializers = ServletContextInitializers.from(this.settings, initializers); Initializer initializer = new Initializer(mergedInitializers); deployment.addServletContainerInitializer(new ServletContainerInitializerInfo(Initializer.class, new ImmediateInstanceFactory<>(initializer), NO_CLASSES)); @@ -380,9 +301,11 @@ private ClassLoader getServletClassLoader() { } private ResourceManager getDocumentRootResourceManager() { - File root = getValidDocumentRoot(); + DocumentRoot documentRoot = new DocumentRoot(logger); + documentRoot.setDirectory(this.settings.getDocumentRoot()); + File root = documentRoot.getValidDirectory(); File docBase = getCanonicalDocumentRoot(root); - List metaInfResourceUrls = getUrlsOfJarsWithMetaInfResources(); + List metaInfResourceUrls = getSettings().getStaticResourceUrls(); List resourceJarUrls = new ArrayList<>(); List managers = new ArrayList<>(); ResourceManager rootManager = (docBase.isDirectory() ? new FileResourceManager(docBase, 0) @@ -441,7 +364,7 @@ private io.undertow.servlet.api.ErrorPage getUndertowErrorPage(ErrorPage errorPa } private void configureMimeMappings(DeploymentInfo deployment) { - for (Mapping mimeMapping : getMimeMappings()) { + for (Mapping mimeMapping : getSettings().getMimeMappings()) { deployment.addMimeMapping(new MimeMapping(mimeMapping.getExtension(), mimeMapping.getMimeType())); } } @@ -473,33 +396,39 @@ protected UndertowServletWebServer getUndertowWebServer(Builder builder, Deploym if (cooHandlerFactory != null) { initialHandlerFactories.add(cooHandlerFactory); } - List httpHandlerFactories = this.delegate.createHttpHandlerFactories(this, + List httpHandlerFactories = createHttpHandlerFactories(this, initialHandlerFactories.toArray(new HttpHandlerFactory[0])); - return new UndertowServletWebServer(builder, httpHandlerFactories, getContextPath(), port >= 0); + return new UndertowServletWebServer(builder, httpHandlerFactories, getSettings().getContextPath().toString(), + port >= 0); } private HttpHandlerFactory getCookieHandlerFactory(Deployment deployment) { - SameSite sessionSameSite = getSession().getCookie().getSameSite(); + SameSite sessionSameSite = getSettings().getSession().getCookie().getSameSite(); List suppliers = new ArrayList<>(); if (sessionSameSite != null) { String sessionCookieName = deployment.getServletContext().getSessionCookieConfig().getName(); suppliers.add(CookieSameSiteSupplier.of(sessionSameSite).whenHasName(sessionCookieName)); } - if (!CollectionUtils.isEmpty(getCookieSameSiteSuppliers())) { - suppliers.addAll(getCookieSameSiteSuppliers()); + if (!CollectionUtils.isEmpty(getSettings().getCookieSameSiteSuppliers())) { + suppliers.addAll(getSettings().getCookieSameSiteSuppliers()); } return (!suppliers.isEmpty()) ? (next) -> new SuppliedSameSiteCookieHandler(next, suppliers) : null; } + @Override + public ServletWebServerSettings getSettings() { + return this.settings; + } + /** * {@link ServletContainerInitializer} to initialize {@link ServletContextInitializer * ServletContextInitializers}. */ private static class Initializer implements ServletContainerInitializer { - private final ServletContextInitializer[] initializers; + private final ServletContextInitializers initializers; - Initializer(ServletContextInitializer[] initializers) { + Initializer(ServletContextInitializers initializers) { this.initializers = initializers; } diff --git a/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/package-info.java b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/package-info.java new file mode 100644 index 000000000000..e00b16f80750 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/java/org/springframework/boot/undertow/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Servlet web server implementation backed by Undertow. + */ +package org.springframework.boot.undertow.servlet; diff --git a/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/META-INF/spring.factories b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/META-INF/spring.factories new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..507df4191900 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,13 @@ +{ + "groups": [], + "properties": [ + { + "name": "server.undertow.buffers-per-region", + "type": "java.lang.Integer", + "description": "Number of buffer per region.", + "deprecation": { + "level": "error" + } + } + ] +} diff --git a/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..ae1653d5ffb8 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.undertow.UndertowWebServer$UndertowWebServerRuntimeHints diff --git a/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..bdb872273c8d --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.undertow.autoconfigure.actuate.web.UndertowReactiveManagementChildContextConfiguration +org.springframework.boot.undertow.autoconfigure.actuate.web.UndertowServletManagementChildContextConfiguration diff --git a/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..ca6246e7d46d --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.springframework.boot.undertow.autoconfigure.actuate.web.UndertowReactiveManagementContextAutoConfiguration +org.springframework.boot.undertow.autoconfigure.actuate.web.UndertowServletManagementContextAutoConfiguration +org.springframework.boot.undertow.autoconfigure.reactive.UndertowReactiveWebServerAutoConfiguration +org.springframework.boot.undertow.autoconfigure.servlet.UndertowServletWebServerAutoConfiguration diff --git a/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowAccess.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowAccess.java new file mode 100644 index 000000000000..74a1c1559794 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowAccess.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow; + +/** + * Helper class to provide public access to package-private methods for testing purposes. + * + * @author Andy Wilkinson + */ +public final class UndertowAccess { + + private UndertowAccess() { + + } + + public static String getStartedLogMessage(UndertowWebServer undertowWebServer) { + return undertowWebServer.getStartedLogMessage(); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerRuntimeHintsTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowWebServerRuntimeHintsTests.java similarity index 93% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerRuntimeHintsTests.java rename to spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowWebServerRuntimeHintsTests.java index a0df41b402d7..da851e73a936 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/UndertowWebServerRuntimeHintsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow; import java.util.function.Predicate; @@ -23,7 +23,7 @@ import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.web.embedded.undertow.UndertowWebServer.UndertowWebServerRuntimeHints; +import org.springframework.boot.undertow.UndertowWebServer.UndertowWebServerRuntimeHints; import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowServerPropertiesTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowServerPropertiesTests.java new file mode 100644 index 000000000000..6b4b136d6bc6 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowServerPropertiesTests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure; + +import java.util.Collections; +import java.util.Map; + +import io.undertow.UndertowOptions; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.context.properties.source.ConfigurationPropertySource; +import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link UndertowServerProperties}. + * + * @author Andy Wilkinson + */ +class UndertowServerPropertiesTests { + + private final UndertowServerProperties properties = new UndertowServerProperties(); + + @Test + void testCustomizeUndertowServerOption() { + bind("server.undertow.options.server.ALWAYS_SET_KEEP_ALIVE", "true"); + assertThat(this.properties.getOptions().getServer()).containsEntry("ALWAYS_SET_KEEP_ALIVE", "true"); + } + + @Test + void testCustomizeUndertowSocketOption() { + bind("server.undertow.options.socket.ALWAYS_SET_KEEP_ALIVE", "true"); + assertThat(this.properties.getOptions().getSocket()).containsEntry("ALWAYS_SET_KEEP_ALIVE", "true"); + } + + @Test + void testCustomizeUndertowIoThreads() { + bind("server.undertow.threads.io", "4"); + assertThat(this.properties.getThreads().getIo()).isEqualTo(4); + } + + @Test + void testCustomizeUndertowWorkerThreads() { + bind("server.undertow.threads.worker", "10"); + assertThat(this.properties.getThreads().getWorker()).isEqualTo(10); + } + + @Test + void undertowMaxHttpPostSizeMatchesDefault() { + assertThat(this.properties.getMaxHttpPostSize().toBytes()).isEqualTo(UndertowOptions.DEFAULT_MAX_ENTITY_SIZE); + } + + private void bind(String name, String value) { + bind(Collections.singletonMap(name, value)); + } + + private void bind(Map map) { + ConfigurationPropertySource source = new MapConfigurationPropertySource(map); + new Binder(source).bind("server.undertow", Bindable.ofInstance(this.properties)); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizerTests.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java rename to spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizerTests.java index 19c81ee4182c..faeacfbfc7b5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/UndertowWebServerFactoryCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.embedded; +package org.springframework.boot.undertow.autoconfigure; import java.io.File; import java.nio.charset.StandardCharsets; @@ -29,12 +29,12 @@ import org.xnio.OptionMap; import org.xnio.Options; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.web.embedded.undertow.ConfigurableUndertowWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory; +import org.springframework.boot.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.mock.env.MockEnvironment; import org.springframework.test.context.support.TestPropertySourceUtils; import org.springframework.test.util.ReflectionTestUtils; @@ -56,18 +56,19 @@ */ class UndertowWebServerFactoryCustomizerTests { - private MockEnvironment environment; + private final MockEnvironment environment = new MockEnvironment(); - private ServerProperties serverProperties; + private final ServerProperties serverProperties = new ServerProperties(); + + private final UndertowServerProperties undertowProperties = new UndertowServerProperties(); private UndertowWebServerFactoryCustomizer customizer; @BeforeEach void setup() { - this.environment = new MockEnvironment(); - this.serverProperties = new ServerProperties(); ConfigurationPropertySources.attach(this.environment); - this.customizer = new UndertowWebServerFactoryCustomizer(this.environment, this.serverProperties); + this.customizer = new UndertowWebServerFactoryCustomizer(this.environment, this.serverProperties, + this.undertowProperties); } @Test @@ -149,13 +150,6 @@ void customizeWorkerThreads() { then(factory).should().setWorkerThreads(10); } - @Test - @Deprecated(forRemoval = true, since = "3.0.3") - void allowEncodedSlashes() { - bind("server.undertow.allow-encoded-slash=true"); - assertThat(boundServerOption(UndertowOptions.ALLOW_ENCODED_SLASH)).isTrue(); - } - @Test void enableSlashDecoding() { bind("server.undertow.decode-slash=true"); @@ -266,8 +260,9 @@ private ConfigurableUndertowWebServerFactory mockFactory(Builder builder) { private void bind(String... inlinedProperties) { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, inlinedProperties); - new Binder(ConfigurationPropertySources.get(this.environment)).bind("server", - Bindable.ofInstance(this.serverProperties)); + Binder binder = new Binder(ConfigurationPropertySources.get(this.environment)); + binder.bind("server", Bindable.ofInstance(this.serverProperties)); + binder.bind("server.undertow", Bindable.ofInstance(this.undertowProperties)); } } diff --git a/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerPropertiesTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerPropertiesTests.java new file mode 100644 index 000000000000..a4afad4e345f --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/actuate/web/UndertowManagementServerPropertiesTests.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.actuate.web; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link UndertowManagementServerProperties}. + * + * @author Andy Wilkinson + */ +class UndertowManagementServerPropertiesTests { + + @Test + void accessLogsArePrefixedByDefault() { + UndertowManagementServerProperties properties = new UndertowManagementServerProperties(); + assertThat(properties.getAccesslog().getPrefix()).isEqualTo("management_"); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..283670952538 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/reactive/UndertowReactiveWebServerAutoConfigurationTests.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.reactive; + +import io.undertow.Undertow.Builder; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory; +import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.reactive.AbstractReactiveWebServerAutoConfigurationTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link UndertowReactiveWebServerAutoConfiguration}. + * + * @author Brian Clozel + * @author Raheela Aslam + * @author Madhura Bhave + * @author Scott Frederick + */ +class UndertowReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests { + + UndertowReactiveWebServerAutoConfigurationTests() { + super(UndertowReactiveWebServerAutoConfiguration.class); + } + + @Test + void undertowBuilderCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(UndertowBuilderCustomizerConfiguration.class).run((context) -> { + UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class); + assertThat(factory.getBuilderCustomizers()) + .contains(context.getBean("builderCustomizer", UndertowBuilderCustomizer.class)); + }); + } + + @Test + void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class) + .run((context) -> { + UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class); + UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer", + UndertowBuilderCustomizer.class); + assertThat(factory.getBuilderCustomizers()).contains(customizer); + then(customizer).should().customize(any(Builder.class)); + }); + } + + @Configuration(proxyBeanMethods = false) + static class UndertowBuilderCustomizerConfiguration { + + @Bean + UndertowBuilderCustomizer builderCustomizer() { + return (builder) -> { + }; + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationUndertowBuilderCustomizerConfiguration { + + private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class); + + @Bean + UndertowBuilderCustomizer builderCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer undertowCustomizer() { + return (undertow) -> undertow.addBuilderCustomizers(this.customizer); + } + + } + + @Configuration(proxyBeanMethods = false) + static class UndertowDeploymentInfoCustomizerConfiguration { + + @Bean + UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { + return (deploymentInfo) -> { + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..c4ac22794c70 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerAutoConfigurationTests.java @@ -0,0 +1,158 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.servlet; + +import io.undertow.Undertow.Builder; +import io.undertow.servlet.api.DeploymentInfo; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.undertow.servlet.UndertowDeploymentInfoCustomizer; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.servlet.AbstractServletWebServerAutoConfigurationTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link UndertowServletWebServerAutoConfiguration}. + * + * @author Dave Syer + * @author Phillip Webb + * @author Stephane Nicoll + * @author Raheela Aslam + * @author Madhura Bhave + */ +class UndertowServletWebServerAutoConfigurationTests extends AbstractServletWebServerAutoConfigurationTests { + + UndertowServletWebServerAutoConfigurationTests() { + super(UndertowServletWebServerAutoConfiguration.class); + } + + @Test + void undertowDeploymentInfoCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(UndertowDeploymentInfoCustomizerConfiguration.class).run((context) -> { + UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); + UndertowDeploymentInfoCustomizer customizer = context.getBean("deploymentInfoCustomizer", + UndertowDeploymentInfoCustomizer.class); + assertThat(factory.getDeploymentInfoCustomizers()).contains(customizer); + }); + } + + @Test + void undertowDeploymentInfoCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withUserConfiguration(DoubleRegistrationUndertowDeploymentInfoCustomizerConfiguration.class) + .run((context) -> { + UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); + UndertowDeploymentInfoCustomizer customizer = context.getBean("deploymentInfoCustomizer", + UndertowDeploymentInfoCustomizer.class); + assertThat(factory.getDeploymentInfoCustomizers()).contains(customizer); + then(customizer).should().customize(any(DeploymentInfo.class)); + }); + } + + @Test + void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() { + this.serverRunner.withConfiguration(AutoConfigurations.of(UndertowServletWebServerAutoConfiguration.class)) + .withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class) + .run((context) -> { + UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); + UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer", + UndertowBuilderCustomizer.class); + assertThat(factory.getBuilderCustomizers()).contains(customizer); + then(customizer).should().customize(any(Builder.class)); + }); + } + + @Test + void undertowBuilderCustomizerBeanIsAddedToFactory() { + this.serverRunner.withUserConfiguration(UndertowBuilderCustomizerConfiguration.class).run((context) -> { + UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class); + assertThat(factory.getBuilderCustomizers()) + .contains(context.getBean("builderCustomizer", UndertowBuilderCustomizer.class)); + }); + } + + @Test + void undertowServletWebServerFactoryCustomizerIsAutoConfigured() { + this.serverRunner.withUserConfiguration(UndertowBuilderCustomizerConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(UndertowServletWebServerFactoryCustomizer.class)); + } + + @Configuration(proxyBeanMethods = false) + static class UndertowBuilderCustomizerConfiguration { + + @Bean + UndertowBuilderCustomizer builderCustomizer() { + return (builder) -> { + }; + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationUndertowBuilderCustomizerConfiguration { + + private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class); + + @Bean + UndertowBuilderCustomizer builderCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer undertowCustomizer() { + return (undertow) -> undertow.addBuilderCustomizers(this.customizer); + } + + } + + @Configuration(proxyBeanMethods = false) + static class UndertowDeploymentInfoCustomizerConfiguration { + + @Bean + UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { + return (deploymentInfo) -> { + }; + } + + } + + @Configuration(proxyBeanMethods = false) + static class DoubleRegistrationUndertowDeploymentInfoCustomizerConfiguration { + + private final UndertowDeploymentInfoCustomizer customizer = mock(UndertowDeploymentInfoCustomizer.class); + + @Bean + UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() { + return this.customizer; + } + + @Bean + WebServerFactoryCustomizer undertowCustomizer() { + return (undertow) -> undertow.addDeploymentInfoCustomizers(this.customizer); + } + + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizerTests.java new file mode 100644 index 000000000000..1925ff6ea02e --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerFactoryCustomizerTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.undertow.autoconfigure.UndertowServerProperties; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link UndertowServletWebServerFactoryCustomizer} + * + * @author Andy Wilkinson + */ +class UndertowServletWebServerFactoryCustomizerTests { + + @Test + void eagerFilterInitCanBeDisabled() { + UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(0); + assertThat(factory.isEagerFilterInit()).isTrue(); + UndertowServerProperties undertowProperties = new UndertowServerProperties(); + undertowProperties.setEagerFilterInit(false); + new UndertowServletWebServerFactoryCustomizer(undertowProperties).customize(factory); + assertThat(factory.isEagerFilterInit()).isFalse(); + } + + @Test + void preservePathOnForwardCanBeEnabled() { + UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(0); + assertThat(factory.isPreservePathOnForward()).isFalse(); + UndertowServerProperties undertowProperties = new UndertowServerProperties(); + undertowProperties.setPreservePathOnForward(true); + new UndertowServletWebServerFactoryCustomizer(undertowProperties).customize(factory); + assertThat(factory.isPreservePathOnForward()).isTrue(); + } + +} diff --git a/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerServletContextListenerTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerServletContextListenerTests.java new file mode 100644 index 000000000000..b1f94856b815 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/autoconfigure/servlet/UndertowServletWebServerServletContextListenerTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.autoconfigure.servlet; + +import jakarta.servlet.ServletContextListener; + +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.servlet.AbstractServletWebServerServletContextListenerTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Tests for Undertow driving {@link ServletContextListener}s correctly. + * + * @author Andy Wilkinson + */ +class UndertowServletWebServerServletContextListenerTests extends AbstractServletWebServerServletContextListenerTests { + + UndertowServletWebServerServletContextListenerTests() { + super(UndertowConfiguration.class); + } + + @Configuration(proxyBeanMethods = false) + static class UndertowConfiguration { + + @Bean + UndertowServletWebServerFactory webServerFactory() { + return new UndertowServletWebServerFactory(0); + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactoryTests.java similarity index 91% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactoryTests.java rename to spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactoryTests.java index 99eaca8c53d7..c69edebcdf10 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/reactive/UndertowReactiveWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.reactive; import java.io.File; import java.time.Duration; @@ -27,9 +27,12 @@ import org.mockito.InOrder; import reactor.core.publisher.Mono; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests; +import org.springframework.boot.undertow.UndertowAccess; +import org.springframework.boot.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.undertow.UndertowWebServer; import org.springframework.boot.web.server.Shutdown; +import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactoryTests; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.web.reactive.function.BodyInserters; @@ -158,11 +161,11 @@ private void awaitFile(File file) { @Override protected String startedLogMessage() { - return ((UndertowWebServer) this.webServer).getStartLogMessage(); + return UndertowAccess.getStartedLogMessage((UndertowWebServer) this.webServer); } @Override - protected void addConnector(int port, AbstractReactiveWebServerFactory factory) { + protected void addConnector(int port, ConfigurableReactiveWebServerFactory factory) { ((UndertowReactiveWebServerFactory) factory) .addBuilderCustomizers((builder) -> builder.addHttpListener(port, "0.0.0.0")); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/FileSessionPersistenceTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/FileSessionPersistenceTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/FileSessionPersistenceTests.java rename to spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/FileSessionPersistenceTests.java index 080505bffad0..dda0be4d9c1b 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/FileSessionPersistenceTests.java +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/FileSessionPersistenceTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import java.io.File; import java.util.Date; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/JarResourceManagerTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/JarResourceManagerTests.java similarity index 98% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/JarResourceManagerTests.java rename to spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/JarResourceManagerTests.java index 6beacf5322e3..d2d4e8c3cc85 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/JarResourceManagerTests.java +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/JarResourceManagerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import java.io.File; import java.io.FileOutputStream; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactoryTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactoryTests.java rename to spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactoryTests.java index 9fb0cf5c405d..b83597873c38 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.embedded.undertow; +package org.springframework.boot.undertow.servlet; import java.io.File; import java.io.IOException; @@ -50,13 +50,14 @@ import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; import org.springframework.boot.testsupport.web.servlet.ExampleServlet; -import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.undertow.UndertowBuilderCustomizer; +import org.springframework.boot.web.error.ErrorPage; import org.springframework.boot.web.server.GracefulShutdownResult; import org.springframework.boot.web.server.PortInUseException; import org.springframework.boot.web.server.Shutdown; +import org.springframework.boot.web.server.servlet.AbstractServletWebServerFactoryTests; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests; import org.springframework.http.HttpStatus; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.test.util.ReflectionTestUtils; @@ -91,7 +92,7 @@ void awaitClosureOfSslRelatedInputStreams() { @Test void errorPage404() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/hello")); this.webServer = factory.getWebServer(new ServletRegistrationBean<>(new ExampleServlet(), "/hello")); this.webServer.start(); @@ -196,7 +197,7 @@ void accessLogCanBeCustomized() throws IOException, URISyntaxException { @Test void whenServerIsShuttingDownGracefullyThenRequestsAreRejectedWithServiceUnavailable() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory.getWebServer((context) -> { @@ -221,7 +222,7 @@ void whenServerIsShuttingDownGracefullyThenRequestsAreRejectedWithServiceUnavail @Test void whenServerIsShuttingDownARequestOnAnIdleConnectionAreRejectedWithServiceUnavailable() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory.getWebServer((context) -> { @@ -285,7 +286,7 @@ private void testAccessLog(String prefix, String suffix, String expectedFile) } @Override - protected void addConnector(int port, AbstractServletWebServerFactory factory) { + protected void addConnector(int port, ConfigurableServletWebServerFactory factory) { ((UndertowServletWebServerFactory) factory) .addBuilderCustomizers((builder) -> builder.addHttpListener(port, "0.0.0.0")); } @@ -382,11 +383,11 @@ protected void handleExceptionCausedByBlockedPortOnSecondaryConnector(RuntimeExc @Override protected String startedLogMessage() { - return ((UndertowServletWebServer) this.webServer).getStartLogMessage(); + return ((UndertowServletWebServer) this.webServer).getStartedLogMessage(); } private void testRestrictedSSLProtocolsAndCipherSuites(String[] protocols, String[] ciphers) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setSsl(getSsl(null, "password", "classpath:restricted.jks", null, protocols, ciphers)); this.webServer = factory.getWebServer(new ServletRegistrationBean<>(new ExampleServlet(true, false), "/hello")); this.webServer.start(); diff --git a/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerMvcIntegrationTests.java b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerMvcIntegrationTests.java new file mode 100644 index 000000000000..aca7f4dc54e8 --- /dev/null +++ b/spring-boot-project/spring-boot-undertow/src/test/java/org/springframework/boot/undertow/servlet/UndertowServletWebServerMvcIntegrationTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.undertow.servlet; + +import org.springframework.boot.undertow.UndertowWebServer; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.context.AbstractServletWebServerMvcIntegrationTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Integration tests for {@link ServletWebServerApplicationContext} and + * {@link UndertowWebServer} running Spring MVC. + */ +class UndertowServletWebServerMvcIntegrationTests extends AbstractServletWebServerMvcIntegrationTests { + + protected UndertowServletWebServerMvcIntegrationTests() { + super(UndertowConfig.class); + } + + @Configuration(proxyBeanMethods = false) + static class UndertowConfig { + + @Bean + UndertowServletWebServerFactory webServerFactory() { + return new UndertowServletWebServerFactory(0); + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/undertow/restricted.jks b/spring-boot-project/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/servlet/restricted.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/embedded/undertow/restricted.jks rename to spring-boot-project/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/servlet/restricted.jks diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/reactive/server/test.jks b/spring-boot-project/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/servlet/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/reactive/server/test.jks rename to spring-boot-project/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/servlet/test.jks diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test.jks b/spring-boot-project/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test.jks rename to spring-boot-project/spring-boot-undertow/src/test/resources/org/springframework/boot/undertow/test.jks diff --git a/spring-boot-project/spring-boot-validation/build.gradle b/spring-boot-project/spring-boot-validation/build.gradle new file mode 100644 index 000000000000..b12032ac4671 --- /dev/null +++ b/spring-boot-project/spring-boot-validation/build.gradle @@ -0,0 +1,39 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Validation" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.apache.tomcat.embed:tomcat-embed-el") + api("org.hibernate.validator:hibernate-validator") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/JakartaValidationBackgroundPreinitializer.java b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/JakartaValidationBackgroundPreinitializer.java new file mode 100644 index 000000000000..7b1aadeca476 --- /dev/null +++ b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/JakartaValidationBackgroundPreinitializer.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.validation.autoconfigure; + +import jakarta.validation.Configuration; +import jakarta.validation.Validation; + +import org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer; + +/** + * {@link BackgroundPreinitializer} for jakarta.validation. + * + * @author Phillip Webb + */ +final class JakartaValidationBackgroundPreinitializer implements BackgroundPreinitializer { + + @Override + public void preinitialize() throws Exception { + Configuration configuration = Validation.byDefaultProvider().configure(); + configuration.buildValidatorFactory().getValidator(); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/PrimaryDefaultValidatorPostProcessor.java b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/PrimaryDefaultValidatorPostProcessor.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/PrimaryDefaultValidatorPostProcessor.java rename to spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/PrimaryDefaultValidatorPostProcessor.java index 9fe70405e395..39ae0a1f5251 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/PrimaryDefaultValidatorPostProcessor.java +++ b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/PrimaryDefaultValidatorPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.validation; +package org.springframework.boot.validation.autoconfigure; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java rename to spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfiguration.java index f3c370c53a18..2c1dbfbf8705 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.validation; +package org.springframework.boot.validation.autoconfigure; import jakarta.validation.Validator; import jakarta.validation.executable.ExecutableValidator; @@ -45,7 +45,7 @@ * @author Stephane Nicoll * @author Madhura Bhave * @author Yanming Zhou - * @since 1.5.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass(ExecutableValidator.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationConfigurationCustomizer.java b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidationConfigurationCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationConfigurationCustomizer.java rename to spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidationConfigurationCustomizer.java index 70afc4e6b327..427e61522af9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationConfigurationCustomizer.java +++ b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidationConfigurationCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.validation; +package org.springframework.boot.validation.autoconfigure; import jakarta.validation.Configuration; @@ -22,7 +22,7 @@ * Callback interface that can be used to customize {@link Configuration}. * * @author Dang Zhicairang - * @since 3.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface ValidationConfigurationCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapter.java b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidatorAdapter.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapter.java rename to spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidatorAdapter.java index 85a97e302ed4..69605c39151a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapter.java +++ b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/ValidatorAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.validation; +package org.springframework.boot.validation.autoconfigure; import jakarta.validation.ValidationException; @@ -40,7 +40,7 @@ * @author Stephane Nicoll * @author Phillip Webb * @author Zisis Pavloudis - * @since 2.0.0 + * @since 4.0.0 */ public class ValidatorAdapter implements SmartValidator, ApplicationContextAware, InitializingBean, DisposableBean { diff --git a/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/package-info.java b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/package-info.java new file mode 100644 index 000000000000..dd70c0b9290e --- /dev/null +++ b/spring-boot-project/spring-boot-validation/src/main/java/org/springframework/boot/validation/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for (JSR-303) Validation. + */ +package org.springframework.boot.validation.autoconfigure; diff --git a/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..dfbcc5a0d710 --- /dev/null +++ b/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,12 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.validation.method.adapt-constraint-violations", + "type": "java.lang.Boolean", + "description": "Whether to adapt ConstraintViolations to MethodValidationResult.", + "defaultValue": false + } + ], + "hints": [] +} diff --git a/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..59ac9c7f6273 --- /dev/null +++ b/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Background Preinitializers +org.springframework.boot.autoconfigure.preinitialize.BackgroundPreinitializer=\ +org.springframework.boot.validation.autoconfigure.JakartaValidationBackgroundPreinitializer diff --git a/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..b44e6e163930 --- /dev/null +++ b/spring-boot-project/spring-boot-validation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java b/spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java rename to spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationTests.java index 89488ea915c0..db01b58f6889 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.validation; +package org.springframework.boot.validation.autoconfigure; import java.util.HashSet; import java.util.Set; @@ -32,9 +32,9 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfigurationTests.CustomValidatorConfiguration.TestBeanPostProcessor; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.validation.autoconfigure.ValidationAutoConfigurationTests.CustomValidatorConfiguration.TestBeanPostProcessor; import org.springframework.boot.validation.beanvalidation.MethodValidationExcludeFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationWithHibernateValidatorMissingElImplTests.java b/spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationWithHibernateValidatorMissingElImplTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationWithHibernateValidatorMissingElImplTests.java rename to spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationWithHibernateValidatorMissingElImplTests.java index 39bb25ce8ab8..1f7eb95dacb1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationWithHibernateValidatorMissingElImplTests.java +++ b/spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationWithHibernateValidatorMissingElImplTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.validation; +package org.springframework.boot.validation.autoconfigure; import jakarta.validation.Validator; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationWithoutValidatorTests.java b/spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationWithoutValidatorTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationWithoutValidatorTests.java rename to spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationWithoutValidatorTests.java index fac87342ae09..09560e9557eb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationWithoutValidatorTests.java +++ b/spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidationAutoConfigurationWithoutValidatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.validation; +package org.springframework.boot.validation.autoconfigure; import jakarta.validation.Validator; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapterTests.java b/spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidatorAdapterTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapterTests.java rename to spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidatorAdapterTests.java index fdb243143948..034fa2299e94 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapterTests.java +++ b/spring-boot-project/spring-boot-validation/src/test/java/org/springframework/boot/validation/autoconfigure/ValidatorAdapterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.validation; +package org.springframework.boot.validation.autoconfigure; import java.util.HashMap; diff --git a/spring-boot-project/spring-boot-web-server-test/build.gradle b/spring-boot-project/spring-boot-web-server-test/build.gradle new file mode 100644 index 000000000000..e8984f22063e --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/build.gradle @@ -0,0 +1,58 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "dev.adamko.dokkatoo-html" + id "java-library" + id "org.jetbrains.kotlin.jvm" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Web Server Test" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + + implementation(project(":spring-boot-project:spring-boot-test")) + + optional(project(":spring-boot-project:spring-boot-http-codec")) + optional(project(":spring-boot-project:spring-boot-restclient")) + optional(project(":spring-boot-project:spring-boot-web-server")) + optional(project(":spring-boot-project:spring-boot-webclient")) + optional("jakarta.servlet:jakarta.servlet-api") + optional("org.apache.httpcomponents.client5:httpclient5") + optional("org.jetbrains.kotlin:kotlin-reflect") + optional("org.jetbrains.kotlin:kotlin-stdlib") + optional("org.springframework:spring-test") + optional("org.springframework:spring-web") + optional("org.springframework:spring-webflux") + optional("org.htmlunit:htmlunit") + optional("org.seleniumhq.selenium:htmlunit3-driver") { + exclude(group: "com.sun.activation", module: "jakarta.activation") + } + optional("org.seleniumhq.selenium:selenium-api") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("io.mockk:mockk") + testImplementation("io.projectreactor.netty:reactor-netty-http") + testImplementation("org.springframework:spring-webmvc") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/LocalManagementPort.java similarity index 95% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/LocalManagementPort.java index e4e913795053..d1decec373c3 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/LocalManagementPort.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.server; +package org.springframework.boot.web.server.test; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -30,7 +30,7 @@ * @Value("${local.management.port}"). * * @author Stephane Nicoll - * @since 2.7.0 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/LocalServerPort.java similarity index 95% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/LocalServerPort.java index fdedc7717ddd..f8d5017bcdff 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/LocalServerPort.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.server; +package org.springframework.boot.web.server.test; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -31,7 +31,7 @@ * * @author Anand Shah * @author Stephane Nicoll - * @since 2.7.0 + * @since 4.0.0 */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/SpringBootTestRandomPortEnvironmentPostProcessor.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/SpringBootTestRandomPortEnvironmentPostProcessor.java similarity index 98% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/SpringBootTestRandomPortEnvironmentPostProcessor.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/SpringBootTestRandomPortEnvironmentPostProcessor.java index ce36b6b3f0f5..dcfe7b165d84 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/SpringBootTestRandomPortEnvironmentPostProcessor.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/SpringBootTestRandomPortEnvironmentPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web; +package org.springframework.boot.web.server.test; import java.util.Objects; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandler.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/LocalHostUriTemplateHandler.java similarity index 94% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandler.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/LocalHostUriTemplateHandler.java index a7efc02659c3..78e583655b09 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandler.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/LocalHostUriTemplateHandler.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; -import org.springframework.boot.web.client.RootUriTemplateHandler; +import org.springframework.boot.restclient.RootUriTemplateHandler; import org.springframework.core.env.Environment; import org.springframework.util.Assert; import org.springframework.web.util.DefaultUriBuilderFactory; @@ -30,7 +30,7 @@ * @author Andy Wilkinson * @author Eddú Meléndez * @author Madhura Bhave - * @since 1.4.0 + * @since 4.0.0 */ public class LocalHostUriTemplateHandler extends RootUriTemplateHandler { @@ -55,7 +55,6 @@ public LocalHostUriTemplateHandler(Environment environment) { * context-path and port. * @param environment the environment used to determine the port * @param scheme the scheme of the root uri - * @since 1.4.1 */ public LocalHostUriTemplateHandler(Environment environment, String scheme) { this(environment, scheme, new DefaultUriBuilderFactory()); @@ -68,7 +67,6 @@ public LocalHostUriTemplateHandler(Environment environment, String scheme) { * @param environment the environment used to determine the port * @param scheme the scheme of the root uri * @param handler the delegate handler - * @since 2.0.3 */ public LocalHostUriTemplateHandler(Environment environment, String scheme, UriTemplateHandler handler) { super(handler); diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplate.java similarity index 89% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplate.java index cf4e3593dc34..d2fa25e79acb 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplate.java @@ -14,35 +14,25 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import java.net.URI; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; -import java.time.Duration; import java.util.Map; import java.util.Set; -import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.UnaryOperator; import javax.net.ssl.SSLContext; -import org.apache.hc.client5.http.classic.HttpClient; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.cookie.StandardCookieSpec; -import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; -import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; -import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; import org.apache.hc.client5.http.ssl.TlsSocketStrategy; -import org.apache.hc.core5.http.io.SocketConfig; -import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.http.ssl.TLS; import org.apache.hc.core5.ssl.SSLContextBuilder; import org.apache.hc.core5.ssl.TrustStrategy; @@ -51,9 +41,9 @@ import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.http.client.HttpComponentsClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.restclient.RootUriTemplateHandler; import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.client.RootUriTemplateHandler; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -61,7 +51,6 @@ import org.springframework.http.RequestEntity; import org.springframework.http.RequestEntity.UriTemplateRequestEntity; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.web.client.NoOpResponseErrorHandler; @@ -86,11 +75,10 @@ * {@link RestTemplate}. If you need access to the underlying {@link RestTemplate} use * {@link #getRestTemplate()}. *

    - * If you are using the - * {@link org.springframework.boot.test.context.SpringBootTest @SpringBootTest} annotation - * with an embedded server, a {@link TestRestTemplate} is automatically available and can - * be {@code @Autowired} into your test. If you need customizations (for example to adding - * additional message converters) use a {@link RestTemplateBuilder} {@code @Bean}. + * If you are using the {@code @SpringBootTest} annotation with an embedded server, a + * {@link TestRestTemplate} is automatically available and can be {@code @Autowired} into + * your test. If you need customizations (for example to adding additional message + * converters) use a {@link RestTemplateBuilder} {@code @Bean}. * * @author Dave Syer * @author Phillip Webb @@ -98,7 +86,7 @@ * @author Kristine Jetzke * @author Dmytro Nosan * @author Yanming Zhou - * @since 1.4.0 + * @since 4.0.0 */ public class TestRestTemplate { @@ -110,7 +98,6 @@ public class TestRestTemplate { * Create a new {@link TestRestTemplate} instance. * @param restTemplateBuilder builder used to configure underlying * {@link RestTemplate} - * @since 1.4.1 */ public TestRestTemplate(RestTemplateBuilder restTemplateBuilder) { this(restTemplateBuilder, null, null); @@ -140,7 +127,6 @@ public TestRestTemplate(String username, String password, HttpClientOption... ht * @param username the username to use (or {@code null}) * @param password the password (or {@code null}) * @param httpClientOptions client options to use if the Apache HTTP Client is used - * @since 2.0.0 */ public TestRestTemplate(RestTemplateBuilder builder, String username, String password, HttpClientOption... httpClientOptions) { @@ -163,9 +149,6 @@ private static RestTemplateBuilder createInitialBuilder(RestTemplateBuilder buil if (requestFactoryBuilder instanceof HttpComponentsClientHttpRequestFactoryBuilder) { builder = builder.requestFactoryBuilder(applyHttpClientOptions( (HttpComponentsClientHttpRequestFactoryBuilder) requestFactoryBuilder, httpClientOptions)); - if (HttpClientOption.ENABLE_REDIRECTS.isPresent(httpClientOptions)) { - builder = builder.redirects(HttpRedirects.FOLLOW); - } } if (username != null || password != null) { builder = builder.basicAuthentication(username, password); @@ -591,7 +574,6 @@ public void put(URI url, Object request) { * @param uriVariables the variables to expand the template * @param the type of the return value * @return the converted object - * @since 1.4.4 * @see HttpEntity */ public T patchForObject(String url, Object request, Class responseType, Object... uriVariables) { @@ -612,7 +594,6 @@ public T patchForObject(String url, Object request, Class responseType, O * @param uriVariables the variables to expand the template * @param the type of the return value * @return the converted object - * @since 1.4.4 * @see HttpEntity */ public T patchForObject(String url, Object request, Class responseType, Map uriVariables) { @@ -630,7 +611,6 @@ public T patchForObject(String url, Object request, Class responseType, M * @param responseType the type of the return value * @param the type of the return value * @return the converted object - * @since 1.4.4 * @see HttpEntity */ public T patchForObject(URI url, Object request, Class responseType) { @@ -964,7 +944,6 @@ public RestTemplate getRestTemplate() { * @param username the username * @param password the password * @return the new template - * @since 1.4.1 */ public TestRestTemplate withBasicAuth(String username, String password) { if (username == null && password == null) { @@ -981,7 +960,6 @@ public TestRestTemplate withBasicAuth(String username, String password) { * (when possible). * @param redirects the new redirect settings * @return the new template - * @since 3.5.0 */ public TestRestTemplate withRedirects(HttpRedirects redirects) { return withRequestFactorySettings((settings) -> settings.withRedirects(redirects)); @@ -994,7 +972,6 @@ public TestRestTemplate withRedirects(HttpRedirects redirects) { * request factory type (when possible). * @param requestFactorySettings the new request factory settings * @return the new template - * @since 3.4.1 */ public TestRestTemplate withRequestFactorySettings(ClientHttpRequestFactorySettings requestFactorySettings) { return new TestRestTemplate(this.builder.requestFactorySettings(requestFactorySettings), @@ -1009,7 +986,6 @@ public TestRestTemplate withRequestFactorySettings(ClientHttpRequestFactorySetti * @param requestFactorySettingsCustomizer a {@link UnaryOperator} to update the * settings * @return the new template - * @since 3.4.1 */ public TestRestTemplate withRequestFactorySettings( UnaryOperator requestFactorySettingsCustomizer) { @@ -1057,14 +1033,6 @@ public enum HttpClientOption { */ ENABLE_COOKIES, - /** - * Enable redirects. - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link TestRestTemplate#withRedirects(HttpRedirects)} - */ - @Deprecated(since = "3.5.0", forRemoval = true) - ENABLE_REDIRECTS, - /** * Use a {@link TlsSocketStrategy} that trusts self-signed certificates. */ @@ -1076,104 +1044,6 @@ boolean isPresent(HttpClientOption[] options) { } - /** - * {@link HttpComponentsClientHttpRequestFactory} to apply customizations. - * - * @deprecated since 3.5.0 for removal in 4.0.0 - */ - @Deprecated(since = "3.5.0", forRemoval = true) - protected static class CustomHttpComponentsClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory { - - private final String cookieSpec; - - private final boolean enableRedirects; - - /** - * Create a new {@link CustomHttpComponentsClientHttpRequestFactory} instance. - * @param httpClientOptions the {@link HttpClient} options - * @param settings the settings to apply - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[], ClientHttpRequestFactorySettings)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - @SuppressWarnings("removal") - public CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[] httpClientOptions, - org.springframework.boot.web.client.ClientHttpRequestFactorySettings settings) { - this(httpClientOptions, new ClientHttpRequestFactorySettings(null, settings.connectTimeout(), - settings.readTimeout(), settings.sslBundle())); - } - - /** - * Create a new {@link CustomHttpComponentsClientHttpRequestFactory} instance. - * @param httpClientOptions the {@link HttpClient} options - * @param settings the settings to apply - */ - public CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[] httpClientOptions, - ClientHttpRequestFactorySettings settings) { - this.cookieSpec = (HttpClientOption.ENABLE_COOKIES.isPresent(httpClientOptions) ? StandardCookieSpec.STRICT - : StandardCookieSpec.IGNORE); - this.enableRedirects = settings.redirects() != HttpRedirects.DONT_FOLLOW; - boolean ssl = HttpClientOption.SSL.isPresent(httpClientOptions); - if (settings.readTimeout() != null || ssl) { - setHttpClient(createHttpClient(settings.readTimeout(), ssl)); - } - if (settings.connectTimeout() != null) { - setConnectTimeout((int) settings.connectTimeout().toMillis()); - } - } - - private HttpClient createHttpClient(Duration readTimeout, boolean ssl) { - try { - HttpClientBuilder builder = HttpClients.custom(); - builder.setConnectionManager(createConnectionManager(readTimeout, ssl)); - builder.setDefaultRequestConfig(createRequestConfig()); - return builder.build(); - } - catch (Exception ex) { - throw new IllegalStateException("Unable to create customized HttpClient", ex); - } - } - - private PoolingHttpClientConnectionManager createConnectionManager(Duration readTimeout, boolean ssl) - throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { - PoolingHttpClientConnectionManagerBuilder builder = PoolingHttpClientConnectionManagerBuilder.create(); - if (ssl) { - builder.setTlsSocketStrategy(createTlsSocketStrategy()); - } - if (readTimeout != null) { - SocketConfig socketConfig = SocketConfig.custom() - .setSoTimeout((int) readTimeout.toMillis(), TimeUnit.MILLISECONDS) - .build(); - builder.setDefaultSocketConfig(socketConfig); - } - return builder.build(); - } - - private TlsSocketStrategy createTlsSocketStrategy() - throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { - SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()) - .build(); - return new DefaultClientTlsStrategy(sslContext, new String[] { TLS.V_1_3.getId(), TLS.V_1_2.getId() }, null, - null, null); - } - - @Override - protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { - HttpClientContext context = HttpClientContext.create(); - context.setRequestConfig(createRequestConfig()); - return context; - } - - protected RequestConfig createRequestConfig() { - RequestConfig.Builder builder = RequestConfig.custom(); - builder.setCookieSpec(this.cookieSpec); - builder.setAuthenticationEnabled(false); - builder.setRedirectsEnabled(this.enableRedirects); - return builder.build(); - } - - } - /** * Factory used to create a {@link TlsSocketStrategy} supporting self-signed * certificates. diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizer.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizer.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizer.java index a0d9ad703636..a069597ee2c6 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizer.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import org.springframework.aot.AotDetector; import org.springframework.beans.BeansException; @@ -29,10 +29,10 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; +import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.test.client.TestRestTemplate.HttpClientOption; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ConfigurableApplicationContext; @@ -149,8 +149,8 @@ public void setApplicationContext(ApplicationContext applicationContext) throws private boolean isSslEnabled(ApplicationContext context) { try { - AbstractServletWebServerFactory webServerFactory = context - .getBean(AbstractServletWebServerFactory.class); + AbstractConfigurableWebServerFactory webServerFactory = context + .getBean(AbstractConfigurableWebServerFactory.class); return webServerFactory.getSsl() != null && webServerFactory.getSsl().isEnabled(); } catch (NoSuchBeanDefinitionException ex) { diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerFactory.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerFactory.java similarity index 80% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerFactory.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerFactory.java index dec847595432..e69c92c230f2 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerFactory.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import java.util.List; @@ -23,6 +23,7 @@ import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.TestContextAnnotationUtils; +import org.springframework.util.ClassUtils; /** * {@link ContextCustomizerFactory} for {@link TestRestTemplate}. @@ -32,9 +33,16 @@ */ class TestRestTemplateContextCustomizerFactory implements ContextCustomizerFactory { + private static final boolean REST_TEMPLATE_BUILDER_PRESENT = ClassUtils.isPresent( + "org.springframework.boot.restclient.RestTemplateBuilder", + TestRestTemplateContextCustomizerFactory.class.getClassLoader()); + @Override public ContextCustomizer createContextCustomizer(Class testClass, List configAttributes) { + if (!REST_TEMPLATE_BUILDER_PRESENT) { + return null; + } SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, SpringBootTest.class); return (springBootTest != null) ? new TestRestTemplateContextCustomizer() : null; diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/package-info.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/package-info.java new file mode 100644 index 000000000000..1e8dcf732540 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Client-side support for testing embedded web servers. + */ +package org.springframework.boot.web.server.test.client; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientBuilderCustomizer.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientBuilderCustomizer.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientBuilderCustomizer.java index f208e022f13f..2a00de60a7a7 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import org.springframework.test.web.reactive.server.WebTestClient.Builder; @@ -24,7 +24,7 @@ * auto-configured {@link Builder}. * * @author Andy Wilkinson - * @since 2.2.0 + * @since 4.0.0 */ @FunctionalInterface public interface WebTestClientBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizer.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizer.java similarity index 87% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizer.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizer.java index 1a9e46b4a7da..0cbae1ed6c4e 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizer.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import java.util.Collection; @@ -32,9 +32,9 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.WebApplicationType; +import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.codec.CodecCustomizer; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ConfigurableApplicationContext; @@ -57,6 +57,13 @@ */ class WebTestClientContextCustomizer implements ContextCustomizer { + private static final boolean codecCustomizerPresent; + + static { + ClassLoader loader = WebTestClientContextCustomizerFactory.class.getClassLoader(); + codecCustomizerPresent = ClassUtils.isPresent("org.springframework.boot.http.codec.CodecCustomizer", loader); + } + @Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { if (AotDetector.useGeneratedArtifacts()) { @@ -141,7 +148,7 @@ public static class WebTestClientFactory implements FactoryBean, private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext"; - private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext"; + private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext"; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { @@ -172,7 +179,9 @@ private WebTestClient createWebTestClient() { String baseUrl = getBaseUrl(sslEnabled, port); WebTestClient.Builder builder = WebTestClient.bindToServer(); customizeWebTestClientBuilder(builder, this.applicationContext); - customizeWebTestClientCodecs(builder, this.applicationContext); + if (codecCustomizerPresent) { + WebTestClientCodecCustomizer.customizeWebTestClientCodecs(builder, this.applicationContext); + } return builder.baseUrl(baseUrl).build(); } @@ -231,14 +240,19 @@ private void customizeWebTestClientBuilder(WebTestClient.Builder clientBuilder, } } - private void customizeWebTestClientCodecs(WebTestClient.Builder clientBuilder, ApplicationContext context) { - Collection codecCustomizers = context.getBeansOfType(CodecCustomizer.class).values(); - if (!CollectionUtils.isEmpty(codecCustomizers)) { - clientBuilder.exchangeStrategies(ExchangeStrategies.builder() - .codecs((codecs) -> codecCustomizers - .forEach((codecCustomizer) -> codecCustomizer.customize(codecs))) - .build()); + private static final class WebTestClientCodecCustomizer { + + private static void customizeWebTestClientCodecs(WebTestClient.Builder clientBuilder, + ApplicationContext context) { + Collection codecCustomizers = context.getBeansOfType(CodecCustomizer.class).values(); + if (!CollectionUtils.isEmpty(codecCustomizers)) { + clientBuilder.exchangeStrategies(ExchangeStrategies.builder() + .codecs((codecs) -> codecCustomizers + .forEach((codecCustomizer) -> codecCustomizer.customize(codecs))) + .build()); + } } + } } diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerFactory.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerFactory.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerFactory.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerFactory.java index c11df1c3a9fb..8e4b54e33cef 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerFactory.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import java.util.List; diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/package-info.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/package-info.java new file mode 100644 index 000000000000..61f8a0dd0344 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring Boot support for testing Spring WebFlux server endpoints via + * {@link org.springframework.test.web.reactive.server.WebTestClient}. + */ +package org.springframework.boot.web.server.test.client.reactive; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClient.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/LocalHostWebClient.java similarity index 95% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClient.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/LocalHostWebClient.java index 5b3693eeb4f2..2e9bea7ab036 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClient.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/LocalHostWebClient.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.htmlunit; +package org.springframework.boot.web.server.test.htmlunit; import java.io.IOException; @@ -30,7 +30,7 @@ * localhost:${local.server.port}. * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 */ public class LocalHostWebClient extends WebClient { diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/package-info.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/package-info.java new file mode 100644 index 000000000000..eeeccceeb14d --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * HtmlUnit support classes. + */ +package org.springframework.boot.web.server.test.htmlunit; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java index 8018368adca0..2620fbafd05a 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriver.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.htmlunit.webdriver; +package org.springframework.boot.web.server.test.htmlunit.webdriver; import org.htmlunit.BrowserVersion; import org.openqa.selenium.Capabilities; @@ -28,7 +28,7 @@ * with localhost:${local.server.port}. * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 */ public class LocalHostWebConnectionHtmlUnitDriver extends WebConnectionHtmlUnitDriver { diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/webdriver/package-info.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/webdriver/package-info.java new file mode 100644 index 000000000000..f08170096109 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/htmlunit/webdriver/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Selenium support classes. + */ +package org.springframework.boot.web.server.test.htmlunit.webdriver; diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/package-info.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/package-info.java new file mode 100644 index 000000000000..fd7ed18ef20e --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Web server test utilities and support classes. + */ +package org.springframework.boot.web.server.test; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesBeanPostProcessor.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesBeanPostProcessor.java similarity index 95% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesBeanPostProcessor.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesBeanPostProcessor.java index 0ed33b48c882..f015fcbad614 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesBeanPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactor.netty; +package org.springframework.boot.web.server.test.reactor.netty; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory.java similarity index 97% rename from spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory.java rename to spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory.java index c3ccf6970b5f..9957967e9fc5 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory.java +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactor.netty; +package org.springframework.boot.web.server.test.reactor.netty; import java.util.List; diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/package-info.java b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/package-info.java new file mode 100644 index 000000000000..20d11f30ef91 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/reactor/netty/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring Boot support for testing Reactor Netty. + */ +package org.springframework.boot.web.server.test.reactor.netty; diff --git a/spring-boot-project/spring-boot-test/src/main/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensions.kt b/spring-boot-project/spring-boot-web-server-test/src/main/kotlin/org/springframework/boot/web/server/test/client/TestRestTemplateExtensions.kt similarity index 99% rename from spring-boot-project/spring-boot-test/src/main/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensions.kt rename to spring-boot-project/spring-boot-web-server-test/src/main/kotlin/org/springframework/boot/web/server/test/client/TestRestTemplateExtensions.kt index 17f6b9807ad9..f3efb9154e27 100644 --- a/spring-boot-project/spring-boot-test/src/main/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensions.kt +++ b/spring-boot-project/spring-boot-web-server-test/src/main/kotlin/org/springframework/boot/web/server/test/client/TestRestTemplateExtensions.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client +package org.springframework.boot.web.server.test.client import org.springframework.core.ParameterizedTypeReference import org.springframework.http.HttpEntity @@ -31,7 +31,7 @@ import java.net.URI * generic type arguments. * * @author Sebastien Deleuze - * @since 2.0.0 + * @since 4.0.0 */ @Throws(RestClientException::class) inline fun TestRestTemplate.getForObject(url: String, vararg uriVariables: Any): T? = diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-web-server-test/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..671fd2520c26 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,4 @@ +{ + "groups": [], + "properties": [] +} diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-web-server-test/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..108534a29eb2 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server-test/src/main/resources/META-INF/spring.factories @@ -0,0 +1,9 @@ +# Environment Post Processors +org.springframework.boot.env.EnvironmentPostProcessor=\ +org.springframework.boot.web.server.test.SpringBootTestRandomPortEnvironmentPostProcessor + +# Spring Test Context Customizer Factories +org.springframework.test.context.ContextCustomizerFactory=\ +org.springframework.boot.web.server.test.client.TestRestTemplateContextCustomizerFactory,\ +org.springframework.boot.web.server.test.client.reactive.WebTestClientContextCustomizerFactory,\ +org.springframework.boot.web.server.test.reactor.netty.DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory diff --git a/spring-boot-project/spring-boot-web-server-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-web-server-test/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java similarity index 89% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java index 08eaa83c3d49..b3a9c8893e26 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; import java.time.Duration; @@ -23,11 +23,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/AbstractSpringBootTestWebServerWebEnvironmentTests.java similarity index 91% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/AbstractSpringBootTestWebServerWebEnvironmentTests.java index 41cdab371511..d36987a59530 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/AbstractSpringBootTestWebServerWebEnvironmentTests.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; import jakarta.servlet.ServletContext; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/LocalManagementPortTests.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/LocalManagementPortTests.java index 7e6cbcefddda..a55f9b5ce180 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/LocalManagementPortTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.server; +package org.springframework.boot.web.server.test; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/LocalServerPortTests.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/LocalServerPortTests.java index 0df64834dd3e..a1892f9c7830 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/LocalServerPortTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.server; +package org.springframework.boot.web.server.test; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/SpringBootTestRandomPortEnvironmentPostProcessorTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestRandomPortEnvironmentPostProcessorTests.java similarity index 99% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/SpringBootTestRandomPortEnvironmentPostProcessorTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestRandomPortEnvironmentPostProcessorTests.java index 00b4a4e1a859..91a216200343 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/SpringBootTestRandomPortEnvironmentPostProcessorTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestRandomPortEnvironmentPostProcessorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web; +package org.springframework.boot.web.server.test; import java.util.Collections; import java.util.HashMap; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentDefinedPortTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentDefinedPortTests.java similarity index 93% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentDefinedPortTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentDefinedPortTests.java index 00142409a2c3..3d8abed31fcd 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentDefinedPortTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentDefinedPortTests.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentRandomPortTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentRandomPortTests.java similarity index 93% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentRandomPortTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentRandomPortTests.java index 1bf0dc526e81..09c7d1b669a1 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentRandomPortTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentRandomPortTests.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentUserDefinedTestRestTemplateTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentUserDefinedTestRestTemplateTests.java similarity index 94% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentUserDefinedTestRestTemplateTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentUserDefinedTestRestTemplateTests.java index d90a19aa0ab0..4372bb33ee36 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestReactiveWebEnvironmentUserDefinedTestRestTemplateTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestReactiveWebEnvironmentUserDefinedTestRestTemplateTests.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestUserDefinedTestRestTemplateTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestUserDefinedTestRestTemplateTests.java similarity index 94% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestUserDefinedTestRestTemplateTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestUserDefinedTestRestTemplateTests.java index e920ea429e5f..82c46ac7927f 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestUserDefinedTestRestTemplateTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestUserDefinedTestRestTemplateTests.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentContextHierarchyTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentContextHierarchyTests.java similarity index 83% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentContextHierarchyTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentContextHierarchyTests.java index bcbe1811d454..983408d54741 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentContextHierarchyTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentContextHierarchyTests.java @@ -14,15 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.AbstractSpringBootTestWebServerWebEnvironmentTests.AbstractConfig; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.context.SpringBootTestWebEnvironmentContextHierarchyTests.ChildConfiguration; -import org.springframework.boot.test.context.SpringBootTestWebEnvironmentContextHierarchyTests.ParentConfiguration; +import org.springframework.boot.web.server.test.AbstractSpringBootTestWebServerWebEnvironmentTests.AbstractConfig; +import org.springframework.boot.web.server.test.SpringBootTestWebEnvironmentContextHierarchyTests.ChildConfiguration; +import org.springframework.boot.web.server.test.SpringBootTestWebEnvironmentContextHierarchyTests.ParentConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentDefinedPortTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentDefinedPortTests.java similarity index 93% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentDefinedPortTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentDefinedPortTests.java index 281ab16e6000..fd5c436012ff 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentDefinedPortTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentDefinedPortTests.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentRandomPortCustomPortTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentRandomPortCustomPortTests.java similarity index 88% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentRandomPortCustomPortTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentRandomPortCustomPortTests.java index 4b9b82b0c902..60ddd78f311f 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentRandomPortCustomPortTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentRandomPortCustomPortTests.java @@ -14,13 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.AbstractSpringBootTestWebServerWebEnvironmentTests.AbstractConfig; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.test.AbstractSpringBootTestWebServerWebEnvironmentTests.AbstractConfig; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.test.annotation.DirtiesContext; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentRandomPortTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentRandomPortTests.java similarity index 92% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentRandomPortTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentRandomPortTests.java index baff7cfe979b..a6cf4b62bc99 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWebEnvironmentRandomPortTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/SpringBootTestWebEnvironmentRandomPortTests.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.test.context; +package org.springframework.boot.web.server.test; import org.junit.jupiter.api.Test; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.StringHttpMessageConverter; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandlerTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/LocalHostUriTemplateHandlerTests.java similarity index 98% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandlerTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/LocalHostUriTemplateHandlerTests.java index 630bf22771df..f25223b3d9e9 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandlerTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/LocalHostUriTemplateHandlerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import java.net.URI; import java.util.HashMap; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/NoTestRestTemplateBeanChecker.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/NoTestRestTemplateBeanChecker.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/NoTestRestTemplateBeanChecker.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/NoTestRestTemplateBeanChecker.java index 12a5dc967bdd..3d51c2fe8b40 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/NoTestRestTemplateBeanChecker.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/NoTestRestTemplateBeanChecker.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerIntegrationTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerIntegrationTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerIntegrationTests.java index 68341fb24a25..e1ad9363aff5 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerIntegrationTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import java.io.IOException; import java.io.PrintWriter; @@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerTests.java similarity index 94% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerTests.java index 119d343f6e08..80a5492091fd 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import org.junit.jupiter.api.Test; @@ -23,7 +23,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer.TestRestTemplateRegistrar; +import org.springframework.boot.web.server.test.client.TestRestTemplateContextCustomizer.TestRestTemplateRegistrar; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.test.context.MergedContextConfiguration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerWithFactoryBeanTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerWithFactoryBeanTests.java similarity index 93% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerWithFactoryBeanTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerWithFactoryBeanTests.java index 756fc50c167b..12c65e349e5f 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerWithFactoryBeanTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerWithFactoryBeanTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerWithOverrideIntegrationTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerWithOverrideIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerWithOverrideIntegrationTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerWithOverrideIntegrationTests.java index efdd40772d70..6ea83651c0b4 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerWithOverrideIntegrationTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateContextCustomizerWithOverrideIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import java.io.IOException; import java.io.PrintWriter; @@ -28,7 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateTests.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateTests.java index 93c2fb6f2ec1..927a028a09f4 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/TestRestTemplateTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client; +package org.springframework.boot.web.server.test.client; import java.io.IOException; import java.lang.reflect.Method; @@ -35,8 +35,8 @@ import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.http.client.HttpRedirects; -import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.web.server.test.client.TestRestTemplate.HttpClientOption; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -140,11 +140,8 @@ void authenticated() { } @Test - @SuppressWarnings("removal") void options() { - RequestConfig config = getRequestConfig( - new TestRestTemplate(HttpClientOption.ENABLE_REDIRECTS, HttpClientOption.ENABLE_COOKIES)); - assertThat(config.isRedirectsEnabled()).isTrue(); + RequestConfig config = getRequestConfig(new TestRestTemplate(HttpClientOption.ENABLE_COOKIES)); assertThat(config.getCookieSpec()).isEqualTo("strict"); } @@ -164,13 +161,9 @@ void httpComponentsAreBuiltConsideringSettingsInRestTemplateBuilder() { RestTemplateBuilder builder = new RestTemplateBuilder() .requestFactoryBuilder(ClientHttpRequestFactoryBuilder.httpComponents()); assertThat(getRedirectStrategy((RestTemplateBuilder) null)).matches(this::isFollowStrategy); - assertThat(getRedirectStrategy(null, HttpClientOption.ENABLE_REDIRECTS)).matches(this::isFollowStrategy); assertThat(getRedirectStrategy(builder)).matches(this::isFollowStrategy); - assertThat(getRedirectStrategy(builder, HttpClientOption.ENABLE_REDIRECTS)).matches(this::isFollowStrategy); assertThat(getRedirectStrategy(builder.redirects(HttpRedirects.DONT_FOLLOW))) .matches(this::isDontFollowStrategy); - assertThat(getRedirectStrategy(builder.redirects(HttpRedirects.DONT_FOLLOW), HttpClientOption.ENABLE_REDIRECTS)) - .matches(this::isFollowStrategy); } @Test diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/NoWebTestClientBeanChecker.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/NoWebTestClientBeanChecker.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/NoWebTestClientBeanChecker.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/NoWebTestClientBeanChecker.java index e2353edd6ae7..89c55e62c484 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/NoWebTestClientBeanChecker.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/NoWebTestClientBeanChecker.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerIntegrationTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerIntegrationTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerIntegrationTests.java index 411fc7061616..c6ca610ca54a 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerIntegrationTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTests.java similarity index 94% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTests.java index 104bf6e0d86e..e0280a9e9c06 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import org.junit.jupiter.api.Test; @@ -23,7 +23,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.web.reactive.server.WebTestClientContextCustomizer.WebTestClientRegistrar; +import org.springframework.boot.web.server.test.client.reactive.WebTestClientContextCustomizer.WebTestClientRegistrar; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.test.context.MergedContextConfiguration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithCustomBasePathTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomBasePathTests.java similarity index 95% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithCustomBasePathTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomBasePathTests.java index 544104d87691..f039b59b626c 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithCustomBasePathTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomBasePathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import java.util.Collections; import java.util.Map; @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.buffer.DefaultDataBufferFactory; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithCustomContextPathTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomContextPathTests.java similarity index 94% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithCustomContextPathTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomContextPathTests.java index a922e717db95..04c278d79b4e 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithCustomContextPathTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomContextPathTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithOverrideIntegrationTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithOverrideIntegrationTests.java similarity index 95% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithOverrideIntegrationTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithOverrideIntegrationTests.java index b9fe003f866e..a5e92eb24d35 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithOverrideIntegrationTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithOverrideIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; +import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java index a133e34b202d..bd81bbc26cb6 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactive.server; +package org.springframework.boot.web.server.test.client.reactive; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClientTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/htmlunit/LocalHostWebClientTests.java similarity index 98% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClientTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/htmlunit/LocalHostWebClientTests.java index 756dbc629cc7..96aa5f51a9c6 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/LocalHostWebClientTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/htmlunit/LocalHostWebClientTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.htmlunit; +package org.springframework.boot.web.server.test.htmlunit; import java.io.IOException; import java.net.URL; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java similarity index 98% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java index c9a13f9e22df..f6c5d8ad8819 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/htmlunit/webdriver/LocalHostWebConnectionHtmlUnitDriverTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.htmlunit.webdriver; +package org.springframework.boot.web.server.test.htmlunit.webdriver; import java.net.URL; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactoryTests.java b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactoryTests.java similarity index 96% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactoryTests.java rename to spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactoryTests.java index e3fab87b4a72..4dc118dd265f 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactoryTests.java +++ b/spring-boot-project/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/reactor/netty/DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.reactor.netty; +package org.springframework.boot.web.server.test.reactor.netty; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-test/src/test/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensionsTests.kt b/spring-boot-project/spring-boot-web-server-test/src/test/kotlin/org/springframework/boot/web/server/test/client/TestRestTemplateExtensionsTests.kt similarity index 98% rename from spring-boot-project/spring-boot-test/src/test/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensionsTests.kt rename to spring-boot-project/spring-boot-web-server-test/src/test/kotlin/org/springframework/boot/web/server/test/client/TestRestTemplateExtensionsTests.kt index 31a1150cc52b..f766585c9c8f 100644 --- a/spring-boot-project/spring-boot-test/src/test/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensionsTests.kt +++ b/spring-boot-project/spring-boot-web-server-test/src/test/kotlin/org/springframework/boot/web/server/test/client/TestRestTemplateExtensionsTests.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test.web.client +package org.springframework.boot.web.server.test.client import io.mockk.mockk import io.mockk.verify @@ -243,7 +243,7 @@ class TestRestTemplateExtensionsTests { @Test fun `RestOperations are available`() { val extensions = Class.forName( - "org.springframework.boot.test.web.client.TestRestTemplateExtensionsKt") + "org.springframework.boot.web.server.test.client.TestRestTemplateExtensionsKt") ReflectionUtils.doWithMethods(RestOperations::class.java) { method -> arrayOf(ParameterizedTypeReference::class, Class::class).forEach { kClass -> if (method.parameterTypes.contains(kClass.java)) { diff --git a/spring-boot-project/spring-boot-web-server/build.gradle b/spring-boot-project/spring-boot-web-server/build.gradle new file mode 100644 index 000000000000..f104f9a10f61 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/build.gradle @@ -0,0 +1,60 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "java-test-fixtures" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Web Server" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-web") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("io.projectreactor:reactor-core") + optional("jakarta.servlet:jakarta.servlet-api") + optional("org.springframework:spring-test") + + testFixturesCompileOnly(project(":spring-boot-project:spring-boot-test")) + testFixturesCompileOnly(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testFixturesCompileOnly("io.projectreactor:reactor-test") + testFixturesCompileOnly("io.projectreactor.netty:reactor-netty-http") + testFixturesCompileOnly("org.apache.httpcomponents.client5:httpclient5") + testFixturesCompileOnly("org.apache.tomcat.embed:tomcat-embed-jasper") + testFixturesCompileOnly("org.eclipse.jetty.http2:jetty-http2-client") + testFixturesCompileOnly("org.eclipse.jetty.http2:jetty-http2-client-transport") + testFixturesCompileOnly("jakarta.servlet:jakarta.servlet-api") + testFixturesCompileOnly("jakarta.websocket:jakarta.websocket-api") + testFixturesCompileOnly("jakarta.websocket:jakarta.websocket-client-api") + testFixturesCompileOnly("org.mockito:mockito-core") + testFixturesCompileOnly("org.springframework:spring-tx") + testFixturesCompileOnly("org.springframework:spring-webflux") + testFixturesCompileOnly("org.springframework:spring-webmvc") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot"))) + testImplementation("org.apache.tomcat.embed:tomcat-embed-core") + testImplementation("org.springframework:spring-webmvc") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java index 9ca73f8e6838..8550a132f20a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java @@ -28,6 +28,7 @@ import org.springframework.boot.ssl.SslBundle; import org.springframework.boot.ssl.SslBundles; +import org.springframework.boot.web.error.ErrorPage; import org.springframework.boot.web.server.Ssl.ServerNameSslBundle; import org.springframework.util.Assert; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Compression.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Compression.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Compression.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Compression.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ConfigurableWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/ConfigurableWebServerFactory.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ConfigurableWebServerFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/ConfigurableWebServerFactory.java index fa99f8ee8f6d..b3c3642a206b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ConfigurableWebServerFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/ConfigurableWebServerFactory.java @@ -20,6 +20,8 @@ import java.util.Set; import org.springframework.boot.ssl.SslBundles; +import org.springframework.boot.web.error.ErrorPage; +import org.springframework.boot.web.error.ErrorPageRegistry; /** * A configurable {@link WebServerFactory}. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Cookie.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Cookie.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Cookie.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Cookie.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/GracefulShutdownCallback.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/GracefulShutdownCallback.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/GracefulShutdownCallback.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/GracefulShutdownCallback.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/GracefulShutdownResult.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/GracefulShutdownResult.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/GracefulShutdownResult.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/GracefulShutdownResult.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Http2.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Http2.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Http2.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Http2.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/MimeMappings.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/MimeMappings.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/MimeMappings.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/MimeMappings.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PortInUseException.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/PortInUseException.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PortInUseException.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/PortInUseException.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PortInUseFailureAnalyzer.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/PortInUseFailureAnalyzer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PortInUseFailureAnalyzer.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/PortInUseFailureAnalyzer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Shutdown.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Shutdown.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Shutdown.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Shutdown.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Ssl.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Ssl.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServer.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServer.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerException.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerException.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerException.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerException.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerFactory.java similarity index 87% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerFactory.java index 6bc3755f3656..a393601b6c41 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerFactory.java @@ -22,8 +22,8 @@ * @author Phillip Webb * @since 2.0.0 * @see WebServer - * @see org.springframework.boot.web.servlet.server.ServletWebServerFactory - * @see org.springframework.boot.web.reactive.server.ReactiveWebServerFactory + * @see org.springframework.boot.web.server.servlet.ServletWebServerFactory + * @see org.springframework.boot.web.server.reactive.ReactiveWebServerFactory */ public interface WebServerFactory { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerFactoryCustomizer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerFactoryCustomizer.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerFactoryCustomizer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerFactoryCustomizerBeanPostProcessor.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerFactoryCustomizerBeanPostProcessor.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerFactoryCustomizerBeanPostProcessor.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerFactoryCustomizerBeanPostProcessor.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerSslBundle.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerSslBundle.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/WebServerSslBundle.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/WebServerSslBundle.java diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/ServerProperties.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/ServerProperties.java new file mode 100644 index 000000000000..518a9e360032 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/ServerProperties.java @@ -0,0 +1,390 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.autoconfigure; + +import java.net.InetAddress; +import java.nio.charset.Charset; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; +import org.springframework.boot.convert.DurationUnit; +import org.springframework.boot.web.server.Compression; +import org.springframework.boot.web.server.Cookie; +import org.springframework.boot.web.server.Http2; +import org.springframework.boot.web.server.MimeMappings; +import org.springframework.boot.web.server.Shutdown; +import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.servlet.Jsp; +import org.springframework.boot.web.server.servlet.Session; +import org.springframework.util.StringUtils; +import org.springframework.util.unit.DataSize; + +/** + * {@link ConfigurationProperties @ConfigurationProperties} for a web server (e.g. port + * and path settings). + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Ivan Sopov + * @author Marcos Barbero + * @author Eddú Meléndez + * @author Quinten De Swaef + * @author Venil Noronha + * @author Aurélien Leboulanger + * @author Brian Clozel + * @author Olivier Lamy + * @author Chentao Qu + * @author Artsiom Yudovin + * @author Andrew McGhie + * @author Rafiullah Hamedy + * @author Dirk Deyne + * @author HaiTao Zhang + * @author Victor Mandujano + * @author Chris Bono + * @author Parviz Rozikov + * @author Florian Storz + * @author Michael Weidmann + * @author Lasse Wulff + * @since 1.0.0 + */ +@ConfigurationProperties("server") +public class ServerProperties { + + /** + * Server HTTP port. + */ + private Integer port; + + /** + * Network address to which the server should bind. + */ + private InetAddress address; + + @NestedConfigurationProperty + private final ErrorProperties error = new ErrorProperties(); + + /** + * Strategy for handling X-Forwarded-* headers. + */ + private ForwardHeadersStrategy forwardHeadersStrategy; + + /** + * Value to use for the Server response header (if empty, no header is sent). + */ + private String serverHeader; + + /** + * Maximum size of the HTTP request header. Refer to the documentation for your chosen + * embedded server for details of exactly how this limit is applied. For example, + * Netty applies the limit separately to each individual header in the request whereas + * Tomcat applies the limit to the combined size of the request line and all of the + * header names and values in the request. + */ + private DataSize maxHttpRequestHeaderSize = DataSize.ofKilobytes(8); + + /** + * Type of shutdown that the server will support. + */ + private Shutdown shutdown = Shutdown.GRACEFUL; + + @NestedConfigurationProperty + private Ssl ssl; + + @NestedConfigurationProperty + private final Compression compression = new Compression(); + + /** + * Custom MIME mappings in addition to the default MIME mappings. + */ + private final MimeMappings mimeMappings = new MimeMappings(); + + @NestedConfigurationProperty + private final Http2 http2 = new Http2(); + + private final Servlet servlet = new Servlet(); + + private final Reactive reactive = new Reactive(); + + public Integer getPort() { + return this.port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public InetAddress getAddress() { + return this.address; + } + + public void setAddress(InetAddress address) { + this.address = address; + } + + public String getServerHeader() { + return this.serverHeader; + } + + public void setServerHeader(String serverHeader) { + this.serverHeader = serverHeader; + } + + public DataSize getMaxHttpRequestHeaderSize() { + return this.maxHttpRequestHeaderSize; + } + + public void setMaxHttpRequestHeaderSize(DataSize maxHttpRequestHeaderSize) { + this.maxHttpRequestHeaderSize = maxHttpRequestHeaderSize; + } + + public Shutdown getShutdown() { + return this.shutdown; + } + + public void setShutdown(Shutdown shutdown) { + this.shutdown = shutdown; + } + + public ErrorProperties getError() { + return this.error; + } + + public Ssl getSsl() { + return this.ssl; + } + + public void setSsl(Ssl ssl) { + this.ssl = ssl; + } + + public Compression getCompression() { + return this.compression; + } + + public MimeMappings getMimeMappings() { + return this.mimeMappings; + } + + public void setMimeMappings(Map customMappings) { + customMappings.forEach(this.mimeMappings::add); + } + + public Http2 getHttp2() { + return this.http2; + } + + public Servlet getServlet() { + return this.servlet; + } + + public Reactive getReactive() { + return this.reactive; + } + + public ForwardHeadersStrategy getForwardHeadersStrategy() { + return this.forwardHeadersStrategy; + } + + public void setForwardHeadersStrategy(ForwardHeadersStrategy forwardHeadersStrategy) { + this.forwardHeadersStrategy = forwardHeadersStrategy; + } + + /** + * Servlet server properties. + */ + public static class Servlet { + + /** + * Servlet context init parameters. + */ + private final Map contextParameters = new HashMap<>(); + + /** + * Context path of the application. + */ + private String contextPath; + + /** + * Display name of the application. + */ + private String applicationDisplayName = "application"; + + /** + * Whether to register the default Servlet with the container. + */ + private boolean registerDefaultServlet = false; + + private final Encoding encoding = new Encoding(); + + @NestedConfigurationProperty + private final Jsp jsp = new Jsp(); + + @NestedConfigurationProperty + private final Session session = new Session(); + + public String getContextPath() { + return this.contextPath; + } + + public void setContextPath(String contextPath) { + this.contextPath = cleanContextPath(contextPath); + } + + private String cleanContextPath(String contextPath) { + String candidate = null; + if (StringUtils.hasLength(contextPath)) { + candidate = contextPath.strip(); + } + if (StringUtils.hasText(candidate) && candidate.endsWith("/")) { + return candidate.substring(0, candidate.length() - 1); + } + return candidate; + } + + public String getApplicationDisplayName() { + return this.applicationDisplayName; + } + + public void setApplicationDisplayName(String displayName) { + this.applicationDisplayName = displayName; + } + + public boolean isRegisterDefaultServlet() { + return this.registerDefaultServlet; + } + + public void setRegisterDefaultServlet(boolean registerDefaultServlet) { + this.registerDefaultServlet = registerDefaultServlet; + } + + public Map getContextParameters() { + return this.contextParameters; + } + + public Encoding getEncoding() { + return this.encoding; + } + + public Jsp getJsp() { + return this.jsp; + } + + public Session getSession() { + return this.session; + } + + } + + /** + * Reactive server properties. + */ + public static class Reactive { + + private final Session session = new Session(); + + public Session getSession() { + return this.session; + } + + public static class Session { + + /** + * Session timeout. If a duration suffix is not specified, seconds will be + * used. + */ + @DurationUnit(ChronoUnit.SECONDS) + private Duration timeout = Duration.ofMinutes(30); + + /** + * Maximum number of sessions that can be stored. + */ + private int maxSessions = 10000; + + @NestedConfigurationProperty + private final Cookie cookie = new Cookie(); + + public Duration getTimeout() { + return this.timeout; + } + + public void setTimeout(Duration timeout) { + this.timeout = timeout; + } + + public int getMaxSessions() { + return this.maxSessions; + } + + public void setMaxSessions(int maxSessions) { + this.maxSessions = maxSessions; + } + + public Cookie getCookie() { + return this.cookie; + } + + } + + } + + /** + * Strategies for supporting forward headers. + */ + public enum ForwardHeadersStrategy { + + /** + * Use the underlying container's native support for forwarded headers. + */ + NATIVE, + + /** + * Use Spring's support for handling forwarded headers. + */ + FRAMEWORK, + + /** + * Ignore X-Forwarded-* headers. + */ + NONE + + } + + public static class Encoding { + + /** + * Mapping of locale to charset for response encoding. + */ + private Map mapping; + + public Map getMapping() { + return this.mapping; + } + + public void setMapping(Map mapping) { + this.mapping = mapping; + } + + } + +} diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/package-info.java new file mode 100644 index 000000000000..13a8a376f6b8 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a web server. + */ +package org.springframework.boot.web.server.autoconfigure; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerConfiguration.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerConfiguration.java new file mode 100644 index 000000000000..7dd622f38696 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerConfiguration.java @@ -0,0 +1,101 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.autoconfigure.reactive; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.ObjectUtils; +import org.springframework.web.server.adapter.ForwardedHeaderTransformer; + +/** + * {@link Configuration Configuration} for a reactive web server. + * + * @author Brian Clozel + * @author Scott Frederick + * @since 4.0.0 + */ +@Configuration(proxyBeanMethods = false) +@EnableConfigurationProperties(ServerProperties.class) +@Import(ReactiveWebServerConfiguration.BeanPostProcessorsRegistrar.class) +public class ReactiveWebServerConfiguration { + + @Bean + public ReactiveWebServerFactoryCustomizer reactiveWebServerFactoryCustomizer(ServerProperties serverProperties, + ObjectProvider sslBundles) { + return new ReactiveWebServerFactoryCustomizer(serverProperties, sslBundles.getIfAvailable()); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(name = "server.forward-headers-strategy", havingValue = "framework") + public ForwardedHeaderTransformer forwardedHeaderTransformer() { + return new ForwardedHeaderTransformer(); + } + + /** + * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via + * {@link ImportBeanDefinitionRegistrar} for early registration. + */ + public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { + + private ConfigurableListableBeanFactory beanFactory; + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + if (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) { + this.beanFactory = listableBeanFactory; + } + } + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, + BeanDefinitionRegistry registry) { + if (this.beanFactory == null) { + return; + } + registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor", + WebServerFactoryCustomizerBeanPostProcessor.class); + } + + private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, + Class beanClass) { + if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass); + beanDefinition.setSynthetic(true); + registry.registerBeanDefinition(name, beanDefinition); + } + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerFactoryCustomizer.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryCustomizer.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerFactoryCustomizer.java index 46638f06e1ba..cbd0a4f67e72 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerFactoryCustomizer.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.web.server.autoconfigure.reactive; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; import org.springframework.core.Ordered; /** @@ -30,7 +30,7 @@ * @author Brian Clozel * @author Yunkun Huang * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ public class ReactiveWebServerFactoryCustomizer implements WebServerFactoryCustomizer, Ordered { @@ -51,7 +51,7 @@ public ReactiveWebServerFactoryCustomizer(ServerProperties serverProperties) { * Create a new {@link ReactiveWebServerFactoryCustomizer} instance. * @param serverProperties the server properties * @param sslBundles the SSL bundles - * @since 3.1.0 + * @since 4.0.0 */ public ReactiveWebServerFactoryCustomizer(ServerProperties serverProperties, SslBundles sslBundles) { this.serverProperties = serverProperties; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/package-info.java new file mode 100644 index 000000000000..f70ff6a6cc29 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a reactive web server. + */ +package org.springframework.boot.web.server.autoconfigure.reactive; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ForwardedHeaderFilterCustomizer.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ForwardedHeaderFilterCustomizer.java new file mode 100644 index 000000000000..b8044a9e3e88 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ForwardedHeaderFilterCustomizer.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.autoconfigure.servlet; + +import org.springframework.web.filter.ForwardedHeaderFilter; + +/** + * Customizer for the auto-configured {@link ForwardedHeaderFilter}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public interface ForwardedHeaderFilterCustomizer { + + /** + * Customizes the given {@code filter}. + * @param filter the filter to customize + */ + void customize(ForwardedHeaderFilter filter); + +} diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerConfiguration.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerConfiguration.java new file mode 100644 index 000000000000..79aea0a6654a --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerConfiguration.java @@ -0,0 +1,122 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.autoconfigure.servlet; + +import jakarta.servlet.DispatcherType; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.ssl.SslBundles; +import org.springframework.boot.web.error.ErrorPageRegistrarBeanPostProcessor; +import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier; +import org.springframework.boot.web.server.servlet.WebListenerRegistrar; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.Ordered; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.ObjectUtils; +import org.springframework.web.filter.ForwardedHeaderFilter; + +/** + * {@link Configuration Configuration} for a servlet web server. + * + * @author Phillip Webb + * @author Dave Syer + * @author Ivan Sopov + * @author Brian Clozel + * @author Stephane Nicoll + * @author Scott Frederick + * @since 4.0.0 + */ +@Configuration(proxyBeanMethods = false) +@EnableConfigurationProperties(ServerProperties.class) +@Import(ServletWebServerConfiguration.BeanPostProcessorsRegistrar.class) +public class ServletWebServerConfiguration { + + @Bean + ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties, + ObjectProvider webListenerRegistrars, + ObjectProvider cookieSameSiteSuppliers, ObjectProvider sslBundles) { + return new ServletWebServerFactoryCustomizer(serverProperties, webListenerRegistrars.orderedStream().toList(), + cookieSameSiteSuppliers.orderedStream().toList(), sslBundles.getIfAvailable()); + } + + @Bean + @ConditionalOnProperty(name = "server.forward-headers-strategy", havingValue = "framework") + @ConditionalOnMissingFilterBean(ForwardedHeaderFilter.class) + FilterRegistrationBean forwardedHeaderFilter( + ObjectProvider customizerProvider) { + ForwardedHeaderFilter filter = new ForwardedHeaderFilter(); + customizerProvider.ifAvailable((customizer) -> customizer.customize(filter)); + FilterRegistrationBean registration = new FilterRegistrationBean<>(filter); + registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR); + registration.setOrder(Ordered.HIGHEST_PRECEDENCE); + return registration; + } + + /** + * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via + * {@link ImportBeanDefinitionRegistrar} for early registration. + */ + static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { + + private ConfigurableListableBeanFactory beanFactory; + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + if (beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) { + this.beanFactory = listableBeanFactory; + } + } + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, + BeanDefinitionRegistry registry) { + if (this.beanFactory == null) { + return; + } + registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor", + WebServerFactoryCustomizerBeanPostProcessor.class); + registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor", + ErrorPageRegistrarBeanPostProcessor.class); + } + + private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, + Class beanClass) { + if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass); + beanDefinition.setSynthetic(true); + registry.registerBeanDefinition(name, beanDefinition); + } + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerFactoryCustomizer.java similarity index 87% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryCustomizer.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerFactoryCustomizer.java index 224d60e042d0..7da8fd14ceb3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerFactoryCustomizer.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.web.server.autoconfigure.servlet; import java.util.Collections; import java.util.List; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.ssl.SslBundles; import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.WebListenerRegistrar; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; -import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier; +import org.springframework.boot.web.server.servlet.WebListenerRegistrar; import org.springframework.core.Ordered; import org.springframework.util.CollectionUtils; @@ -39,7 +39,7 @@ * @author Yunkun Huang * @author Scott Frederick * @author Lasse Wulff - * @since 2.0.0 + * @since 4.0.0 */ public class ServletWebServerFactoryCustomizer implements WebServerFactoryCustomizer, Ordered { @@ -53,15 +53,10 @@ public class ServletWebServerFactoryCustomizer private final SslBundles sslBundles; public ServletWebServerFactoryCustomizer(ServerProperties serverProperties) { - this(serverProperties, Collections.emptyList()); + this(serverProperties, Collections.emptyList(), Collections.emptyList(), null); } public ServletWebServerFactoryCustomizer(ServerProperties serverProperties, - List webListenerRegistrars) { - this(serverProperties, webListenerRegistrars, null, null); - } - - ServletWebServerFactoryCustomizer(ServerProperties serverProperties, List webListenerRegistrars, List cookieSameSiteSuppliers, SslBundles sslBundles) { this.serverProperties = serverProperties; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..6514d77336ce --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Classes related to the auto-configuration of a servlet web server. + */ +package org.springframework.boot.web.server.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ConfigurableWebServerApplicationContext.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/ConfigurableWebServerApplicationContext.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ConfigurableWebServerApplicationContext.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/ConfigurableWebServerApplicationContext.java index 5f1133eca252..d88d5ba6df75 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ConfigurableWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/ConfigurableWebServerApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import org.springframework.context.ConfigurableApplicationContext; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanException.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanException.java index 4b988cb4de0b..f8588b701fb7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.WebApplicationType; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanFailureAnalyzer.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanFailureAnalyzer.java index 1bfb3bb0b855..24fe16a3f9ab 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanFailureAnalyzer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import java.util.Locale; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ServerPortInfoApplicationContextInitializer.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/ServerPortInfoApplicationContextInitializer.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ServerPortInfoApplicationContextInitializer.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/ServerPortInfoApplicationContextInitializer.java index c40a3108085a..cb5eeec61e4f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ServerPortInfoApplicationContextInitializer.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/ServerPortInfoApplicationContextInitializer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import java.util.HashMap; import java.util.Map; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerApplicationContext.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerApplicationContext.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerApplicationContext.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerApplicationContext.java index e955f5581c56..dce6dd9940c9 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerApplicationContext.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import org.springframework.boot.web.server.WebServer; import org.springframework.context.ApplicationContext; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerGracefulShutdownLifecycle.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerGracefulShutdownLifecycle.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerGracefulShutdownLifecycle.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerGracefulShutdownLifecycle.java index 40b0ce5db80e..8091615a9321 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerGracefulShutdownLifecycle.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerGracefulShutdownLifecycle.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import org.springframework.boot.web.server.WebServer; import org.springframework.context.SmartLifecycle; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerInitializedEvent.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerInitializedEvent.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerInitializedEvent.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerInitializedEvent.java index 759767da97cd..1b1fc8708f10 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerInitializedEvent.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerInitializedEvent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import org.springframework.boot.web.server.WebServer; import org.springframework.context.ApplicationEvent; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerPortFileWriter.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerPortFileWriter.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerPortFileWriter.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerPortFileWriter.java index 355ad2724a54..0a37fcbca47b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerPortFileWriter.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/WebServerPortFileWriter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import java.io.File; import java.util.Locale; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/package-info.java new file mode 100644 index 000000000000..fcec8ee25cfa --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/context/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Web integrations with Spring's {@link org.springframework.context.ApplicationContext + * ApplicationContext}. + */ +package org.springframework.boot.web.server.context; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/package-info.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/package-info.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactory.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactory.java index ed6bfd412e5c..7c7fa89a1898 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.server; +package org.springframework.boot.web.server.reactive; import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; @@ -22,7 +22,7 @@ * Abstract base class for {@link ReactiveWebServerFactory} implementations. * * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ public abstract class AbstractReactiveWebServerFactory extends AbstractConfigurableWebServerFactory implements ConfigurableReactiveWebServerFactory { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ConfigurableReactiveWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/ConfigurableReactiveWebServerFactory.java similarity index 92% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ConfigurableReactiveWebServerFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/ConfigurableReactiveWebServerFactory.java index 45740966d1a8..d6a533527693 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ConfigurableReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/ConfigurableReactiveWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.server; +package org.springframework.boot.web.server.reactive; import org.springframework.boot.web.server.ConfigurableWebServerFactory; @@ -22,7 +22,7 @@ * Configurable {@link ReactiveWebServerFactory}. * * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ public interface ConfigurableReactiveWebServerFactory extends ConfigurableWebServerFactory, ReactiveWebServerFactory { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/ReactiveWebServerFactory.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/ReactiveWebServerFactory.java index 177d42d2bede..532a09b2d23b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/ReactiveWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.server; +package org.springframework.boot.web.server.reactive; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.WebServerFactory; @@ -24,7 +24,7 @@ * Factory interface that can be used to create a reactive {@link WebServer}. * * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 * @see WebServer */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java index 0f1ffa985b8a..698ff5f85a21 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; import java.util.Arrays; import java.util.LinkedHashSet; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ApplicationReactiveWebEnvironment.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ApplicationReactiveWebEnvironment.java similarity index 90% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ApplicationReactiveWebEnvironment.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ApplicationReactiveWebEnvironment.java index 2dacc32d081d..a40314d58c82 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ApplicationReactiveWebEnvironment.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ApplicationReactiveWebEnvironment.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; import org.springframework.boot.SpringApplication; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; +import org.springframework.boot.web.context.reactive.StandardReactiveWebEnvironment; import org.springframework.core.env.ConfigurablePropertyResolver; import org.springframework.core.env.MutablePropertySources; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContext.java similarity index 92% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContext.java index bc341710c879..42de45cea0c7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContext.java @@ -14,18 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.WebApplicationType; import org.springframework.boot.availability.AvailabilityChangeEvent; import org.springframework.boot.availability.ReadinessState; -import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; -import org.springframework.boot.web.context.MissingWebServerFactoryBeanException; -import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; +import org.springframework.boot.web.context.reactive.GenericReactiveWebApplicationContext; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.ConfigurableWebServerApplicationContext; +import org.springframework.boot.web.server.context.MissingWebServerFactoryBeanException; +import org.springframework.boot.web.server.context.WebServerGracefulShutdownLifecycle; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; import org.springframework.context.ApplicationContextException; import org.springframework.core.metrics.StartupStep; import org.springframework.http.server.reactive.HttpHandler; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContextFactory.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContextFactory.java index 084d285bda1f..4ae2871be667 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContextFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; import org.springframework.aot.AotDetector; import org.springframework.boot.ApplicationContextFactory; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerInitializedEvent.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerInitializedEvent.java similarity index 90% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerInitializedEvent.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerInitializedEvent.java index 038411c4e2ad..75a013a9a7d0 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerInitializedEvent.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerInitializedEvent.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; -import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerInitializedEvent; /** * Event to be published after the {@link WebServer} is ready. Useful for obtaining the diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/WebServerManager.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/WebServerManager.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/WebServerManager.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/WebServerManager.java index 448433c3d8e0..108cbeb787c5 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/WebServerManager.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/WebServerManager.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; import java.util.function.Supplier; import reactor.core.publisher.Mono; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.boot.web.server.GracefulShutdownCallback; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/WebServerStartStopLifecycle.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/WebServerStartStopLifecycle.java new file mode 100644 index 000000000000..097117d6c318 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/WebServerStartStopLifecycle.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.reactive.context; + +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.context.SmartLifecycle; + +/** + * {@link SmartLifecycle} to start and stop the {@link WebServer} in a + * {@link ReactiveWebServerApplicationContext}. + * + * @author Andy Wilkinson + */ +class WebServerStartStopLifecycle implements SmartLifecycle { + + private final WebServerManager weServerManager; + + private volatile boolean running; + + WebServerStartStopLifecycle(WebServerManager weServerManager) { + this.weServerManager = weServerManager; + } + + @Override + public void start() { + this.weServerManager.start(); + this.running = true; + } + + @Override + public void stop() { + this.running = false; + this.weServerManager.stop(); + } + + @Override + public boolean isRunning() { + return this.running; + } + + @Override + public int getPhase() { + return WebServerApplicationContext.START_STOP_LIFECYCLE_PHASE; + } + +} diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/package-info.java new file mode 100644 index 000000000000..3c765592ebd7 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/context/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive web server based integrations with Spring's + * {@link org.springframework.context.ApplicationContext ApplicationContext}. + */ +package org.springframework.boot.web.server.reactive.context; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/package-info.java new file mode 100644 index 000000000000..4419bc5cdc39 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/reactive/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive web server abstractions. + */ +package org.springframework.boot.web.server.reactive; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ConfigurableServletWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ConfigurableServletWebServerFactory.java new file mode 100644 index 000000000000..1911b3d911b8 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ConfigurableServletWebServerFactory.java @@ -0,0 +1,195 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.servlet; + +import java.io.File; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import jakarta.servlet.ServletContext; + +import org.springframework.boot.web.server.ConfigurableWebServerFactory; +import org.springframework.boot.web.server.Cookie.SameSite; +import org.springframework.boot.web.server.MimeMappings; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.servlet.ServletContextInitializer; + +/** + * A configurable {@link ServletWebServerFactory}. + * + * @author Dave Syer + * @author Andy Wilkinson + * @author Stephane Nicoll + * @author Eddú Meléndez + * @author Brian Clozel + * @since 4.0.0 + * @see ServletWebServerFactory + * @see WebServerFactoryCustomizer + */ +public interface ConfigurableServletWebServerFactory + extends ConfigurableWebServerFactory, ServletWebServerFactory, WebListenerRegistry { + + ServletWebServerSettings getSettings(); + + /** + * Sets the context path for the web server. The context should start with a "/" + * character but not end with a "/" character. The default context path can be + * specified using an empty string. + * @param contextPath the context path to set + */ + default void setContextPath(String contextPath) { + getSettings().setContextPath(ContextPath.of(contextPath)); + } + + /** + * Returns the context path for the servlet web server. + * @return the context path + */ + default String getContextPath() { + return getSettings().getContextPath().toString(); + } + + /** + * Sets the display name of the application deployed in the web server. + * @param displayName the displayName to set + * @since 4.0.0 + */ + default void setDisplayName(String displayName) { + getSettings().setDisplayName(displayName); + } + + /** + * Sets the configuration that will be applied to the container's HTTP session + * support. + * @param session the session configuration + */ + default void setSession(Session session) { + getSettings().setSession(session); + } + + /** + * Set if the DefaultServlet should be registered. Defaults to {@code false} since + * 2.4. + * @param registerDefaultServlet if the default servlet should be registered + */ + default void setRegisterDefaultServlet(boolean registerDefaultServlet) { + getSettings().setRegisterDefaultServlet(registerDefaultServlet); + } + + /** + * Sets the mime-type mappings. + * @param mimeMappings the mime type mappings (defaults to + * {@link MimeMappings#DEFAULT}) + */ + default void setMimeMappings(MimeMappings mimeMappings) { + getSettings().setMimeMappings(mimeMappings); + } + + /** + * Adds mime-type mappings. + * @param mimeMappings the mime type mappings to add + * @since 4.0.0 + */ + default void addMimeMappings(MimeMappings mimeMappings) { + getSettings().addMimeMappings(mimeMappings); + } + + /** + * Sets the document root directory which will be used by the web context to serve + * static files. + * @param documentRoot the document root or {@code null} if not required + */ + default void setDocumentRoot(File documentRoot) { + getSettings().setDocumentRoot(documentRoot); + } + + /** + * Sets {@link ServletContextInitializer} that should be applied in addition to + * {@link ServletWebServerFactory#getWebServer(ServletContextInitializer...)} + * parameters. This method will replace any previously set or added initializers. + * @param initializers the initializers to set + * @see #addInitializers + */ + default void setInitializers(List initializers) { + getSettings().setInitializers(initializers); + } + + /** + * Add {@link ServletContextInitializer}s to those that should be applied in addition + * to {@link ServletWebServerFactory#getWebServer(ServletContextInitializer...)} + * parameters. + * @param initializers the initializers to add + * @see #setInitializers + */ + default void addInitializers(ServletContextInitializer... initializers) { + getSettings().addInitializers(initializers); + } + + /** + * Sets the configuration that will be applied to the server's JSP servlet. + * @param jsp the JSP servlet configuration + */ + default void setJsp(Jsp jsp) { + getSettings().setJsp(jsp); + } + + /** + * Sets the Locale to Charset mappings. + * @param localeCharsetMappings the Locale to Charset mappings + */ + default void setLocaleCharsetMappings(Map localeCharsetMappings) { + getSettings().setLocaleCharsetMappings(localeCharsetMappings); + } + + /** + * Sets the init parameters that are applied to the container's + * {@link ServletContext}. + * @param initParameters the init parameters + */ + default void setInitParameters(Map initParameters) { + getSettings().setInitParameters(initParameters); + } + + /** + * Sets {@link CookieSameSiteSupplier CookieSameSiteSuppliers} that should be used to + * obtain the {@link SameSite} attribute of any added cookie. This method will replace + * any previously set or added suppliers. + * @param cookieSameSiteSuppliers the suppliers to add + * @see #addCookieSameSiteSuppliers + */ + default void setCookieSameSiteSuppliers(List cookieSameSiteSuppliers) { + getSettings().setCookieSameSiteSuppliers(cookieSameSiteSuppliers); + } + + /** + * Add {@link CookieSameSiteSupplier CookieSameSiteSuppliers} to those that should be + * used to obtain the {@link SameSite} attribute of any added cookie. + * @param cookieSameSiteSuppliers the suppliers to add + * @see #setCookieSameSiteSuppliers + */ + default void addCookieSameSiteSuppliers(CookieSameSiteSupplier... cookieSameSiteSuppliers) { + getSettings().addCookieSameSiteSuppliers(cookieSameSiteSuppliers); + } + + @Override + default void addWebListeners(String... webListenerClassNames) { + getSettings().addWebListenerClassNames(webListenerClassNames); + } + +} diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ContextPath.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ContextPath.java new file mode 100644 index 000000000000..7efd6ed8ce65 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ContextPath.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.servlet; + +import org.springframework.util.Assert; + +/** + * The context path of a servlet web server. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public final class ContextPath { + + /** + * The default context path. + */ + public static final ContextPath DEFAULT = ContextPath.of(""); + + private final String path; + + private ContextPath(String path) { + this.path = path; + } + + public static ContextPath of(String contextPath) { + Assert.notNull(contextPath, "'contextPath' must not be null"); + if (!contextPath.isEmpty()) { + if ("/".equals(contextPath)) { + throw new IllegalArgumentException("Root context path must be specified using an empty string"); + } + if (!contextPath.startsWith("/") || contextPath.endsWith("/")) { + throw new IllegalArgumentException("Context path must start with '/' and not end with '/'"); + } + } + return new ContextPath(contextPath); + } + + @Override + public String toString() { + return this.path; + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/CookieSameSiteSupplier.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/CookieSameSiteSupplier.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/CookieSameSiteSupplier.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/CookieSameSiteSupplier.java index 8acbbeb8614e..1a97f47923f7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/CookieSameSiteSupplier.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/CookieSameSiteSupplier.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.util.function.Predicate; import java.util.function.Supplier; @@ -37,7 +37,7 @@ * * * @author Phillip Webb - * @since 2.6.0 + * @since 4.0.0 * @see ConfigurableServletWebServerFactory#addCookieSameSiteSuppliers(CookieSameSiteSupplier...) */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/DocumentRoot.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/DocumentRoot.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/DocumentRoot.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/DocumentRoot.java index 61255f3c0661..34afe526daad 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/DocumentRoot.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/DocumentRoot.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.io.File; import java.net.JarURLConnection; @@ -30,9 +30,9 @@ * Manages a {@link ServletWebServerFactory} document root. * * @author Phillip Webb - * @see AbstractServletWebServerFactory + * @since 4.0.0 */ -class DocumentRoot { +public class DocumentRoot { private static final String[] COMMON_DOC_ROOTS = { "src/main/webapp", "public", "static" }; @@ -40,7 +40,7 @@ class DocumentRoot { private File directory; - DocumentRoot(Log logger) { + public DocumentRoot(Log logger) { this.logger = logger; } @@ -48,7 +48,7 @@ File getDirectory() { return this.directory; } - void setDirectory(File directory) { + public void setDirectory(File directory) { this.directory = directory; } @@ -57,7 +57,7 @@ void setDirectory(File directory) { * warning and returning {@code null} otherwise. * @return the valid document root */ - final File getValidDirectory() { + public final File getValidDirectory() { File file = this.directory; file = (file != null) ? file : getWarFileDocumentRoot(); file = (file != null) ? file : getExplodedWarFileDocumentRoot(); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/Jsp.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/Jsp.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/Jsp.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/Jsp.java index 1163181c0b9e..7d0ea8aa8702 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/Jsp.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/Jsp.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.util.HashMap; import java.util.Map; @@ -26,7 +26,7 @@ * * @author Andy Wilkinson * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationPropertiesSource public class Jsp { diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletContextInitializers.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletContextInitializers.java new file mode 100644 index 000000000000..de0140888089 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletContextInitializers.java @@ -0,0 +1,116 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.servlet; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.SessionCookieConfig; + +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.web.server.Cookie; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.servlet.ServletContextInitializer; + +/** + * The {@link ServletContextInitializer ServletContextInitializers} to apply to a servlet + * {@link WebServer}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public final class ServletContextInitializers implements Iterable { + + private final List initializers; + + private ServletContextInitializers(List initializers) { + this.initializers = initializers; + } + + @Override + public Iterator iterator() { + return this.initializers.iterator(); + } + + /** + * Creates a new instance from the given {@code settings} and {@code initializers}. + * @param settings the settings + * @param initializers the initializers + * @return the new instance + */ + public static ServletContextInitializers from(ServletWebServerSettings settings, + ServletContextInitializer... initializers) { + List mergedInitializers = new ArrayList<>(); + mergedInitializers + .add((servletContext) -> settings.getInitParameters().forEach(servletContext::setInitParameter)); + mergedInitializers.add(new SessionConfiguringInitializer(settings.getSession())); + mergedInitializers.addAll(Arrays.asList(initializers)); + mergedInitializers.addAll(settings.getInitializers()); + return new ServletContextInitializers(mergedInitializers); + } + + private static final class SessionConfiguringInitializer implements ServletContextInitializer { + + private final Session session; + + private SessionConfiguringInitializer(Session session) { + this.session = session; + } + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + if (this.session.getTrackingModes() != null) { + servletContext.setSessionTrackingModes(unwrap(this.session.getTrackingModes())); + } + configureSessionCookie(servletContext.getSessionCookieConfig()); + } + + private void configureSessionCookie(SessionCookieConfig config) { + Cookie cookie = this.session.getCookie(); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(cookie::getName).to(config::setName); + map.from(cookie::getDomain).to(config::setDomain); + map.from(cookie::getPath).to(config::setPath); + map.from(cookie::getHttpOnly).to(config::setHttpOnly); + map.from(cookie::getSecure).to(config::setSecure); + map.from(cookie::getMaxAge).asInt(Duration::getSeconds).to(config::setMaxAge); + map.from(cookie::getPartitioned) + .as(Object::toString) + .to((partitioned) -> config.setAttribute("Partitioned", partitioned)); + } + + private Set unwrap(Set modes) { + if (modes == null) { + return null; + } + Set result = new LinkedHashSet<>(); + for (Session.SessionTrackingMode mode : modes) { + result.add(jakarta.servlet.SessionTrackingMode.valueOf(mode.name())); + } + return result; + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletWebServerFactory.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletWebServerFactory.java index be0d3fa831c6..70c1205db42f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.WebServerFactory; @@ -24,7 +24,7 @@ * Factory interface that can be used to create a {@link WebServer}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 * @see WebServer */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletWebServerSettings.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletWebServerSettings.java new file mode 100644 index 000000000000..11f9a53b132d --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/ServletWebServerSettings.java @@ -0,0 +1,189 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.servlet; + +import java.io.File; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.springframework.boot.web.server.MimeMappings; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.servlet.ServletContextInitializer; +import org.springframework.util.Assert; + +/** + * Settings for a servlet {@link WebServer} to be created by a + * {@link ConfigurableServletWebServerFactory}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class ServletWebServerSettings { + + private ContextPath contextPath = ContextPath.DEFAULT; + + private String displayName; + + private Session session = new Session(); + + private boolean registerDefaultServlet; + + private MimeMappings mimeMappings = MimeMappings.lazyCopy(MimeMappings.DEFAULT); + + private File documentRoot; + + private List initializers = new ArrayList<>(); + + private Jsp jsp = new Jsp(); + + private Map localeCharsetMappings = new HashMap<>(); + + private Map initParameters = new HashMap<>(); + + private List cookieSameSiteSuppliers = new ArrayList<>(); + + private final Set webListenerClassNames = new HashSet<>(); + + private final StaticResourceJars staticResourceJars = new StaticResourceJars(); + + public ContextPath getContextPath() { + return this.contextPath; + } + + public void setContextPath(ContextPath contextPath) { + this.contextPath = contextPath; + } + + public String getDisplayName() { + return this.displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public Session getSession() { + return this.session; + } + + public void setSession(Session session) { + this.session = session; + } + + public boolean isRegisterDefaultServlet() { + return this.registerDefaultServlet; + } + + public void setRegisterDefaultServlet(boolean registerDefaultServlet) { + this.registerDefaultServlet = registerDefaultServlet; + } + + public MimeMappings getMimeMappings() { + return this.mimeMappings; + } + + public File getDocumentRoot() { + return this.documentRoot; + } + + public void setDocumentRoot(File documentRoot) { + this.documentRoot = documentRoot; + } + + public List getInitializers() { + return this.initializers; + } + + public void setJsp(Jsp jsp) { + this.jsp = jsp; + } + + public Jsp getJsp() { + return this.jsp; + } + + public Map getLocaleCharsetMappings() { + return this.localeCharsetMappings; + } + + public Map getInitParameters() { + return this.initParameters; + } + + public List getCookieSameSiteSuppliers() { + return this.cookieSameSiteSuppliers; + } + + public void setMimeMappings(MimeMappings mimeMappings) { + Assert.notNull(mimeMappings, "'mimeMappings' must not be null"); + this.mimeMappings = new MimeMappings(mimeMappings); + } + + public void addMimeMappings(MimeMappings mimeMappings) { + mimeMappings.forEach((mapping) -> this.mimeMappings.add(mapping.getExtension(), mapping.getMimeType())); + } + + public void setInitializers(List initializers) { + Assert.notNull(initializers, "'initializers' must not be null"); + this.initializers = new ArrayList<>(initializers); + } + + public void addInitializers(ServletContextInitializer... initializers) { + Assert.notNull(initializers, "'initializers' must not be null"); + this.initializers.addAll(Arrays.asList(initializers)); + } + + public void setLocaleCharsetMappings(Map localeCharsetMappings) { + Assert.notNull(localeCharsetMappings, "'localeCharsetMappings' must not be null"); + this.localeCharsetMappings = localeCharsetMappings; + } + + public void setInitParameters(Map initParameters) { + this.initParameters = initParameters; + } + + public void setCookieSameSiteSuppliers(List cookieSameSiteSuppliers) { + Assert.notNull(cookieSameSiteSuppliers, "'cookieSameSiteSuppliers' must not be null"); + this.cookieSameSiteSuppliers = new ArrayList<>(cookieSameSiteSuppliers); + } + + public void addCookieSameSiteSuppliers(CookieSameSiteSupplier... cookieSameSiteSuppliers) { + Assert.notNull(cookieSameSiteSuppliers, "'cookieSameSiteSuppliers' must not be null"); + this.cookieSameSiteSuppliers.addAll(Arrays.asList(cookieSameSiteSuppliers)); + } + + public void addWebListenerClassNames(String... webListenerClassNames) { + this.webListenerClassNames.addAll(Arrays.asList(webListenerClassNames)); + } + + public Set getWebListenerClassNames() { + return this.webListenerClassNames; + } + + public List getStaticResourceUrls() { + return this.staticResourceJars.getUrls(); + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/Session.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/Session.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/Session.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/Session.java index a55a5e25a882..d208c59e1c2f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/Session.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/Session.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.io.File; import java.time.Duration; @@ -30,7 +30,7 @@ * Session properties. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationPropertiesSource public class Session { @@ -110,7 +110,7 @@ public Cookie getCookie() { return this.cookie; } - SessionStoreDirectory getSessionStoreDirectory() { + public SessionStoreDirectory getSessionStoreDirectory() { return this.sessionStoreDirectory; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/SessionStoreDirectory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/SessionStoreDirectory.java similarity index 90% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/SessionStoreDirectory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/SessionStoreDirectory.java index 4d89ce84b859..7d37866b61ae 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/SessionStoreDirectory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/SessionStoreDirectory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.io.File; @@ -26,9 +26,9 @@ * Manages a session store directory. * * @author Phillip Webb - * @see AbstractServletWebServerFactory + * @since 4.0.0 */ -class SessionStoreDirectory { +public class SessionStoreDirectory { private File directory; @@ -40,7 +40,7 @@ void setDirectory(File directory) { this.directory = directory; } - File getValidDirectory(boolean mkdirs) { + public File getValidDirectory(boolean mkdirs) { File dir = getDirectory(); if (dir == null) { return new ApplicationTemp().getDir("servlet-sessions"); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/StaticResourceJars.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/StaticResourceJars.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/StaticResourceJars.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/StaticResourceJars.java index 46bb56a3f9df..db4222336204 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/StaticResourceJars.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/StaticResourceJars.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.io.File; import java.io.IOException; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerRegistrar.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/WebListenerRegistrar.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerRegistrar.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/WebListenerRegistrar.java index c68a61cc4271..5a799ec29399 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerRegistrar.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/WebListenerRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet; import jakarta.servlet.annotation.WebListener; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerRegistry.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/WebListenerRegistry.java similarity index 92% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerRegistry.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/WebListenerRegistry.java index bb4f83b2ba5a..7d0637fd5028 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerRegistry.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/WebListenerRegistry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet; import jakarta.servlet.annotation.WebListener; @@ -22,12 +22,12 @@ * A registry that holds {@link WebListener @WebListeners}. * * @author Andy Wilkinson - * @since 2.4.0 + * @since 4.0.0 */ public interface WebListenerRegistry { /** - * Adds web listeners that will be registered with the servlet container. + * Adds web listeners that will be registered with the servlet web server. * @param webListenerClassNames the class names of the web listeners */ void addWebListeners(String... webListenerClassNames); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/AnnotationConfigServletWebServerApplicationContext.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/AnnotationConfigServletWebServerApplicationContext.java index fd8036b51006..18b29babe188 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/AnnotationConfigServletWebServerApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; import java.util.Arrays; import java.util.LinkedHashSet; @@ -51,7 +51,6 @@ * @see #register(Class...) * @see #scan(String...) * @see ServletWebServerApplicationContext - * @see AnnotationConfigServletWebApplicationContext */ public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext implements AnnotationConfigRegistry { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentHandler.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentHandler.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentHandler.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentHandler.java index c2b1f035275c..f604e3f9dc55 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentHandler.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.lang.annotation.Annotation; import java.util.HashMap; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentRegisteringPostProcessor.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentRegisteringPostProcessor.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentRegisteringPostProcessor.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentRegisteringPostProcessor.java index f64555a32ca9..ef31f241eb10 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentRegisteringPostProcessor.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentRegisteringPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.util.ArrayList; import java.util.Collections; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScan.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentScan.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScan.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentScan.java index 3418a3dece8e..42a4d2346253 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScan.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentScan.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanRegistrar.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanRegistrar.java index 2abf8079fee7..b23155b22b94 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanRegistrar.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.util.Arrays; import java.util.Collection; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContext.java similarity index 75% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContext.java index 7328c528e519..c2f740b0c6f5 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContext.java @@ -14,11 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; -import java.util.Collection; import java.util.Collections; -import java.util.EventListener; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; @@ -39,27 +37,25 @@ import org.springframework.boot.WebApplicationType; import org.springframework.boot.availability.AvailabilityChangeEvent; import org.springframework.boot.availability.ReadinessState; -import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; -import org.springframework.boot.web.context.MissingWebServerFactoryBeanException; -import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle; +import org.springframework.boot.web.context.servlet.WebApplicationContextInitializer; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.ConfigurableWebServerApplicationContext; +import org.springframework.boot.web.server.context.MissingWebServerFactoryBeanException; +import org.springframework.boot.web.server.context.WebServerGracefulShutdownLifecycle; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.ServletContextInitializerBeans; import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextException; import org.springframework.core.io.Resource; import org.springframework.core.metrics.StartupStep; import org.springframework.util.StringUtils; -import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.ServletContextAware; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.context.support.ServletContextAwareProcessor; import org.springframework.web.context.support.ServletContextResource; -import org.springframework.web.context.support.ServletContextScope; import org.springframework.web.context.support.WebApplicationContextUtils; /** @@ -235,23 +231,7 @@ protected ServletWebServerFactory getWebServerFactory() { * @see #prepareWebApplicationContext(ServletContext) */ private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() { - return this::selfInitialize; - } - - private void selfInitialize(ServletContext servletContext) throws ServletException { - prepareWebApplicationContext(servletContext); - registerApplicationScope(servletContext); - WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext); - for (ServletContextInitializer initializerBean : getServletContextInitializerBeans()) { - initializerBean.onStartup(servletContext); - } - } - - private void registerApplicationScope(ServletContext servletContext) { - ServletContextScope appScope = new ServletContextScope(servletContext); - getBeanFactory().registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); - // Register as ServletContext attribute, for ContextCleanupListener to detect it. - servletContext.setAttribute(ServletContextScope.class.getName(), appScope); + return new WebApplicationContextInitializer(this)::initialize; } private void registerWebApplicationScopes() { @@ -260,54 +240,6 @@ private void registerWebApplicationScopes() { existingScopes.restore(); } - /** - * Returns {@link ServletContextInitializer}s that should be used with the embedded - * web server. By default this method will first attempt to find - * {@link ServletContextInitializer}, {@link Servlet}, {@link Filter} and certain - * {@link EventListener} beans. - * @return the servlet initializer beans - */ - protected Collection getServletContextInitializerBeans() { - return new ServletContextInitializerBeans(getBeanFactory()); - } - - /** - * Prepare the {@link WebApplicationContext} with the given fully loaded - * {@link ServletContext}. This method is usually called from - * {@link ServletContextInitializer#onStartup(ServletContext)} and is similar to the - * functionality usually provided by a {@link ContextLoaderListener}. - * @param servletContext the operational servlet context - */ - protected void prepareWebApplicationContext(ServletContext servletContext) { - Object rootContext = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); - if (rootContext != null) { - if (rootContext == this) { - throw new IllegalStateException( - "Cannot initialize context because there is already a root application context present - " - + "check whether you have multiple ServletContextInitializers!"); - } - return; - } - servletContext.log("Initializing Spring embedded WebApplicationContext"); - try { - servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this); - if (logger.isDebugEnabled()) { - logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" - + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]"); - } - setServletContext(servletContext); - if (logger.isInfoEnabled()) { - long elapsedTime = System.currentTimeMillis() - getStartupDate(); - logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms"); - } - } - catch (RuntimeException | Error ex) { - logger.error("Context initialization failed", ex); - servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); - throw ex; - } - } - @Override protected Resource getResourceByPath(String path) { if (getServletContext() == null) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextFactory.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContextFactory.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextFactory.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContextFactory.java index a98826b89c50..73337e94fff9 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContextFactory.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; import org.springframework.aot.AotDetector; import org.springframework.boot.ApplicationContextFactory; import org.springframework.boot.WebApplicationType; +import org.springframework.boot.web.context.servlet.ApplicationServletEnvironment; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerInitializedEvent.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerInitializedEvent.java similarity index 92% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerInitializedEvent.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerInitializedEvent.java index b592838f646d..d757bbe08124 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerInitializedEvent.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/ServletWebServerInitializedEvent.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; -import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerInitializedEvent; /** * Event to be published after the {@link WebServer} is ready. Useful for obtaining the diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/WebApplicationContextServletContextAwareProcessor.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebApplicationContextServletContextAwareProcessor.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/WebApplicationContextServletContextAwareProcessor.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebApplicationContextServletContextAwareProcessor.java index 3bf7a5df4e5a..ec4d3ac2070e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/WebApplicationContextServletContextAwareProcessor.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebApplicationContextServletContextAwareProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebFilterHandler.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebFilterHandler.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebFilterHandler.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebFilterHandler.java index 123fa86ecf5a..2f54314693c5 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebFilterHandler.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebFilterHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.util.Arrays; import java.util.EnumSet; @@ -27,6 +27,7 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.util.StringUtils; /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerHandler.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebListenerHandler.java similarity index 90% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerHandler.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebListenerHandler.java index b67d9413b464..736a19c4f408 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebListenerHandler.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebListenerHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.util.Map; @@ -23,6 +23,8 @@ import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.boot.web.server.servlet.WebListenerRegistrar; +import org.springframework.boot.web.server.servlet.WebListenerRegistry; /** * Handler for {@link WebListener @WebListener}-annotated classes. diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebServerStartStopLifecycle.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebServerStartStopLifecycle.java new file mode 100644 index 000000000000..131e7e822de7 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebServerStartStopLifecycle.java @@ -0,0 +1,66 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.servlet.context; + +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.context.SmartLifecycle; + +/** + * {@link SmartLifecycle} to start and stop the {@link WebServer} in a + * {@link ServletWebServerApplicationContext}. + * + * @author Andy Wilkinson + */ +class WebServerStartStopLifecycle implements SmartLifecycle { + + private final ServletWebServerApplicationContext applicationContext; + + private final WebServer webServer; + + private volatile boolean running; + + WebServerStartStopLifecycle(ServletWebServerApplicationContext applicationContext, WebServer webServer) { + this.applicationContext = applicationContext; + this.webServer = webServer; + } + + @Override + public void start() { + this.webServer.start(); + this.running = true; + this.applicationContext + .publishEvent(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext)); + } + + @Override + public void stop() { + this.running = false; + this.webServer.stop(); + } + + @Override + public boolean isRunning() { + return this.running; + } + + @Override + public int getPhase() { + return WebServerApplicationContext.START_STOP_LIFECYCLE_PHASE; + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebServletHandler.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebServletHandler.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebServletHandler.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebServletHandler.java index fccf67149dab..5d75368fc811 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/WebServletHandler.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/WebServletHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.util.Map; @@ -26,6 +26,7 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.util.StringUtils; /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/XmlServletWebServerApplicationContext.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/XmlServletWebServerApplicationContext.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/XmlServletWebServerApplicationContext.java rename to spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/XmlServletWebServerApplicationContext.java index cca975039adb..1d29dae57912 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/XmlServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/XmlServletWebServerApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.env.ConfigurableEnvironment; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/package-info.java new file mode 100644 index 000000000000..e8602ac718c3 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/context/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Servlet web server based web integrations with Spring's + * {@link org.springframework.web.context.WebApplicationContext WebApplicationContext}. + */ +package org.springframework.boot.web.server.servlet.context; diff --git a/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/package-info.java b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/package-info.java new file mode 100644 index 000000000000..a794e4b1fbfd --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Servlet web server abstractions. + */ +package org.springframework.boot.web.server.servlet; diff --git a/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..f04fdaac14b5 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,217 @@ +{ + "properties": [ + { + "name": "server.connection-timeout", + "type": "java.time.Duration", + "deprecation": { + "reason": "Each server behaves differently. Use server specific properties instead.", + "level": "error" + } + }, + { + "name": "server.error.include-binding-errors", + "description": "When to include \"errors\" attribute.", + "defaultValue": "never" + }, + { + "name": "server.error.include-exception", + "description": "Include the \"exception\" attribute.", + "defaultValue": false + }, + { + "name": "server.error.include-message", + "description": "When to include the \"message\" attribute.", + "defaultValue": "never" + }, + { + "name": "server.error.include-path", + "description": "When to include the \"path\" attribute.", + "defaultValue": "always" + }, + { + "name": "server.error.include-stacktrace", + "description": "When to include the \"trace\" attribute.", + "defaultValue": "never" + }, + { + "name": "server.error.path", + "description": "Path of the error controller", + "defaultValue": "/error" + }, + { + "name": "server.error.whitelabel.enabled", + "description": "Whether to enable the default error page displayed in browsers in case of a server error.", + "defaultValue": true + }, + { + "name": "server.max-http-header-size", + "deprecation": { + "replacement": "server.max-http-request-header-size", + "level": "error" + } + }, + { + "name": "server.max-http-post-size", + "type": "java.lang.Integer", + "description": "Maximum size in bytes of the HTTP post content.", + "defaultValue": 0, + "deprecation": { + "reason": "Use dedicated property for each container.", + "level": "error" + } + }, + { + "name": "server.port", + "defaultValue": 8080 + }, + { + "name": "server.reactive.session.cookie.domain", + "description": "Domain for the cookie." + }, + { + "name": "server.reactive.session.cookie.http-only", + "description": "Whether to use \"HttpOnly\" cookies for the cookie." + }, + { + "name": "server.reactive.session.cookie.max-age", + "description": "Maximum age of the cookie. If a duration suffix is not specified, seconds will be used. A positive value indicates when the cookie expires relative to the current time. A value of 0 means the cookie should expire immediately. A negative value means no \"Max-Age\"." + }, + { + "name": "server.reactive.session.cookie.name", + "description": "Name for the cookie." + }, + { + "name": "server.reactive.session.cookie.partitioned", + "description": "Whether the generated cookie carries the Partitioned attribute." + }, + { + "name": "server.reactive.session.cookie.path", + "description": "Path of the cookie." + }, + { + "name": "server.reactive.session.cookie.same-site", + "description": "SameSite setting for the cookie." + }, + { + "name": "server.reactive.session.cookie.secure", + "description": "Whether to always mark the cookie as secure." + }, + { + "name": "server.servlet.encoding.charset", + "type": "java.nio.charset.Charset", + "description": "Charset of HTTP requests and responses. Added to the Content-Type header if not set explicitly.", + "deprecation": { + "replacement": "spring.servlet.encoding.charset", + "level": "error" + } + }, + { + "name": "server.servlet.encoding.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable http encoding support.", + "defaultValue": true, + "deprecation": { + "replacement": "spring.servlet.encoding.enabled", + "level": "error" + } + }, + { + "name": "server.servlet.encoding.force", + "type": "java.lang.Boolean", + "description": "Whether to force the encoding to the configured charset on HTTP requests and responses.", + "defaultValue": false, + "deprecation": { + "replacement": "spring.servlet.encoding.force", + "level": "error" + } + }, + { + "name": "server.servlet.encoding.force-request", + "type": "java.lang.Boolean", + "description": "Whether to force the encoding to the configured charset on HTTP requests. Defaults to true when force has not been specified.", + "defaultValue": true, + "deprecation": { + "replacement": "spring.servlet.encoding.force-request", + "level": "error" + } + }, + { + "name": "server.servlet.encoding.force-response", + "type": "java.lang.Boolean", + "description": "Whether to force the encoding to the configured charset on HTTP responses.", + "defaultValue": false, + "deprecation": { + "replacement": "spring.servlet.encoding.force-response", + "level": "error" + } + }, + { + "name": "server.servlet.jsp.class-name", + "description": "Class name of the servlet to use for JSPs. If registered is true and this class\n\t * is on the classpath then it will be registered.", + "defaultValue": "org.apache.jasper.servlet.JspServlet" + }, + { + "name": "server.servlet.jsp.init-parameters", + "description": "Init parameters used to configure the JSP servlet." + }, + { + "name": "server.servlet.path", + "type": "java.lang.String", + "description": "Path of the main dispatcher servlet.", + "defaultValue": "/", + "deprecation": { + "replacement": "spring.mvc.servlet.path", + "level": "error" + } + }, + { + "name": "server.servlet.session.cookie.comment", + "description": "Comment for the cookie.", + "deprecation": { + "level": "error" + } + }, + { + "name": "server.ssl.protocol", + "description": "SSL protocol to use.", + "defaultValue": "TLS" + }, + { + "name": "server.ssl.server-name-bundles", + "description": "Mapping of host names to SSL bundles for SNI configuration." + }, + { + "name": "server.ssl.trust-certificate", + "description": "Path to a PEM-encoded SSL certificate authority file." + }, + { + "name": "server.ssl.trust-certificate-private-key", + "description": "Path to a PEM-encoded private key file for the SSL certificate authority." + }, + { + "name": "server.ssl.trust-store", + "description": "Trust store that holds SSL certificates." + }, + { + "name": "server.ssl.trust-store-password", + "description": "Password used to access the trust store." + }, + { + "name": "server.ssl.trust-store-provider", + "description": "Provider for the trust store." + }, + { + "name": "server.ssl.trust-store-type", + "description": "Type of the trust store." + }, + { + "name": "server.use-forward-headers", + "type": "java.lang.Boolean", + "deprecation": { + "reason": "Replaced to support additional strategies.", + "replacement": "server.forward-headers-strategy", + "level": "error" + } + } + ] +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..2629b8941191 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/spring.factories @@ -0,0 +1,13 @@ +# Application Context Factories +org.springframework.boot.ApplicationContextFactory=\ +org.springframework.boot.web.server.reactive.context.ReactiveWebServerApplicationContextFactory,\ +org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContextFactory + +# Application Context Initializers +org.springframework.context.ApplicationContextInitializer=\ +org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer + +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.boot.web.server.PortInUseFailureAnalyzer,\ +org.springframework.boot.web.server.context.MissingWebServerFactoryBeanFailureAnalyzer diff --git a/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..93ff207da205 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.boot.web.server.MimeMappings$MimeMappingsRuntimeHints diff --git a/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java new file mode 100644 index 000000000000..b9d18c722bfd --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java @@ -0,0 +1,152 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.web; + +import java.net.InetAddress; +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.context.properties.source.ConfigurationPropertySource; +import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; +import org.springframework.boot.web.server.MimeMappings; +import org.springframework.boot.web.server.MimeMappings.Mapping; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.util.unit.DataSize; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ServerProperties}. + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Andy Wilkinson + * @author Phillip Webb + * @author Eddú Meléndez + * @author Quinten De Swaef + * @author Venil Noronha + * @author Andrew McGhie + * @author HaiTao Zhang + * @author Rafiullah Hamedy + * @author Chris Bono + * @author Parviz Rozikov + * @author Lasse Wulff + * @author Moritz Halbritter + */ +class ServerPropertiesTests { + + private final ServerProperties properties = new ServerProperties(); + + @Test + void testAddressBinding() throws Exception { + bind("server.address", "127.0.0.1"); + assertThat(this.properties.getAddress()).isEqualTo(InetAddress.getByName("127.0.0.1")); + } + + @Test + void testPortBinding() { + bind("server.port", "9000"); + assertThat(this.properties.getPort().intValue()).isEqualTo(9000); + } + + @Test + void testServerHeaderDefault() { + assertThat(this.properties.getServerHeader()).isNull(); + } + + @Test + void testServerHeader() { + bind("server.server-header", "Custom Server"); + assertThat(this.properties.getServerHeader()).isEqualTo("Custom Server"); + } + + @Test + void testTrailingSlashOfContextPathIsRemoved() { + bind("server.servlet.context-path", "/foo/"); + assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/foo"); + } + + @Test + void testSlashOfContextPathIsDefaultValue() { + bind("server.servlet.context-path", "/"); + assertThat(this.properties.getServlet().getContextPath()).isEmpty(); + } + + @Test + void testContextPathWithLeadingWhitespace() { + bind("server.servlet.context-path", " /assets"); + assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/assets"); + } + + @Test + void testContextPathWithTrailingWhitespace() { + bind("server.servlet.context-path", "/assets/copy/ "); + assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/assets/copy"); + } + + @Test + void testContextPathWithLeadingAndTrailingWhitespace() { + bind("server.servlet.context-path", " /assets "); + assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/assets"); + } + + @Test + void testContextPathWithLeadingAndTrailingWhitespaceAndContextWithSpace() { + bind("server.servlet.context-path", " /assets /copy/ "); + assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/assets /copy"); + } + + @Test + void testDefaultMimeMapping() { + assertThat(this.properties.getMimeMappings()).isEmpty(); + } + + @Test + void testCustomizedMimeMapping() { + MimeMappings expectedMappings = new MimeMappings(); + expectedMappings.add("mjs", "text/javascript"); + bind("server.mime-mappings.mjs", "text/javascript"); + assertThat(this.properties.getMimeMappings()) + .containsExactly(expectedMappings.getAll().toArray(new Mapping[0])); + } + + @Test + void testCustomizeMaxHttpRequestHeaderSize() { + bind("server.max-http-request-header-size", "1MB"); + assertThat(this.properties.getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofMegabytes(1)); + } + + @Test + void testCustomizeMaxHttpRequestHeaderSizeUseBytesByDefault() { + bind("server.max-http-request-header-size", "1024"); + assertThat(this.properties.getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofKilobytes(1)); + } + + private void bind(String name, String value) { + bind(Collections.singletonMap(name, value)); + } + + private void bind(Map map) { + ConfigurationPropertySource source = new MapConfigurationPropertySource(map); + new Binder(source).bind("server", Bindable.ofInstance(this.properties)); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CompressionTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/CompressionTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CompressionTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/CompressionTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/MimeMappingsTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/MimeMappingsTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/MimeMappingsTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/MimeMappingsTests.java diff --git a/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/SpringApplicationWebServerTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/SpringApplicationWebServerTests.java new file mode 100644 index 000000000000..f8008656efc0 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/SpringApplicationWebServerTests.java @@ -0,0 +1,188 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server; + +import java.util.Iterator; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.StandardReactiveWebEnvironment; +import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.PropertySource; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.test.context.support.TestPropertySourceUtils; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.StandardServletEnvironment; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplication} with a {@link WebServer}. + * + * @author Andy wilkinson + */ +class SpringApplicationWebServerTests { + + private String headlessProperty; + + private ConfigurableApplicationContext context; + + @BeforeEach + void storeAndClearHeadlessProperty() { + this.headlessProperty = System.getProperty("java.awt.headless"); + System.clearProperty("java.awt.headless"); + } + + @AfterEach + void reinstateHeadlessProperty() { + if (this.headlessProperty == null) { + System.clearProperty("java.awt.headless"); + } + else { + System.setProperty("java.awt.headless", this.headlessProperty); + } + } + + @AfterEach + void cleanUp() { + if (this.context != null) { + this.context.close(); + } + System.clearProperty("spring.main.banner-mode"); + } + + @Test + void defaultApplicationContextForWeb() { + SpringApplication application = new SpringApplication(ExampleWebConfig.class); + application.setWebApplicationType(WebApplicationType.SERVLET); + this.context = application.run(); + assertThat(this.context).isInstanceOf(AnnotationConfigServletWebServerApplicationContext.class); + } + + @Test + void defaultApplicationContextForReactiveWeb() { + SpringApplication application = new SpringApplication(ExampleReactiveWebConfig.class); + application.setWebApplicationType(WebApplicationType.REACTIVE); + this.context = application.run(); + assertThat(this.context).isInstanceOf(AnnotationConfigReactiveWebServerApplicationContext.class); + } + + @Test + void environmentForWeb() { + SpringApplication application = new SpringApplication(ExampleWebConfig.class); + application.setWebApplicationType(WebApplicationType.SERVLET); + this.context = application.run(); + assertThat(this.context.getEnvironment()).isInstanceOf(StandardServletEnvironment.class); + assertThat(this.context.getEnvironment().getClass().getName()).endsWith("ApplicationServletEnvironment"); + } + + @Test + void environmentForReactiveWeb() { + SpringApplication application = new SpringApplication(ExampleReactiveWebConfig.class); + application.setWebApplicationType(WebApplicationType.REACTIVE); + this.context = application.run(); + assertThat(this.context.getEnvironment()).isInstanceOf(StandardReactiveWebEnvironment.class); + assertThat(this.context.getEnvironment().getClass().getName()).endsWith("ApplicationReactiveWebEnvironment"); + } + + @Test + void webApplicationConfiguredViaAPropertyHasTheCorrectTypeOfContextAndEnvironment() { + ConfigurableApplicationContext context = new SpringApplication(ExampleWebConfig.class) + .run("--spring.main.web-application-type=servlet"); + assertThat(context).isInstanceOf(WebApplicationContext.class); + assertThat(context.getEnvironment()).isInstanceOf(StandardServletEnvironment.class); + assertThat(context.getEnvironment().getClass().getName()).endsWith("ApplicationServletEnvironment"); + } + + @Test + void reactiveApplicationConfiguredViaAPropertyHasTheCorrectTypeOfContextAndEnvironment() { + ConfigurableApplicationContext context = new SpringApplication(ExampleReactiveWebConfig.class) + .run("--spring.main.web-application-type=reactive"); + assertThat(context).isInstanceOf(ReactiveWebApplicationContext.class); + assertThat(context.getEnvironment()).isInstanceOf(StandardReactiveWebEnvironment.class); + assertThat(context.getEnvironment().getClass().getName()).endsWith("ApplicationReactiveWebEnvironment"); + } + + @Test + @WithResource(name = "application-withwebapplicationtype.properties", + content = "spring.main.web-application-type=reactive") + void environmentIsConvertedIfTypeDoesNotMatch() { + ConfigurableApplicationContext context = new SpringApplication(ExampleReactiveWebConfig.class) + .run("--spring.profiles.active=withwebapplicationtype"); + assertThat(context).isInstanceOf(ReactiveWebApplicationContext.class); + assertThat(context.getEnvironment()).isInstanceOf(StandardReactiveWebEnvironment.class); + assertThat(context.getEnvironment().getClass().getName()).endsWith("ApplicationReactiveWebEnvironment"); + } + + @Test + void webApplicationSwitchedOffInListener() { + SpringApplication application = new SpringApplication(ExampleWebConfig.class); + application.addListeners((ApplicationListener) (event) -> { + assertThat(event.getEnvironment().getClass().getName()).endsWith("ApplicationServletEnvironment"); + TestPropertySourceUtils.addInlinedPropertiesToEnvironment(event.getEnvironment(), "foo=bar"); + event.getSpringApplication().setWebApplicationType(WebApplicationType.NONE); + }); + this.context = application.run(); + assertThat(this.context.getEnvironment()).isNotInstanceOf(StandardServletEnvironment.class); + assertThat(this.context.getEnvironment().getProperty("foo")).isEqualTo("bar"); + Iterator> iterator = this.context.getEnvironment().getPropertySources().iterator(); + assertThat(iterator.next().getName()).isEqualTo("configurationProperties"); + assertThat(iterator.next().getName()) + .isEqualTo(TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME); + } + + @Configuration(proxyBeanMethods = false) + static class ExampleWebConfig { + + @Bean + MockServletWebServerFactory webServer() { + return new MockServletWebServerFactory(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ExampleReactiveWebConfig { + + @Bean + MockReactiveWebServerFactory webServerFactory() { + return new MockReactiveWebServerFactory(); + } + + @Bean + HttpHandler httpHandler() { + return (serverHttpRequest, serverHttpResponse) -> Mono.empty(); + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/WebServerFactoryCustomizerBeanPostProcessorTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/WebServerFactoryCustomizerBeanPostProcessorTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/WebServerFactoryCustomizerBeanPostProcessorTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/WebServerFactoryCustomizerBeanPostProcessorTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/WebServerSslBundleTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/WebServerSslBundleTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/WebServerSslBundleTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/WebServerSslBundleTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerFactoryCustomizerTests.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryCustomizerTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerFactoryCustomizerTests.java index 3dc1b768519d..519c7b47384d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/reactive/ReactiveWebServerFactoryCustomizerTests.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.web.server.autoconfigure.reactive; import java.net.InetAddress; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.ssl.DefaultSslBundleRegistry; import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory; import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.assertArg; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerFactoryCustomizerTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryCustomizerTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerFactoryCustomizerTests.java index 0bd0241b32f0..3e00d736aed3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/servlet/ServletWebServerFactoryCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.web.server.autoconfigure.servlet; import java.io.File; import java.nio.charset.StandardCharsets; @@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySource; @@ -35,8 +34,9 @@ import org.springframework.boot.web.server.MimeMappings; import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.Ssl; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; -import org.springframework.boot.web.servlet.server.Jsp; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.Jsp; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -168,14 +168,6 @@ void customizeServletDisplayName() { then(factory).should().setDisplayName("MyBootApp"); } - @Test - void testCustomizeTomcatMinSpareThreads() { - Map map = new HashMap<>(); - map.put("server.tomcat.threads.min-spare", "10"); - bindProperties(map); - assertThat(this.properties.getTomcat().getThreads().getMinSpare()).isEqualTo(10); - } - @Test void sessionStoreDir() { Map map = new HashMap<>(); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java similarity index 87% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java index 507a4a3762f7..2cd7dc4c419f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import org.junit.jupiter.api.Test; import org.springframework.boot.diagnostics.FailureAnalysis; -import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.context.ReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; import org.springframework.context.ApplicationContextException; import org.springframework.context.ConfigurableApplicationContext; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/WebServerApplicationContextTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/WebServerApplicationContextTests.java similarity index 97% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/WebServerApplicationContextTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/WebServerApplicationContextTests.java index fe0e71b1cc67..3de35510ddab 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/WebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/WebServerApplicationContextTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/WebServerPortFileWriterTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/WebServerPortFileWriterTests.java similarity index 99% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/WebServerPortFileWriterTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/WebServerPortFileWriterTests.java index af6b5800d5ac..e573d3df2577 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/WebServerPortFileWriterTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/context/WebServerPortFileWriterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.context; +package org.springframework.boot.web.server.context; import java.io.File; import java.util.HashSet; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java similarity index 92% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java index d6f38ec30132..5ac37a55f093 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; import org.junit.jupiter.api.Test; -import org.springframework.boot.web.reactive.context.WebServerManager.DelayedInitializationHttpHandler; -import org.springframework.boot.web.reactive.context.config.ExampleReactiveWebServerApplicationConfiguration; -import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.context.WebServerManager.DelayedInitializationHttpHandler; +import org.springframework.boot.web.server.reactive.context.config.ExampleReactiveWebServerApplicationConfiguration; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ApplicationReactiveWebEnvironmentTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/ApplicationReactiveWebEnvironmentTests.java similarity index 94% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ApplicationReactiveWebEnvironmentTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/ApplicationReactiveWebEnvironmentTests.java index a8fd9a9b5720..47f78b16e87a 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ApplicationReactiveWebEnvironmentTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/ApplicationReactiveWebEnvironmentTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; import org.springframework.boot.AbstractApplicationEnvironmentTests; import org.springframework.core.env.StandardEnvironment; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContextTests.java similarity index 97% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContextTests.java index e6297f0608a6..309537d8c249 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/ReactiveWebServerApplicationContextTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.server.reactive.context; import java.util.ArrayDeque; import java.util.ArrayList; @@ -28,9 +28,9 @@ import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.availability.AvailabilityChangeEvent; import org.springframework.boot.availability.ReadinessState; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; -import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; +import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory; import org.springframework.context.ApplicationContextException; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/config/ExampleReactiveWebServerApplicationConfiguration.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/config/ExampleReactiveWebServerApplicationConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/config/ExampleReactiveWebServerApplicationConfiguration.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/config/ExampleReactiveWebServerApplicationConfiguration.java index 07ce87ca6b0e..3ca37160269f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/config/ExampleReactiveWebServerApplicationConfiguration.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/reactive/context/config/ExampleReactiveWebServerApplicationConfiguration.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context.config; +package org.springframework.boot.web.server.reactive.context.config; -import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.server.reactive.HttpHandler; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/CookieSameSiteSupplierTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/CookieSameSiteSupplierTests.java similarity index 99% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/CookieSameSiteSupplierTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/CookieSameSiteSupplierTests.java index 0ced6e07c014..a31237b0f323 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/CookieSameSiteSupplierTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/CookieSameSiteSupplierTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.util.function.Supplier; import java.util.regex.Pattern; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/DocumentRootTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/DocumentRootTests.java similarity index 97% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/DocumentRootTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/DocumentRootTests.java index 06031577a3af..d9f364fe72b8 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/DocumentRootTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/DocumentRootTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.io.File; import java.net.URL; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/StaticResourceJarsTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/StaticResourceJarsTests.java similarity index 99% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/StaticResourceJarsTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/StaticResourceJarsTests.java index 8f06eb3ac031..daef3ac2f56a 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/StaticResourceJarsTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/StaticResourceJarsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.io.File; import java.io.FileOutputStream; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java similarity index 95% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java index f7ae203c76b7..abc84d1a1c2a 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; import jakarta.servlet.GenericServlet; import jakarta.servlet.Servlet; @@ -25,10 +25,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.servlet.context.config.ExampleServletWebServerApplicationConfiguration; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.config.ExampleServletWebServerApplicationConfiguration; import org.springframework.boot.web.servlet.mock.MockServlet; -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ApplicationServletEnvironmentTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ApplicationServletEnvironmentTests.java similarity index 87% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ApplicationServletEnvironmentTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ApplicationServletEnvironmentTests.java index 958f8cebc597..14cb8f91557c 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ApplicationServletEnvironmentTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ApplicationServletEnvironmentTests.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; import org.springframework.boot.AbstractApplicationEnvironmentTests; +import org.springframework.boot.web.context.servlet.ApplicationServletEnvironment; import org.springframework.core.env.StandardEnvironment; /** diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/MockWebEnvironmentServletComponentScanIntegrationTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/MockWebEnvironmentServletComponentScanIntegrationTests.java similarity index 85% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/MockWebEnvironmentServletComponentScanIntegrationTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/MockWebEnvironmentServletComponentScanIntegrationTests.java index 22991a0b5798..5f836e7b4bcf 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/MockWebEnvironmentServletComponentScanIntegrationTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/MockWebEnvironmentServletComponentScanIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.io.File; import java.io.FileWriter; @@ -33,11 +33,15 @@ import org.junit.jupiter.api.io.TempDir; import org.springframework.boot.testsupport.classpath.ForkedClassPath; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.boot.web.servlet.testcomponents.filter.TestFilter; -import org.springframework.boot.web.servlet.testcomponents.listener.TestListener; -import org.springframework.boot.web.servlet.testcomponents.servlet.TestMultipartServlet; -import org.springframework.boot.web.servlet.testcomponents.servlet.TestServlet; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.server.servlet.WebListenerRegistrar; +import org.springframework.boot.web.server.servlet.WebListenerRegistry; +import org.springframework.boot.web.server.servlet.context.testcomponents.filter.TestFilter; +import org.springframework.boot.web.server.servlet.context.testcomponents.listener.TestListener; +import org.springframework.boot.web.server.servlet.context.testcomponents.servlet.TestMultipartServlet; +import org.springframework.boot.web.server.servlet.context.testcomponents.servlet.TestServlet; +import org.springframework.boot.web.servlet.RegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.mock.web.MockServletContext; import static org.assertj.core.api.Assertions.assertThat; @@ -132,7 +136,7 @@ private void prepareContext() { this.context.setServletContext(new MockServletContext()); } - @ServletComponentScan(basePackages = "org.springframework.boot.web.servlet.testcomponents") + @ServletComponentScan(basePackages = "org.springframework.boot.web.server.servlet.context.testcomponents") static class ScanningConfiguration { } diff --git a/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanIntegrationTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanIntegrationTests.java new file mode 100644 index 000000000000..634b3835f478 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanIntegrationTests.java @@ -0,0 +1,140 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.servlet.context; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Map; +import java.util.Properties; + +import jakarta.servlet.MultipartConfigElement; +import jakarta.servlet.annotation.WebFilter; +import jakarta.servlet.annotation.WebListener; +import jakarta.servlet.annotation.WebServlet; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.WebListenerRegistrar; +import org.springframework.boot.web.server.servlet.context.testcomponents.filter.TestFilter; +import org.springframework.boot.web.server.servlet.context.testcomponents.listener.TestListener; +import org.springframework.boot.web.server.servlet.context.testcomponents.servlet.TestMultipartServlet; +import org.springframework.boot.web.server.servlet.context.testcomponents.servlet.TestServlet; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link ServletComponentScan @ServletComponentScan} + * + * @author Andy Wilkinson + */ +class ServletComponentScanIntegrationTests { + + private AnnotationConfigServletWebServerApplicationContext context; + + @TempDir + File temp; + + @AfterEach + void cleanUp() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + void componentsAreRegistered() { + this.context = new AnnotationConfigServletWebServerApplicationContext(); + this.context.register(TestConfiguration.class); + this.context.refresh(); + assertThat(this.context.getServletContext().getFilterRegistrations()).hasSize(1) + .containsKey(TestFilter.class.getName()); + assertThat(this.context.getServletContext().getServletRegistrations()).hasSize(2) + .containsKeys(TestServlet.class.getName(), TestMultipartServlet.class.getName()); + assertThat(this.context.getBean(MockServletWebServerFactory.class).getSettings().getWebListenerClassNames()) + .containsExactly(TestListener.class.getName()); + } + + @Test + void indexedComponentsAreRegistered() throws IOException { + writeIndex(this.temp); + this.context = new AnnotationConfigServletWebServerApplicationContext(); + try (URLClassLoader classLoader = new URLClassLoader(new URL[] { this.temp.toURI().toURL() }, + getClass().getClassLoader())) { + this.context.setClassLoader(classLoader); + this.context.register(TestConfiguration.class); + this.context.refresh(); + assertThat(this.context.getServletContext().getFilterRegistrations()).hasSize(1) + .containsKey(TestFilter.class.getName()); + assertThat(this.context.getServletContext().getServletRegistrations()).hasSize(1) + .containsKeys(TestServlet.class.getName()); + assertThat(this.context.getBean(MockServletWebServerFactory.class).getSettings().getWebListenerClassNames()) + .containsExactly(TestListener.class.getName()); + } + } + + @Test + void multipartConfigIsHonoured() { + this.context = new AnnotationConfigServletWebServerApplicationContext(); + this.context.register(TestConfiguration.class); + this.context.refresh(); + @SuppressWarnings("rawtypes") + Map beans = this.context.getBeansOfType(ServletRegistrationBean.class); + ServletRegistrationBean servletRegistrationBean = beans.get(TestMultipartServlet.class.getName()); + assertThat(servletRegistrationBean).isNotNull(); + MultipartConfigElement multipartConfig = servletRegistrationBean.getMultipartConfig(); + assertThat(multipartConfig).isNotNull(); + assertThat(multipartConfig.getLocation()).isEqualTo("test"); + assertThat(multipartConfig.getMaxRequestSize()).isEqualTo(2048); + assertThat(multipartConfig.getMaxFileSize()).isEqualTo(1024); + assertThat(multipartConfig.getFileSizeThreshold()).isEqualTo(512); + } + + private void writeIndex(File temp) throws IOException { + File metaInf = new File(temp, "META-INF"); + metaInf.mkdirs(); + Properties index = new Properties(); + index.setProperty(TestFilter.class.getName(), WebFilter.class.getName()); + index.setProperty(TestListener.class.getName(), WebListener.class.getName()); + index.setProperty(TestServlet.class.getName(), WebServlet.class.getName()); + try (FileWriter writer = new FileWriter(new File(metaInf, "spring.components"))) { + index.store(writer, null); + } + } + + @ServletComponentScan(basePackages = "org.springframework.boot.web.server.servlet.context.testcomponents") + static class TestConfiguration { + + @Bean + protected ServletWebServerFactory webServerFactory(ObjectProvider webListenerRegistrars) { + ConfigurableServletWebServerFactory factory = new MockServletWebServerFactory(); + webListenerRegistrars.orderedStream().forEach((registrar) -> registrar.register(factory)); + return factory; + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanRegistrarTests.java similarity index 92% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanRegistrarTests.java index 1f14fbf0f817..26081a772dc6 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletComponentScanRegistrarTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.util.function.Consumer; @@ -25,8 +25,7 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.aot.test.generate.TestGenerationContext; import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.testcomponents.listener.TestListener; +import org.springframework.boot.web.server.servlet.context.testcomponents.listener.TestListener; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; @@ -114,7 +113,8 @@ void withNoBasePackagesScanningUsesBasePackageOfAnnotatedClass() { this.context = new AnnotationConfigApplicationContext(NoBasePackages.class); ServletComponentRegisteringPostProcessor postProcessor = this.context .getBean(ServletComponentRegisteringPostProcessor.class); - assertThat(postProcessor.getPackagesToScan()).containsExactly("org.springframework.boot.web.servlet"); + assertThat(postProcessor.getPackagesToScan()) + .containsExactly("org.springframework.boot.web.server.servlet.context"); } @Test @@ -122,8 +122,8 @@ void noBasePackageAndBasePackageAreCombinedCorrectly() { this.context = new AnnotationConfigApplicationContext(NoBasePackages.class, BasePackages.class); ServletComponentRegisteringPostProcessor postProcessor = this.context .getBean(ServletComponentRegisteringPostProcessor.class); - assertThat(postProcessor.getPackagesToScan()).containsExactlyInAnyOrder("org.springframework.boot.web.servlet", - "com.example.foo", "com.example.bar"); + assertThat(postProcessor.getPackagesToScan()).containsExactlyInAnyOrder( + "org.springframework.boot.web.server.servlet.context", "com.example.foo", "com.example.bar"); } @Test @@ -131,8 +131,8 @@ void basePackageAndNoBasePackageAreCombinedCorrectly() { this.context = new AnnotationConfigApplicationContext(BasePackages.class, NoBasePackages.class); ServletComponentRegisteringPostProcessor postProcessor = this.context .getBean(ServletComponentRegisteringPostProcessor.class); - assertThat(postProcessor.getPackagesToScan()).containsExactlyInAnyOrder("org.springframework.boot.web.servlet", - "com.example.foo", "com.example.bar"); + assertThat(postProcessor.getPackagesToScan()).containsExactlyInAnyOrder( + "org.springframework.boot.web.server.servlet.context", "com.example.foo", "com.example.bar"); } @Test @@ -221,13 +221,13 @@ static class NoBasePackages { } @Configuration(proxyBeanMethods = false) - @ServletComponentScan("org.springframework.boot.web.servlet.testcomponents.listener") + @ServletComponentScan("org.springframework.boot.web.server.servlet.context.testcomponents.listener") static class ScanListenerPackage { } @Configuration(proxyBeanMethods = false) - @ServletComponentScan("org.springframework.boot.web.servlet.testcomponents.servlet") + @ServletComponentScan("org.springframework.boot.web.server.servlet.context.testcomponents.servlet") static class ScanServletPackage { } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContextTests.java similarity index 99% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContextTests.java index 09499f032b89..b7861877423c 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/ServletWebServerApplicationContextTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; import java.util.ArrayDeque; import java.util.ArrayList; @@ -50,13 +50,13 @@ import org.springframework.boot.availability.AvailabilityChangeEvent; import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; import org.springframework.context.ApplicationContextException; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebFilterHandlerTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebFilterHandlerTests.java similarity index 99% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebFilterHandlerTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebFilterHandlerTests.java index 2cff90732bba..a5e2a64dd070 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebFilterHandlerTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebFilterHandlerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.io.IOException; import java.util.EnumSet; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebListenerHandlerTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebListenerHandlerTests.java similarity index 97% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebListenerHandlerTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebListenerHandlerTests.java index 90edd71cc461..6b8ec0c91db2 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebListenerHandlerTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebListenerHandlerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.io.IOException; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebServletHandlerTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebServletHandlerTests.java similarity index 99% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebServletHandlerTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebServletHandlerTests.java index b88935c38f04..f02b7c446c84 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/WebServletHandlerTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/WebServletHandlerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet; +package org.springframework.boot.web.server.servlet.context; import java.io.IOException; import java.util.Map; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/XmlServletWebServerApplicationContextTests.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/XmlServletWebServerApplicationContextTests.java similarity index 95% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/XmlServletWebServerApplicationContextTests.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/XmlServletWebServerApplicationContextTests.java index 916550a95fa4..3c0d4af8c889 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/XmlServletWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/XmlServletWebServerApplicationContextTests.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.server.servlet.context; import jakarta.servlet.Servlet; import org.junit.jupiter.api.Test; -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; import org.springframework.core.io.ClassPathResource; import static org.mockito.BDDMockito.then; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/config/ExampleServletWebServerApplicationConfiguration.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/config/ExampleServletWebServerApplicationConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/config/ExampleServletWebServerApplicationConfiguration.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/config/ExampleServletWebServerApplicationConfiguration.java index 67cc49530d22..d9037fdd2d95 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/config/ExampleServletWebServerApplicationConfiguration.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/config/ExampleServletWebServerApplicationConfiguration.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context.config; +package org.springframework.boot.web.server.servlet.context.config; import jakarta.servlet.Servlet; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; import org.springframework.boot.web.servlet.mock.MockServlet; -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/filter/TestFilter.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/filter/TestFilter.java similarity index 94% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/filter/TestFilter.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/filter/TestFilter.java index 2e38d961ab42..eefcbfabbe2b 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/filter/TestFilter.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/filter/TestFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.testcomponents.filter; +package org.springframework.boot.web.server.servlet.context.testcomponents.filter; import java.io.IOException; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/listener/TestListener.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/listener/TestListener.java similarity index 95% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/listener/TestListener.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/listener/TestListener.java index 948a5b70a225..574d285f5f70 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/listener/TestListener.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/listener/TestListener.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.testcomponents.listener; +package org.springframework.boot.web.server.servlet.context.testcomponents.listener; import java.io.IOException; import java.util.EnumSet; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/servlet/TestMultipartServlet.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/servlet/TestMultipartServlet.java similarity index 91% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/servlet/TestMultipartServlet.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/servlet/TestMultipartServlet.java index 054631093867..7d4a5370b432 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/servlet/TestMultipartServlet.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/servlet/TestMultipartServlet.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.testcomponents.servlet; +package org.springframework.boot.web.server.servlet.context.testcomponents.servlet; import jakarta.servlet.annotation.MultipartConfig; import jakarta.servlet.annotation.WebServlet; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/servlet/TestServlet.java b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/servlet/TestServlet.java similarity index 93% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/servlet/TestServlet.java rename to spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/servlet/TestServlet.java index dd59533c72d5..1dbe770b0a60 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/testcomponents/servlet/TestServlet.java +++ b/spring-boot-project/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/servlet/context/testcomponents/servlet/TestServlet.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.testcomponents.servlet; +package org.springframework.boot.web.server.servlet.context.testcomponents.servlet; import java.io.IOException; diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs1/dsa.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs1/dsa.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs1/dsa.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs1/dsa.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs1/rsa-aes-256-cbc.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs1/rsa-aes-256-cbc.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs1/rsa-aes-256-cbc.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs1/rsa-aes-256-cbc.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs1/rsa.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs1/rsa.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs1/rsa.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs1/rsa.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP256r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP256r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP256r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP256r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP256t1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP256t1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP256t1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP256t1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP320r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP320r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP320r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP320r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP320t1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP320t1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP320t1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP320t1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP384r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP384r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP384r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP384r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP384t1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP384t1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP384t1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP384t1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP512r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP512r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP512r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP512r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP512t1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP512t1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP512t1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/brainpoolP512t1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/dsa-aes-128-cbc.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/dsa-aes-128-cbc.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/dsa-aes-128-cbc.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/dsa-aes-128-cbc.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/dsa.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/dsa.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/dsa.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/dsa.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/ed25519-aes-256-cbc.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/ed25519-aes-256-cbc.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/ed25519-aes-256-cbc.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/ed25519-aes-256-cbc.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/ed25519.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/ed25519.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/ed25519.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/ed25519.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/ed448.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/ed448.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/ed448.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/ed448.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/prime256v1-aes-256-cbc.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/prime256v1-aes-256-cbc.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/prime256v1-aes-256-cbc.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/prime256v1-aes-256-cbc.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/prime256v1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/prime256v1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/prime256v1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/prime256v1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-aes-256-cbc.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-aes-256-cbc.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-aes-256-cbc.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-aes-256-cbc.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-des-ede3-cbc.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-des-ede3-cbc.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-des-ede3-cbc.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-des-ede3-cbc.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-pss.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-pss.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-pss.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-pss.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-scrypt.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-scrypt.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-scrypt.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa-scrypt.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/rsa.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp224r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp224r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp224r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp224r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp256k1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp256k1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp256k1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp256k1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp256r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp256r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp256r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp256r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp384r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp384r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp384r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp384r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp521r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp521r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/secp521r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/secp521r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/x25519.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/x25519.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/x25519.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/x25519.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/x448-aes-256-cbc.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/x448-aes-256-cbc.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/x448-aes-256-cbc.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/x448-aes-256-cbc.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/x448.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/x448.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/pkcs8/x448.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/pkcs8/x448.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP256r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP256r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP256r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP256r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP256t1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP256t1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP256t1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP256t1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP320r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP320r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP320r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP320r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP320t1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP320t1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP320t1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP320t1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP384r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP384r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP384r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP384r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP384t1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP384t1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP384t1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP384t1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP512r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP512r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP512r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP512r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP512t1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP512t1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP512t1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/brainpoolP512t1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/prime256v1-aes-128-cbc.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/prime256v1-aes-128-cbc.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/prime256v1-aes-128-cbc.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/prime256v1-aes-128-cbc.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/prime256v1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/prime256v1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/prime256v1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/prime256v1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp224r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp224r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp224r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp224r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp256k1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp256k1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp256k1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp256k1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp256r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp256r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp256r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp256r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp384r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp384r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp384r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp384r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp521r1.key b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp521r1.key similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/sec1/secp521r1.key rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/sec1/secp521r1.key diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/context/exampleEmbeddedWebApplicationConfiguration.xml b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/servlet/context/exampleEmbeddedWebApplicationConfiguration.xml similarity index 87% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/context/exampleEmbeddedWebApplicationConfiguration.xml rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/servlet/context/exampleEmbeddedWebApplicationConfiguration.xml index e220798078e4..76d72bef23a5 100644 --- a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/context/exampleEmbeddedWebApplicationConfiguration.xml +++ b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/servlet/context/exampleEmbeddedWebApplicationConfiguration.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> + class="org.springframework.boot.web.server.servlet.MockServletWebServerFactory" /> diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test-cert-chain.pem b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test-cert-chain.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test-cert-chain.pem rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test-cert-chain.pem diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/reactive/server/test-cert.pem b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test-cert.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/reactive/server/test-cert.pem rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test-cert.pem diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/reactive/server/test-key.pem b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test-key.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/reactive/server/test-key.pem rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test-key.pem diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/server/test.jks b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test.jks similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/server/test.jks rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test.jks diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test.p12 b/spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test.p12 similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test.p12 rename to spring-boot-project/spring-boot-web-server/src/test/resources/org/springframework/boot/web/server/test.p12 diff --git a/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/autoconfigure/reactive/AbstractReactiveWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/autoconfigure/reactive/AbstractReactiveWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..57f7e316ce79 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/autoconfigure/reactive/AbstractReactiveWebServerAutoConfigurationTests.java @@ -0,0 +1,187 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.autoconfigure.reactive; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.ssl.DefaultSslBundleRegistry; +import org.springframework.boot.ssl.NoSuchSslBundleException; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.web.server.ConfigurableWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.context.ApplicationContextException; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.web.server.adapter.ForwardedHeaderTransformer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Base class for testing sub-classes of {@link ReactiveWebServerConfiguration}. + * + * @author Brian Clozel + * @author Raheela Aslam + * @author Madhura Bhave + * @author Scott Frederick + */ +// @DirtiesUrlFactories +public abstract class AbstractReactiveWebServerAutoConfigurationTests { + + private final ReactiveWebApplicationContextRunner mockServerRunner; + + protected final ReactiveWebApplicationContextRunner serverRunner; + + protected AbstractReactiveWebServerAutoConfigurationTests(Class serverAutoConfiguration) { + ReactiveWebApplicationContextRunner common = new ReactiveWebApplicationContextRunner( + AnnotationConfigReactiveWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(serverAutoConfiguration)); + this.serverRunner = common.withPropertyValues("server.port=0") + .withUserConfiguration(HttpHandlerConfiguration.class); + this.mockServerRunner = common.withUserConfiguration(MockWebServerConfiguration.class); + } + + @Test + void createFromConfigClass() { + this.mockServerRunner.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class) + .run((context) -> { + assertThat(context.getBeansOfType(ReactiveWebServerFactory.class)).hasSize(1); + assertThat(context.getBeansOfType(WebServerFactoryCustomizer.class)).hasSizeGreaterThanOrEqualTo(1); + assertThat(context.getBeansOfType(ReactiveWebServerFactoryCustomizer.class)).hasSize(1); + }); + } + + @Test + void missingHttpHandler() { + this.mockServerRunner.withUserConfiguration(MockWebServerConfiguration.class) + .run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(ApplicationContextException.class) + .rootCause() + .hasMessageContaining("missing HttpHandler bean")); + } + + @Test + void multipleHttpHandler() { + this.mockServerRunner + .withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class, + TooManyHttpHandlers.class) + .run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(ApplicationContextException.class) + .rootCause() + .hasMessageContaining("multiple HttpHandler beans : httpHandler,additionalHttpHandler")); + } + + @Test + void customizeReactiveWebServer() { + this.mockServerRunner + .withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class, + ReactiveWebServerCustomization.class) + .run((context) -> assertThat(context.getBean(MockReactiveWebServerFactory.class).getPort()) + .isEqualTo(9000)); + } + + @Test + void webServerFailsWithInvalidSslBundle() { + this.serverRunner.withUserConfiguration(HttpHandlerConfiguration.class) + .withBean(WebServerFactoryCustomizer.class, + () -> (WebServerFactoryCustomizer) (factory) -> factory + .setSslBundles(new DefaultSslBundleRegistry())) + .withPropertyValues("server.ssl.bundle=test-bundle") + .run((context) -> { + assertThat(context).hasFailed(); + assertThat(context.getStartupFailure().getCause()).isInstanceOf(NoSuchSslBundleException.class) + .withFailMessage("test"); + }); + } + + @Test + void forwardedHeaderTransformerShouldBeConfigured() { + this.mockServerRunner.withUserConfiguration(HttpHandlerConfiguration.class) + .withPropertyValues("server.forward-headers-strategy=framework", "server.port=0") + .run((context) -> assertThat(context).hasSingleBean(ForwardedHeaderTransformer.class)); + } + + @Test + void forwardedHeaderTransformerWhenStrategyNotFilterShouldNotBeConfigured() { + this.mockServerRunner.withUserConfiguration(HttpHandlerConfiguration.class) + .withPropertyValues("server.forward-headers-strategy=native", "server.port=0") + .run((context) -> assertThat(context).doesNotHaveBean(ForwardedHeaderTransformer.class)); + } + + @Test + void forwardedHeaderTransformerWhenAlreadyRegisteredShouldBackOff() { + this.mockServerRunner + .withUserConfiguration(ForwardedHeaderTransformerConfiguration.class, HttpHandlerConfiguration.class) + .withPropertyValues("server.forward-headers-strategy=framework", "server.port=0") + .run((context) -> assertThat(context).hasSingleBean(ForwardedHeaderTransformer.class)); + } + + @Configuration(proxyBeanMethods = false) + static class HttpHandlerConfiguration { + + @Bean + HttpHandler httpHandler() { + return mock(HttpHandler.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TooManyHttpHandlers { + + @Bean + HttpHandler additionalHttpHandler() { + return mock(HttpHandler.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ReactiveWebServerCustomization { + + @Bean + WebServerFactoryCustomizer reactiveWebServerCustomizer() { + return (factory) -> factory.setPort(9000); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MockWebServerConfiguration { + + @Bean + MockReactiveWebServerFactory mockReactiveWebServerFactory() { + return new MockReactiveWebServerFactory(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ForwardedHeaderTransformerConfiguration { + + @Bean + ForwardedHeaderTransformer testForwardedHeaderTransformer() { + return new ForwardedHeaderTransformer(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/autoconfigure/servlet/AbstractServletWebServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/autoconfigure/servlet/AbstractServletWebServerAutoConfigurationTests.java new file mode 100644 index 000000000000..0ca5f657f23c --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/autoconfigure/servlet/AbstractServletWebServerAutoConfigurationTests.java @@ -0,0 +1,285 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.autoconfigure.servlet; + +import java.io.IOException; + +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.websocket.server.ServerContainer; +import jakarta.websocket.server.ServerEndpoint; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletContextInitializer; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.filter.ForwardedHeaderFilter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * Base class for testing sub-classes of {@link ServletWebServerConfiguration}. + * + * @author Dave Syer + * @author Phillip Webb + * @author Stephane Nicoll + * @author Raheela Aslam + * @author Madhura Bhave + */ +public abstract class AbstractServletWebServerAutoConfigurationTests { + + private final WebApplicationContextRunner mockServerRunner; + + protected final WebApplicationContextRunner serverRunner; + + protected AbstractServletWebServerAutoConfigurationTests(Class serverAutoConfiguration) { + WebApplicationContextRunner common = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(serverAutoConfiguration)); + this.serverRunner = common.withPropertyValues("server.port=0"); + this.mockServerRunner = common.withUserConfiguration(MockWebServerConfiguration.class); + } + + @Test + void createFromConfigClass() { + this.mockServerRunner + .run((context) -> assertThat(context).hasSingleBean(ServletWebServerFactoryCustomizer.class)); + } + + @Test + void webServerHasNoServletContext() { + this.mockServerRunner.withUserConfiguration(EnsureWebServerHasNoServletContext.class) + .run((context) -> assertThat(context).hasNotFailed()); + } + + @Test + void webServerFactoryCustomizerBeansAreCalledToCustomizeWebServerFactory() { + this.mockServerRunner + .withBean(WebServerFactoryCustomizer.class, + () -> (WebServerFactoryCustomizer) (factory) -> factory + .setPort(9000)) + .run((context) -> assertThat(context.getBean(MockServletWebServerFactory.class).getPort()).isEqualTo(9000)); + } + + @Test + void initParametersAreConfiguredOnTheServletContext() { + this.mockServerRunner + .withPropertyValues("server.servlet.context-parameters.a:alpha", + "server.servlet.context-parameters.b:bravo") + .run((context) -> { + ServletContext servletContext = context.getServletContext(); + assertThat(servletContext.getInitParameter("a")).isEqualTo("alpha"); + assertThat(servletContext.getInitParameter("b")).isEqualTo("bravo"); + }); + } + + @Test + void forwardedHeaderFilterShouldBeConfigured() { + this.mockServerRunner.withPropertyValues("server.forward-headers-strategy=framework").run((context) -> { + assertThat(context).hasSingleBean(FilterRegistrationBean.class); + Filter filter = context.getBean(FilterRegistrationBean.class).getFilter(); + assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class); + assertThat(filter).extracting("relativeRedirects").isEqualTo(false); + }); + } + + @Test + void forwardedHeaderFilterWhenStrategyNotFilterShouldNotBeConfigured() { + this.mockServerRunner.withPropertyValues("server.forward-headers-strategy=native") + .run((context) -> assertThat(context).doesNotHaveBean(FilterRegistrationBean.class)); + } + + @Test + void forwardedHeaderFilterWhenFilterAlreadyRegisteredShouldBackOff() { + this.mockServerRunner.withUserConfiguration(ForwardedHeaderFilterConfiguration.class) + .withPropertyValues("server.forward-headers-strategy=framework") + .run((context) -> assertThat(context).hasSingleBean(FilterRegistrationBean.class)); + } + + @Test + void cookieSameSiteSuppliersAreApplied() { + this.mockServerRunner.withUserConfiguration(CookieSameSiteSupplierConfiguration.class).run((context) -> { + ConfigurableServletWebServerFactory webServerFactory = context + .getBean(ConfigurableServletWebServerFactory.class); + assertThat(webServerFactory.getSettings().getCookieSameSiteSuppliers()).hasSize(2); + }); + } + + @Test + void webSocketServerContainerIsAvailableFromServletContext() { + this.serverRunner.run((context) -> { + Object serverContainer = context.getServletContext() + .getAttribute("jakarta.websocket.server.ServerContainer"); + assertThat(serverContainer).isInstanceOf(ServerContainer.class); + }); + } + + @Test + void webSocketUpgradeDoesNotPreventAFilterFromRejectingTheRequest() { + this.serverRunner + .withBean("testEndpointRegistrar", ServletContextInitializer.class, () -> TestEndpoint::register) + .withUserConfiguration(UnauthorizedFilterConfiguration.class) + .run((context) -> { + TestEndpoint.register(context.getServletContext()); + WebServer webServer = ((WebServerApplicationContext) context.getSourceApplicationContext()) + .getWebServer(); + int port = webServer.getPort(); + RestTemplate rest = new RestTemplate(); + RequestEntity request = RequestEntity.get("http://localhost:" + port) + .header("Upgrade", "websocket") + .header("Connection", "upgrade") + .header("Sec-WebSocket-Version", "13") + .header("Sec-WebSocket-Key", "key") + .build(); + assertThatExceptionOfType(HttpClientErrorException.Unauthorized.class) + .isThrownBy(() -> rest.exchange(request, Void.class)); + }); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnExpression("true") + static class MockWebServerConfiguration { + + @Bean + ServletWebServerFactory webServerFactory() { + return new MockServletWebServerFactory(); + } + + } + + @Component + static class EnsureWebServerHasNoServletContext implements BeanPostProcessor { + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) { + if (bean instanceof ConfigurableServletWebServerFactory) { + MockServletWebServerFactory webServerFactory = (MockServletWebServerFactory) bean; + assertThat(webServerFactory.getServletContext()).isNull(); + } + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) { + return bean; + } + + } + + @Configuration(proxyBeanMethods = false) + static class ForwardedHeaderFilterConfiguration { + + @Bean + FilterRegistrationBean testForwardedHeaderFilter() { + ForwardedHeaderFilter filter = new ForwardedHeaderFilter(); + return new FilterRegistrationBean<>(filter); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CookieSameSiteSupplierConfiguration { + + @Bean + CookieSameSiteSupplier cookieSameSiteSupplier1() { + return CookieSameSiteSupplier.ofLax().whenHasName("test1"); + } + + @Bean + CookieSameSiteSupplier cookieSameSiteSupplier2() { + return CookieSameSiteSupplier.ofNone().whenHasName("test2"); + } + + } + + @ServerEndpoint("/") + public static class TestEndpoint { + + static void register(ServletContext context) { + try { + ServerContainer serverContainer = (ServerContainer) context + .getAttribute("jakarta.websocket.server.ServerContainer"); + if (serverContainer != null) { + serverContainer.addEndpoint(TestEndpoint.class); + } + } + catch (Exception ex) { + // Continue + } + } + + } + + @Configuration(proxyBeanMethods = false) + static class UnauthorizedFilterConfiguration { + + @Bean + FilterRegistrationBean unauthorizedFilter() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(new Filter() { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + ((HttpServletResponse) response).sendError(HttpStatus.UNAUTHORIZED.value()); + } + + }); + registration.setOrder(Ordered.HIGHEST_PRECEDENCE); + registration.addUrlPatterns("/*"); + registration.setDispatcherTypes(DispatcherType.REQUEST); + return registration; + } + + @Bean + ServletRegistrationBean basicServlet() { + ServletRegistrationBean registration = new ServletRegistrationBean<>(new HttpServlet() { + }); + registration.addUrlMappings("/"); + return registration; + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactoryTests.java similarity index 95% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java rename to spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactoryTests.java index 680296fdba30..8efb6d2634b9 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/AbstractReactiveWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.server; +package org.springframework.boot.web.server.reactive; import java.io.InputStream; import java.net.InetSocketAddress; @@ -111,11 +111,11 @@ void tearDown() { } } - protected abstract AbstractReactiveWebServerFactory getFactory(); + protected abstract ConfigurableReactiveWebServerFactory getFactory(); @Test void specificPort() throws Exception { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); int specificPort = doWithRetry(() -> { factory.setPort(0); this.webServer = factory.getWebServer(new EchoHandler()); @@ -135,7 +135,7 @@ void specificPort() throws Exception { @Test protected void restartAfterStop() throws Exception { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); int port = this.webServer.getPort(); @@ -159,7 +159,7 @@ private String getResponse(int port, String uri) { @Test void portIsMinusOneWhenConnectionIsClosed() { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); assertThat(this.webServer.getPort()).isGreaterThan(0); @@ -181,7 +181,7 @@ void basicSslFromFileSystem(@ResourcePath("test.jks") String keyStore) { } protected final void testBasicSslWithKeyStore(String keyStore, String keyPassword) { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); Ssl ssl = new Ssl(); ssl.setKeyStore(keyStore); ssl.setKeyPassword(keyPassword); @@ -208,7 +208,7 @@ protected final void testBasicSslWithKeyStore(String keyStore, String keyPasswor void sslWithValidAlias() { String keyStore = "classpath:test.jks"; String keyPassword = "password"; - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); Ssl ssl = new Ssl(); ssl.setKeyStore(keyStore); ssl.setKeyStorePassword("secret"); @@ -238,7 +238,7 @@ void sslWithValidAlias() { void sslWithInvalidAliasFailsDuringStartup() { String keyStore = "classpath:test.jks"; String keyPassword = "password"; - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); Ssl ssl = new Ssl(); ssl.setKeyStore(keyStore); ssl.setKeyPassword(keyPassword); @@ -303,7 +303,7 @@ protected ReactorClientHttpConnector buildTrustAllSslWithClientKeyConnector(Stri } protected void testClientAuthSuccess(Ssl sslConfiguration, ReactorClientHttpConnector clientConnector) { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); factory.setSsl(sslConfiguration); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); @@ -356,7 +356,7 @@ void sslWithPemCertificates() throws Exception { } protected void testClientAuthFailure(Ssl sslConfiguration, ReactorClientHttpConnector clientConnector) { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); factory.setSsl(sslConfiguration); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); @@ -449,7 +449,7 @@ void whenSslIsEnabledAndNoKeyStoreIsConfiguredThenServerFailsToStart() { @Test void whenThereAreNoInFlightRequestsShutDownGracefullyReturnsTrueBeforePeriodElapses() throws Exception { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); @@ -461,7 +461,7 @@ void whenThereAreNoInFlightRequestsShutDownGracefullyReturnsTrueBeforePeriodElap @Test void whenARequestRemainsInFlightThenShutDownGracefullyDoesNotInvokeCallbackUntilTheRequestCompletes() throws Exception { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingHandler blockingHandler = new BlockingHandler(); this.webServer = factory.getWebServer(blockingHandler); @@ -488,7 +488,7 @@ void whenARequestRemainsInFlightThenShutDownGracefullyDoesNotInvokeCallbackUntil @Test void givenAnInflightRequestWhenTheServerIsStoppedThenGracefulShutdownCallbackIsCalledWithRequestsActive() throws Exception { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingHandler blockingHandler = new BlockingHandler(); this.webServer = factory.getWebServer(blockingHandler); @@ -522,7 +522,7 @@ void givenAnInflightRequestWhenTheServerIsStoppedThenGracefulShutdownCallbackIsC @Test void whenARequestIsActiveAfterGracefulShutdownEndsThenStopWillComplete() throws InterruptedException { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingHandler blockingHandler = new BlockingHandler(); this.webServer = factory.getWebServer(blockingHandler); @@ -549,7 +549,7 @@ void whenARequestIsActiveAfterGracefulShutdownEndsThenStopWillComplete() throws @Test void whenARequestIsActiveThenStopWillComplete() throws InterruptedException { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); BlockingHandler blockingHandler = new BlockingHandler(); this.webServer = factory.getWebServer(blockingHandler); this.webServer.start(); @@ -575,7 +575,7 @@ void whenARequestIsActiveThenStopWillComplete() throws InterruptedException { @Test protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() throws Exception { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); Http2 http2 = new Http2(); http2.setEnabled(true); factory.setHttp2(http2); @@ -595,7 +595,7 @@ protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() throws Excep @Test protected void whenHttp2IsEnabledAndSslIsDisabledThenHttp11CanStillBeUsed() { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); Http2 http2 = new Http2(); http2.setEnabled(true); factory.setHttp2(http2); @@ -613,7 +613,7 @@ protected void whenHttp2IsEnabledAndSslIsDisabledThenHttp11CanStillBeUsed() { @Test void startedLogMessageWithSinglePort() { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); assertThat(startedLogMessage()).matches( @@ -622,7 +622,7 @@ void startedLogMessageWithSinglePort() { @Test protected void startedLogMessageWithMultiplePorts() { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); addConnector(0, factory); this.webServer = factory.getWebServer(new EchoHandler()); this.webServer.start(); @@ -641,7 +641,7 @@ protected WebClient prepareCompressionTest(Compression compression) { } protected WebClient prepareCompressionTest(Compression compression, String responseContentType) { - AbstractReactiveWebServerFactory factory = getFactory(); + ConfigurableReactiveWebServerFactory factory = getFactory(); factory.setCompression(compression); this.webServer = factory.getWebServer(new CharsHandler(3000, responseContentType)); this.webServer.start(); @@ -665,7 +665,7 @@ protected void assertResponseIsNotCompressed(ResponseEntity response) { assertThat(response.getHeaders().headerNames()).doesNotContain("X-Test-Compressed"); } - protected void assertForwardHeaderIsUsed(AbstractReactiveWebServerFactory factory) { + protected void assertForwardHeaderIsUsed(ConfigurableReactiveWebServerFactory factory) { this.webServer = factory.getWebServer(new XForwardedHandler()); this.webServer.start(); String body = getWebClient(this.webServer.getPort()).build() @@ -703,7 +703,7 @@ protected final void doWithBlockedPort(BlockedPortAction action) throws Exceptio protected abstract String startedLogMessage(); - protected abstract void addConnector(int port, AbstractReactiveWebServerFactory factory); + protected abstract void addConnector(int port, ConfigurableReactiveWebServerFactory factory); public interface BlockedPortAction { diff --git a/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/reactive/server/MockReactiveWebServer.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/MockReactiveWebServer.java similarity index 96% rename from spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/reactive/server/MockReactiveWebServer.java rename to spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/MockReactiveWebServer.java index b657c919b003..c72159327b5d 100644 --- a/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/reactive/server/MockReactiveWebServer.java +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/MockReactiveWebServer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.server; +package org.springframework.boot.web.server.reactive; import java.util.Map; diff --git a/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/reactive/server/MockReactiveWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/MockReactiveWebServerFactory.java similarity index 95% rename from spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/reactive/server/MockReactiveWebServerFactory.java rename to spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/MockReactiveWebServerFactory.java index 8ca03badd36f..3a5ddb952901 100644 --- a/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/reactive/server/MockReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/reactive/MockReactiveWebServerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.server; +package org.springframework.boot.web.server.reactive; import org.springframework.boot.web.server.WebServer; import org.springframework.http.server.reactive.HttpHandler; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java similarity index 89% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java rename to spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java index be407f3138e0..90826e9b8d0d 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.io.File; import java.io.FileWriter; @@ -128,12 +128,11 @@ import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; import org.springframework.boot.testsupport.web.servlet.ExampleFilter; import org.springframework.boot.testsupport.web.servlet.ExampleServlet; +import org.springframework.boot.web.error.ErrorPage; import org.springframework.boot.web.server.Compression; import org.springframework.boot.web.server.Cookie.SameSite; -import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.GracefulShutdownResult; import org.springframework.boot.web.server.Http2; import org.springframework.boot.web.server.MimeMappings; @@ -143,10 +142,10 @@ import org.springframework.boot.web.server.Ssl.ClientAuth; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.WebServerException; +import org.springframework.boot.web.server.servlet.Session.SessionTrackingMode; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.server.Session.SessionTrackingMode; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpMethod; @@ -172,7 +171,7 @@ import static org.mockito.Mockito.never; /** - * Base for testing classes that extends {@link AbstractServletWebServerFactory}. + * Base for testing classes that implements {@link ConfigurableServletWebServerFactory}. * * @author Phillip Webb * @author Greg Turnquist @@ -182,7 +181,7 @@ * @author Moritz Halbritter */ @ExtendWith(OutputCaptureExtension.class) -@DirtiesUrlFactories +// @DirtiesUrlFactories public abstract class AbstractServletWebServerFactoryTests { @TempDir @@ -215,7 +214,7 @@ void tearDown() { @Test void startServlet() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); assertThat(getResponse(getLocalUrl("/hello"))).isEqualTo("Hello World"); @@ -223,7 +222,7 @@ void startServlet() throws Exception { @Test void startCalledTwice(CapturedOutput output) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); int port = this.webServer.getPort(); @@ -235,7 +234,7 @@ void startCalledTwice(CapturedOutput output) throws Exception { @Test void stopCalledTwice() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); this.webServer.stop(); @@ -244,7 +243,7 @@ void stopCalledTwice() { @Test protected void restartAfterStop() throws IOException, URISyntaxException { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); assertThat(getResponse(getLocalUrl("/hello"))).isEqualTo("Hello World"); @@ -257,7 +256,7 @@ protected void restartAfterStop() throws IOException, URISyntaxException { @Test void emptyServerWhenPortIsMinusOne() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setPort(-1); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); @@ -266,7 +265,7 @@ void emptyServerWhenPortIsMinusOne() { @Test void stopServlet() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); int port = this.webServer.getPort(); @@ -276,7 +275,7 @@ void stopServlet() { @Test void startServletAndFilter() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(exampleServletRegistration(), new FilterRegistrationBean<>(new ExampleFilter())); this.webServer.start(); @@ -285,7 +284,7 @@ void startServletAndFilter() throws Exception { @Test void startBlocksUntilReadyToServe() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); final Date[] date = new Date[1]; this.webServer = factory.getWebServer((servletContext) -> { try { @@ -302,7 +301,7 @@ void startBlocksUntilReadyToServe() { @Test void loadOnStartAfterContextIsInitialized() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); final InitCountingServlet servlet = new InitCountingServlet(); this.webServer = factory .getWebServer((servletContext) -> servletContext.addServlet("test", servlet).setLoadOnStartup(1)); @@ -313,7 +312,7 @@ void loadOnStartAfterContextIsInitialized() { @Test void portIsMinusOneWhenConnectionIsClosed() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(); this.webServer.start(); assertThat(this.webServer.getPort()).isGreaterThan(0); @@ -323,7 +322,7 @@ void portIsMinusOneWhenConnectionIsClosed() { @Test void specificPort() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); int specificPort = doWithRetry(() -> { factory.setPort(0); this.webServer = factory.getWebServer(exampleServletRegistration()); @@ -336,7 +335,7 @@ void specificPort() throws Exception { @Test void specificContextRoot() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setContextPath("/say"); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); @@ -345,7 +344,7 @@ void specificContextRoot() throws Exception { @Test void contextPathIsLoggedOnStartup(CapturedOutput output) { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setContextPath("/custom"); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); @@ -355,24 +354,24 @@ void contextPathIsLoggedOnStartup(CapturedOutput output) { @Test void contextPathMustStartWithSlash() { assertThatIllegalArgumentException().isThrownBy(() -> getFactory().setContextPath("missingslash")) - .withMessageContaining("ContextPath must start with '/' and not end with '/'"); + .withMessageContaining("Context path must start with '/' and not end with '/'"); } @Test void contextPathMustNotEndWithSlash() { assertThatIllegalArgumentException().isThrownBy(() -> getFactory().setContextPath("extraslash/")) - .withMessageContaining("ContextPath must start with '/' and not end with '/'"); + .withMessageContaining("Context path must start with '/' and not end with '/'"); } @Test void contextRootPathMustNotBeSlash() { assertThatIllegalArgumentException().isThrownBy(() -> getFactory().setContextPath("/")) - .withMessageContaining("Root ContextPath must be specified using an empty string"); + .withMessageContaining("Root context path must be specified using an empty string"); } @Test void multipleConfigurations() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); ServletContextInitializer[] initializers = new ServletContextInitializer[6]; Arrays.setAll(initializers, (i) -> mock(ServletContextInitializer.class)); factory.setInitializers(Arrays.asList(initializers[2], initializers[3])); @@ -387,7 +386,7 @@ void multipleConfigurations() throws Exception { @Test void documentRoot() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); this.webServer = factory.getWebServer(); this.webServer.start(); @@ -397,7 +396,7 @@ void documentRoot() throws Exception { @Test void mimeType() throws Exception { FileCopyUtils.copy("test", new FileWriter(new File(this.tempDir, "test.xxcss"))); - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setRegisterDefaultServlet(true); factory.setDocumentRoot(this.tempDir); MimeMappings mimeMappings = new MimeMappings(); @@ -412,7 +411,7 @@ void mimeType() throws Exception { @Test void errorPage() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/hello")); this.webServer = factory.getWebServer(exampleServletRegistration(), errorServletRegistration()); this.webServer.start(); @@ -422,7 +421,7 @@ void errorPage() throws Exception { @Test void errorPageFromPutRequest() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/hello")); this.webServer = factory.getWebServer(exampleServletRegistration(), errorServletRegistration()); this.webServer.start(); @@ -445,7 +444,7 @@ void basicSslFromFileSystem(@ResourcePath("test.jks") String keyStore) throws Ex @Test @WithPackageResources("test.jks") void sslDisabled() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Ssl ssl = getSsl(null, "password", "classpath:test.jks"); ssl.setEnabled(false); factory.setSsl(ssl); @@ -460,7 +459,7 @@ void sslDisabled() throws Exception { @Test @WithPackageResources("test.jks") void sslGetScheme() throws Exception { // gh-2232 - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setSsl(getSsl(null, "password", "classpath:test.jks")); this.webServer = factory.getWebServer(new ServletRegistrationBean<>(new ExampleServlet(true, false), "/hello")); this.webServer.start(); @@ -472,7 +471,7 @@ void sslGetScheme() throws Exception { // gh-2232 @Test @WithPackageResources("test.jks") void sslKeyAlias() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Ssl ssl = getSsl(null, "password", "test-alias", "classpath:test.jks"); factory.setSsl(ssl); ServletRegistrationBean registration = new ServletRegistrationBean<>( @@ -493,7 +492,7 @@ void sslKeyAlias() throws Exception { @Test @WithPackageResources("test.jks") void sslWithInvalidAliasFailsDuringStartup() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Ssl ssl = getSsl(null, "password", "test-alias-404", "classpath:test.jks"); factory.setSsl(ssl); ServletRegistrationBean registration = new ServletRegistrationBean<>( @@ -510,7 +509,7 @@ protected void assertThatSslWithInvalidAliasCallFails(ThrowingCallable call) { @Test @WithPackageResources("test.jks") void serverHeaderIsDisabledByDefaultWhenUsingSsl() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setSsl(getSsl(null, "password", "classpath:test.jks")); this.webServer = factory.getWebServer(new ServletRegistrationBean<>(new ExampleServlet(true, false), "/hello")); this.webServer.start(); @@ -526,7 +525,7 @@ void serverHeaderIsDisabledByDefaultWhenUsingSsl() throws Exception { @Test @WithPackageResources("test.jks") void serverHeaderCanBeCustomizedWhenUsingSsl() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setServerHeader("MyServer"); factory.setSsl(getSsl(null, "password", "classpath:test.jks")); this.webServer = factory.getWebServer(new ServletRegistrationBean<>(new ExampleServlet(true, false), "/hello")); @@ -541,7 +540,7 @@ void serverHeaderCanBeCustomizedWhenUsingSsl() throws Exception { } protected final void testBasicSslWithKeyStore(String keyStore) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(getSsl(null, "password", keyStore)); this.webServer = factory.getWebServer(); @@ -554,7 +553,7 @@ protected final void testBasicSslWithKeyStore(String keyStore) throws Exception @Test @WithPackageResources("test.p12") void pkcs12KeyStoreAndTrustStore(@ResourcePath("test.p12") File keyStoreFile) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(getSsl(ClientAuth.NEED, null, "classpath:test.p12", "classpath:test.p12", null, null)); this.webServer = factory.getWebServer(); @@ -572,7 +571,7 @@ void pkcs12KeyStoreAndTrustStore(@ResourcePath("test.p12") File keyStoreFile) th @Test @WithPackageResources({ "test.p12", "test-cert.pem", "test-key.pem" }) void pemKeyStoreAndTrustStore(@ResourcePath("test.p12") File keyStoreFile) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(getSsl("classpath:test-cert.pem", "classpath:test-key.pem")); this.webServer = factory.getWebServer(); @@ -590,7 +589,7 @@ void pemKeyStoreAndTrustStore(@ResourcePath("test.p12") File keyStoreFile) throw @Test @WithPackageResources("test.p12") void pkcs12KeyStoreAndTrustStoreFromBundle(@ResourcePath("test.p12") File keyStoreFile) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(Ssl.forBundle("test")); factory.setSslBundles( @@ -610,7 +609,7 @@ void pkcs12KeyStoreAndTrustStoreFromBundle(@ResourcePath("test.p12") File keySto @Test @WithPackageResources({ "test.p12", "test-cert.pem", "test-key.pem" }) void pemKeyStoreAndTrustStoreFromBundle(@ResourcePath("test.p12") File keyStoreFile) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(Ssl.forBundle("test")); factory.setSslBundles(new DefaultSslBundleRegistry("test", @@ -631,7 +630,7 @@ void pemKeyStoreAndTrustStoreFromBundle(@ResourcePath("test.p12") File keyStoreF @WithPackageResources("test.jks") void sslNeedsClientAuthenticationSucceedsWithClientCertificate(@ResourcePath("test.jks") File keyStoreFile) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setRegisterDefaultServlet(true); addTestTxtFile(factory); factory.setSsl(getSsl(ClientAuth.NEED, "password", "classpath:test.jks", "classpath:test.jks", null, null)); @@ -650,7 +649,7 @@ void sslNeedsClientAuthenticationSucceedsWithClientCertificate(@ResourcePath("te @Test @WithPackageResources("test.jks") void sslNeedsClientAuthenticationFailsWithoutClientCertificate() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(getSsl(ClientAuth.NEED, "password", "classpath:test.jks")); this.webServer = factory.getWebServer(); @@ -665,7 +664,7 @@ void sslNeedsClientAuthenticationFailsWithoutClientCertificate() throws Exceptio @WithPackageResources("test.jks") void sslWantsClientAuthenticationSucceedsWithClientCertificate(@ResourcePath("test.jks") File keyStoreFile) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); factory .setSsl(getSsl(ClientAuth.WANT, "password", "classpath:test.jks", null, new String[] { "TLSv1.2" }, null)); @@ -684,7 +683,7 @@ void sslWantsClientAuthenticationSucceedsWithClientCertificate(@ResourcePath("te @Test @WithPackageResources("test.jks") void sslWantsClientAuthenticationSucceedsWithoutClientCertificate() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(getSsl(ClientAuth.WANT, "password", "classpath:test.jks")); this.webServer = factory.getWebServer(); @@ -696,15 +695,15 @@ void sslWantsClientAuthenticationSucceedsWithoutClientCertificate() throws Excep @Test void disableJspServletRegistration() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); - factory.getJsp().setRegistered(false); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getJsp().setRegistered(false); this.webServer = factory.getWebServer(); assertThat(getJspServlet()).isNull(); } @Test void cannotReadClassPathFiles() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); ClientHttpResponse response = getClientResponse( @@ -796,13 +795,13 @@ private String getStoreType(String keyStore) { @Test void defaultSessionTimeout() { - assertThat(getFactory().getSession().getTimeout()).hasMinutes(30); + assertThat(getFactory().getSettings().getSession().getTimeout()).hasMinutes(30); } @Test void persistSession() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); - factory.getSession().setPersistent(true); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getSession().setPersistent(true); this.webServer = factory.getWebServer(sessionServletRegistration()); this.webServer.start(); String s1 = getResponse(getLocalUrl("/session")); @@ -818,11 +817,11 @@ void persistSession() throws Exception { @Test void persistSessionInSpecificSessionStoreDir() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); File sessionStoreDir = new File(this.tempDir, "sessions"); sessionStoreDir.mkdir(); - factory.getSession().setPersistent(true); - factory.getSession().setStoreDir(sessionStoreDir); + factory.getSettings().getSession().setPersistent(true); + factory.getSettings().getSession().setStoreDir(sessionStoreDir); this.webServer = factory.getWebServer(sessionServletRegistration()); this.webServer.start(); getResponse(getLocalUrl("/session")); @@ -833,41 +832,43 @@ void persistSessionInSpecificSessionStoreDir() throws Exception { @Test void getValidSessionStoreWhenSessionStoreNotSet() { - AbstractServletWebServerFactory factory = getFactory(); - File dir = factory.getValidSessionStoreDir(false); + ConfigurableServletWebServerFactory factory = getFactory(); + File dir = factory.getSettings().getSession().getSessionStoreDirectory().getValidDirectory(false); assertThat(dir).hasName("servlet-sessions"); assertThat(dir).hasParent(new ApplicationTemp().getDir()); } @Test void getValidSessionStoreWhenSessionStoreIsRelative() { - AbstractServletWebServerFactory factory = getFactory(); - factory.getSession().setStoreDir(new File("sessions")); - File dir = factory.getValidSessionStoreDir(false); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getSession().setStoreDir(new File("sessions")); + File dir = factory.getSettings().getSession().getSessionStoreDirectory().getValidDirectory(false); assertThat(dir).hasName("sessions"); assertThat(dir).hasParent(new ApplicationHome().getDir()); } @Test void getValidSessionStoreWhenSessionStoreReferencesFile() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); File file = new File(this.tempDir, "file"); file.createNewFile(); - factory.getSession().setStoreDir(file); - assertThatIllegalStateException().isThrownBy(() -> factory.getValidSessionStoreDir(false)) + factory.getSettings().getSession().setStoreDir(file); + assertThatIllegalStateException() + .isThrownBy(() -> factory.getSettings().getSession().getSessionStoreDirectory().getValidDirectory(false)) .withMessageContaining("points to a file"); } @Test void sessionCookieConfiguration() { - AbstractServletWebServerFactory factory = getFactory(); - factory.getSession().getCookie().setName("testname"); - factory.getSession().getCookie().setDomain("testdomain"); - factory.getSession().getCookie().setPath("/testpath"); - factory.getSession().getCookie().setHttpOnly(true); - factory.getSession().getCookie().setSecure(true); - factory.getSession().getCookie().setPartitioned(true); - factory.getSession().getCookie().setMaxAge(Duration.ofSeconds(60)); + ConfigurableServletWebServerFactory factory = getFactory(); + org.springframework.boot.web.server.Cookie cookie = factory.getSettings().getSession().getCookie(); + cookie.setName("testname"); + cookie.setDomain("testdomain"); + cookie.setPath("/testpath"); + cookie.setHttpOnly(true); + cookie.setSecure(true); + cookie.setPartitioned(true); + cookie.setMaxAge(Duration.ofSeconds(60)); final AtomicReference configReference = new AtomicReference<>(); this.webServer = factory.getWebServer((context) -> configReference.set(context.getSessionCookieConfig())); SessionCookieConfig sessionCookieConfig = configReference.get(); @@ -883,8 +884,8 @@ void sessionCookieConfiguration() { @ParameterizedTest @EnumSource(mode = EnumSource.Mode.EXCLUDE, names = "OMITTED") void sessionCookieSameSiteAttributeCanBeConfiguredAndOnlyAffectsSessionCookies(SameSite sameSite) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); - factory.getSession().getCookie().setSameSite(sameSite); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getSession().getCookie().setSameSite(sameSite); factory.addInitializers(new ServletRegistrationBean<>(new CookieServlet(false), "/")); this.webServer = factory.getWebServer(); this.webServer.start(); @@ -899,9 +900,9 @@ void sessionCookieSameSiteAttributeCanBeConfiguredAndOnlyAffectsSessionCookies(S @EnumSource(mode = EnumSource.Mode.EXCLUDE, names = "OMITTED") void sessionCookieSameSiteAttributeCanBeConfiguredAndOnlyAffectsSessionCookiesWhenUsingCustomName(SameSite sameSite) throws Exception { - AbstractServletWebServerFactory factory = getFactory(); - factory.getSession().getCookie().setName("THESESSION"); - factory.getSession().getCookie().setSameSite(sameSite); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getSession().getCookie().setName("THESESSION"); + factory.getSettings().getSession().getCookie().setSameSite(sameSite); factory.addInitializers(new ServletRegistrationBean<>(new CookieServlet(false), "/")); this.webServer = factory.getWebServer(); this.webServer.start(); @@ -914,7 +915,7 @@ void sessionCookieSameSiteAttributeCanBeConfiguredAndOnlyAffectsSessionCookiesWh @Test void cookieSameSiteSuppliers() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.addCookieSameSiteSuppliers(CookieSameSiteSupplier.ofLax().whenHasName("relaxed")); factory.addCookieSameSiteSuppliers(CookieSameSiteSupplier.ofNone().whenHasName("empty")); factory.addCookieSameSiteSuppliers(CookieSameSiteSupplier.ofStrict().whenHasName("controlled")); @@ -934,9 +935,9 @@ void cookieSameSiteSuppliers() throws Exception { @Test void cookieSameSiteSuppliersShouldNotAffectSessionCookie() throws IOException, URISyntaxException { - AbstractServletWebServerFactory factory = getFactory(); - factory.getSession().getCookie().setSameSite(SameSite.LAX); - factory.getSession().getCookie().setName("SESSIONCOOKIE"); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getSession().getCookie().setSameSite(SameSite.LAX); + factory.getSettings().getSession().getCookie().setName("SESSIONCOOKIE"); factory.addCookieSameSiteSuppliers(CookieSameSiteSupplier.ofStrict()); factory.addInitializers(new ServletRegistrationBean<>(new CookieServlet(false), "/")); this.webServer = factory.getWebServer(); @@ -951,9 +952,9 @@ void cookieSameSiteSuppliersShouldNotAffectSessionCookie() throws IOException, U @Test void cookieSameSiteSuppliersShouldNotAffectOmittedSameSite() throws IOException, URISyntaxException { - AbstractServletWebServerFactory factory = getFactory(); - factory.getSession().getCookie().setSameSite(SameSite.OMITTED); - factory.getSession().getCookie().setName("SESSIONCOOKIE"); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getSession().getCookie().setSameSite(SameSite.OMITTED); + factory.getSettings().getSession().getCookie().setName("SESSIONCOOKIE"); factory.addCookieSameSiteSuppliers(CookieSameSiteSupplier.ofStrict()); factory.addInitializers(new ServletRegistrationBean<>(new CookieServlet(false), "/")); this.webServer = factory.getWebServer(); @@ -967,14 +968,15 @@ void cookieSameSiteSuppliersShouldNotAffectOmittedSameSite() throws IOException, } @Test + @WithPackageResources("test.jks") protected void sslSessionTracking() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Ssl ssl = new Ssl(); ssl.setEnabled(true); - ssl.setKeyStore("src/test/resources/org/springframework/boot/web/server/test.jks"); + ssl.setKeyStore("classpath:test.jks"); ssl.setKeyPassword("password"); factory.setSsl(ssl); - factory.getSession().setTrackingModes(EnumSet.of(SessionTrackingMode.SSL)); + factory.getSettings().getSession().setTrackingModes(EnumSet.of(SessionTrackingMode.SSL)); AtomicReference contextReference = new AtomicReference<>(); this.webServer = factory.getWebServer(contextReference::set); assertThat(contextReference.get().getEffectiveSessionTrackingModes()) @@ -1009,7 +1011,7 @@ protected void noCompressionForUserAgent() throws Exception { @Test void compressionWithoutContentSizeHeader() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Compression compression = new Compression(); compression.setEnabled(true); factory.setCompression(compression); @@ -1025,7 +1027,7 @@ void compressionWithoutContentSizeHeader() throws Exception { @Test void mimeMappingsAreCorrectlyConfigured() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(); Collection configuredMimeMappings = getActualMimeMappings().entrySet() .stream() @@ -1037,7 +1039,7 @@ void mimeMappingsAreCorrectlyConfigured() { @Test void additionalMimeMappingsCanBeConfigured() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); MimeMappings additionalMimeMappings = new MimeMappings(); additionalMimeMappings.add("a", "alpha"); additionalMimeMappings.add("b", "bravo"); @@ -1054,7 +1056,7 @@ void additionalMimeMappingsCanBeConfigured() { @Test void rootServletContextResource() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); final AtomicReference rootResource = new AtomicReference<>(); this.webServer = factory.getWebServer((servletContext) -> { try { @@ -1070,7 +1072,7 @@ void rootServletContextResource() { @Test void customServerHeader() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setServerHeader("MyServer"); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); @@ -1080,7 +1082,7 @@ void customServerHeader() throws Exception { @Test void serverHeaderIsDisabledByDefault() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(exampleServletRegistration()); this.webServer.start(); ClientHttpResponse response = getClientResponse(getLocalUrl("/hello")); @@ -1091,7 +1093,7 @@ void serverHeaderIsDisabledByDefault() throws Exception { protected void portClashOfPrimaryConnectorResultsInPortInUseException() throws Exception { doWithBlockedPort((port) -> { assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setPort(port); AbstractServletWebServerFactoryTests.this.webServer = factory.getWebServer(); AbstractServletWebServerFactoryTests.this.webServer.start(); @@ -1103,7 +1105,7 @@ protected void portClashOfPrimaryConnectorResultsInPortInUseException() throws E protected void portClashOfSecondaryConnectorResultsInPortInUseException() throws Exception { doWithBlockedPort((port) -> { assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addConnector(port, factory); AbstractServletWebServerFactoryTests.this.webServer = factory.getWebServer(); AbstractServletWebServerFactoryTests.this.webServer.start(); @@ -1113,7 +1115,7 @@ protected void portClashOfSecondaryConnectorResultsInPortInUseException() throws @Test void malformedAddress() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setAddress(InetAddress.getByName("129.129.129.129")); assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> { this.webServer = factory.getWebServer(); @@ -1123,7 +1125,7 @@ void malformedAddress() throws Exception { @Test void localeCharsetMappingsAreConfigured() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Map mappings = new HashMap<>(); mappings.put(Locale.GERMAN, StandardCharsets.UTF_8); factory.setLocaleCharsetMappings(mappings); @@ -1136,8 +1138,8 @@ void localeCharsetMappingsAreConfigured() { void jspServletInitParameters() throws Exception { Map initParameters = new HashMap<>(); initParameters.put("a", "alpha"); - AbstractServletWebServerFactory factory = getFactory(); - factory.getJsp().setInitParameters(initParameters); + ConfigurableServletWebServerFactory factory = getFactory(); + factory.getSettings().getJsp().setInitParameters(initParameters); this.webServer = factory.getWebServer(); Assumptions.assumeFalse(getJspServlet() == null); JspServlet jspServlet = getJspServlet(); @@ -1146,7 +1148,7 @@ void jspServletInitParameters() throws Exception { @Test void jspServletIsNotInDevelopmentModeByDefault() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(); Assumptions.assumeFalse(getJspServlet() == null); JspServlet jspServlet = getJspServlet(); @@ -1156,7 +1158,7 @@ void jspServletIsNotInDevelopmentModeByDefault() throws Exception { @Test void faultyFilterCausesStartFailure() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.addInitializers((servletContext) -> servletContext.addFilter("faulty", new Filter() { @Override @@ -1180,28 +1182,31 @@ public void destroy() { @Test void sessionConfiguration() { - AbstractServletWebServerFactory factory = getFactory(); - factory.getSession().setTimeout(Duration.ofSeconds(123)); - factory.getSession().setTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE, SessionTrackingMode.URL)); - factory.getSession().getCookie().setName("testname"); - factory.getSession().getCookie().setDomain("testdomain"); - factory.getSession().getCookie().setPath("/testpath"); - factory.getSession().getCookie().setHttpOnly(true); - factory.getSession().getCookie().setSecure(true); - factory.getSession().getCookie().setPartitioned(false); - factory.getSession().getCookie().setMaxAge(Duration.ofMinutes(1)); + ConfigurableServletWebServerFactory factory = getFactory(); + Session session = factory.getSettings().getSession(); + session.setTimeout(Duration.ofSeconds(123)); + session.setTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE, SessionTrackingMode.URL)); + org.springframework.boot.web.server.Cookie cookie = session.getCookie(); + cookie.setName("testname"); + cookie.setDomain("testdomain"); + cookie.setPath("/testpath"); + cookie.setHttpOnly(true); + cookie.setSecure(true); + cookie.setPartitioned(false); + cookie.setMaxAge(Duration.ofMinutes(1)); AtomicReference contextReference = new AtomicReference<>(); factory.getWebServer(contextReference::set).start(); ServletContext servletContext = contextReference.get(); assertThat(servletContext.getEffectiveSessionTrackingModes()) .isEqualTo(EnumSet.of(jakarta.servlet.SessionTrackingMode.COOKIE, jakarta.servlet.SessionTrackingMode.URL)); - assertThat(servletContext.getSessionCookieConfig().getName()).isEqualTo("testname"); - assertThat(servletContext.getSessionCookieConfig().getDomain()).isEqualTo("testdomain"); - assertThat(servletContext.getSessionCookieConfig().getPath()).isEqualTo("/testpath"); - assertThat(servletContext.getSessionCookieConfig().isHttpOnly()).isTrue(); - assertThat(servletContext.getSessionCookieConfig().isSecure()).isTrue(); - assertThat(servletContext.getSessionCookieConfig().getMaxAge()).isEqualTo(60); - assertThat(servletContext.getSessionCookieConfig().getAttribute("Partitioned")).isEqualTo("false"); + SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig(); + assertThat(sessionCookieConfig.getName()).isEqualTo("testname"); + assertThat(sessionCookieConfig.getDomain()).isEqualTo("testdomain"); + assertThat(sessionCookieConfig.getPath()).isEqualTo("/testpath"); + assertThat(sessionCookieConfig.isHttpOnly()).isTrue(); + assertThat(sessionCookieConfig.isSecure()).isTrue(); + assertThat(sessionCookieConfig.getMaxAge()).isEqualTo(60); + assertThat(sessionCookieConfig.getAttribute("Partitioned")).isEqualTo("false"); } @Test @@ -1224,7 +1229,7 @@ void servletContextListenerContextDestroyedIsCalledWhenContainerIsDestroyed() th @Test void exceptionThrownOnLoadFailureIsRethrown() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory .getWebServer((context) -> context.addServlet("failing", FailingServlet.class).setLoadOnStartup(0)); assertThatExceptionOfType(WebServerException.class).isThrownBy(this.webServer::start) @@ -1233,7 +1238,7 @@ void exceptionThrownOnLoadFailureIsRethrown() { @Test void whenThereAreNoInFlightRequestsShutDownGracefullyInvokesCallbackWithIdle() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); this.webServer = factory.getWebServer(); this.webServer.start(); @@ -1245,7 +1250,7 @@ void whenThereAreNoInFlightRequestsShutDownGracefullyInvokesCallbackWithIdle() t @Test void whenARequestRemainsInFlightThenShutDownGracefullyDoesNotInvokeCallbackUntilTheRequestCompletes() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory.getWebServer((context) -> { @@ -1266,7 +1271,7 @@ void whenARequestRemainsInFlightThenShutDownGracefullyDoesNotInvokeCallbackUntil @Test void whenAnAsyncRequestRemainsInFlightThenShutDownGracefullyDoesNotInvokeCallbackUntilRequestCompletes() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingAsyncServlet blockingAsyncServlet = new BlockingAsyncServlet(); this.webServer = factory.getWebServer((context) -> { @@ -1290,7 +1295,7 @@ void whenAnAsyncRequestRemainsInFlightThenShutDownGracefullyDoesNotInvokeCallbac @Test void whenARequestIsActiveThenStopWillComplete() throws InterruptedException { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory .getWebServer((context) -> context.addServlet("blockingServlet", blockingServlet).addMapping("/")); @@ -1309,7 +1314,7 @@ void whenARequestIsActiveThenStopWillComplete() throws InterruptedException { @Test protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Http2 http2 = new Http2(); http2.setEnabled(true); factory.setHttp2(http2); @@ -1326,7 +1331,7 @@ protected void whenHttp2IsEnabledAndSslIsDisabledThenH2cCanBeUsed() throws Excep @Test protected void whenHttp2IsEnabledAndSslIsDisabledThenHttp11CanStillBeUsed() throws IOException, URISyntaxException { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Http2 http2 = new Http2(); http2.setEnabled(true); factory.setHttp2(http2); @@ -1337,7 +1342,7 @@ protected void whenHttp2IsEnabledAndSslIsDisabledThenHttp11CanStillBeUsed() thro @Test void whenARequestIsActiveAfterGracefulShutdownEndsThenStopWillComplete() throws InterruptedException { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setShutdown(Shutdown.GRACEFUL); BlockingServlet blockingServlet = new BlockingServlet(); this.webServer = factory @@ -1361,7 +1366,7 @@ void whenARequestIsActiveAfterGracefulShutdownEndsThenStopWillComplete() throws @Test void startedLogMessageWithSinglePort() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(); this.webServer.start(); assertThat(startedLogMessage()).matches("(Jetty|Tomcat|Undertow) started on port " + this.webServer.getPort() @@ -1370,7 +1375,7 @@ void startedLogMessageWithSinglePort() { @Test void startedLogMessageWithSinglePortAndContextPath() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); factory.setContextPath("/test"); this.webServer = factory.getWebServer(); this.webServer.start(); @@ -1380,7 +1385,7 @@ void startedLogMessageWithSinglePortAndContextPath() { @Test void startedLogMessageWithMultiplePorts() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); addConnector(0, factory); this.webServer = factory.getWebServer(); this.webServer.start(); @@ -1390,7 +1395,7 @@ void startedLogMessageWithMultiplePorts() { @Test void servletComponentsAreInitializedWithTheSameThreadContextClassLoader() { - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); ThreadContextClassLoaderCapturingServlet servlet = new ThreadContextClassLoaderCapturingServlet(); ThreadContextClassLoaderCapturingFilter filter = new ThreadContextClassLoaderCapturingFilter(); ThreadContextClassLoaderCapturingListener listener = new ThreadContextClassLoaderCapturingListener(); @@ -1440,7 +1445,7 @@ private void wrapsFailingServletException(WebServerException ex) { fail("Exception did not wrap FailingServletException"); } - protected abstract void addConnector(int port, AbstractServletWebServerFactory factory); + protected abstract void addConnector(int port, ConfigurableServletWebServerFactory factory); protected abstract void handleExceptionCausedByBlockedPortOnPrimaryConnector(RuntimeException ex, int blockedPort); @@ -1471,7 +1476,7 @@ private String setUpFactoryForCompression(int contentSize, String[] mimeTypes, S char[] chars = new char[contentSize]; Arrays.fill(chars, 'F'); String testContent = new String(chars); - AbstractServletWebServerFactory factory = getFactory(); + ConfigurableServletWebServerFactory factory = getFactory(); Compression compression = new Compression(); compression.setEnabled(true); if (mimeTypes != null) { @@ -1501,7 +1506,7 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws protected abstract Charset getCharset(Locale locale); - protected void addTestTxtFile(AbstractServletWebServerFactory factory) throws IOException { + protected void addTestTxtFile(ConfigurableServletWebServerFactory factory) throws IOException { FileCopyUtils.copy("test", new FileWriter(new File(this.tempDir, "test.txt"))); factory.setDocumentRoot(this.tempDir); factory.setRegisterDefaultServlet(true); @@ -1578,7 +1583,7 @@ protected void assertForwardHeaderIsUsed(ServletWebServerFactory factory) throws .contains("remoteaddr=140.211.11.130"); } - protected abstract AbstractServletWebServerFactory getFactory(); + protected abstract ConfigurableServletWebServerFactory getFactory(); protected abstract org.apache.jasper.servlet.JspServlet getJspServlet() throws Exception; diff --git a/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerServletContextListenerTests.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerServletContextListenerTests.java new file mode 100644 index 000000000000..cc29599de56a --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerServletContextListenerTests.java @@ -0,0 +1,93 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.servlet; + +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.testsupport.classpath.ForkedClassPath; +import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + +/** + * Base class for tests for {@link WebServer}s driving {@link ServletContextListener}s + * correctly. + * + * @author Andy Wilkinson + */ +@DirtiesUrlFactories +public abstract class AbstractServletWebServerServletContextListenerTests { + + private final Class webServerConfiguration; + + protected AbstractServletWebServerServletContextListenerTests(Class webServerConfiguration) { + this.webServerConfiguration = webServerConfiguration; + } + + @Test + @ForkedClassPath + void registeredServletContextListenerBeanIsCalled() { + AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( + ServletListenerRegistrationBeanConfiguration.class, this.webServerConfiguration); + ServletContextListener servletContextListener = (ServletContextListener) context + .getBean("registration", ServletListenerRegistrationBean.class) + .getListener(); + then(servletContextListener).should().contextInitialized(any(ServletContextEvent.class)); + context.close(); + } + + @Test + @ForkedClassPath + void servletContextListenerBeanIsCalled() { + AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext( + ServletContextListenerBeanConfiguration.class, this.webServerConfiguration); + ServletContextListener servletContextListener = context.getBean("servletContextListener", + ServletContextListener.class); + then(servletContextListener).should().contextInitialized(any(ServletContextEvent.class)); + context.close(); + } + + @Configuration(proxyBeanMethods = false) + static class ServletContextListenerBeanConfiguration { + + @Bean + ServletContextListener servletContextListener() { + return mock(ServletContextListener.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ServletListenerRegistrationBeanConfiguration { + + @Bean + ServletListenerRegistrationBean registration() { + return new ServletListenerRegistrationBean<>(mock(ServletContextListener.class)); + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/server/MockServletWebServer.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/MockServletWebServer.java similarity index 85% rename from spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/server/MockServletWebServer.java rename to spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/MockServletWebServer.java index b52b98a15443..b8efd73cdeea 100644 --- a/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/server/MockServletWebServer.java +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/MockServletWebServer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.server; +package org.springframework.boot.web.server.servlet; import java.util.ArrayList; import java.util.Arrays; @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.StreamSupport; import jakarta.servlet.Filter; import jakarta.servlet.FilterRegistration; @@ -33,7 +34,6 @@ import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.WebServerException; -import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.mock.web.MockSessionCookieConfig; import static org.mockito.ArgumentMatchers.any; @@ -58,10 +58,14 @@ public class MockServletWebServer implements WebServer { private final List registeredFilters = new ArrayList<>(); + private final Map filterRegistrations = new HashMap<>(); + + private final Map servletRegistrations = new HashMap<>(); + private final int port; - MockServletWebServer(ServletContextInitializer[] initializers, int port) { - this(Arrays.stream(initializers) + MockServletWebServer(ServletContextInitializers initializers, int port) { + this(StreamSupport.stream(initializers.spliterator(), false) .map((initializer) -> (Initializer) initializer::onStartup) .toArray(Initializer[]::new), port); } @@ -72,17 +76,20 @@ public class MockServletWebServer implements WebServer { initialize(); } + @SuppressWarnings("unchecked") private void initialize() { try { this.servletContext = mock(ServletContext.class); lenient().doAnswer((invocation) -> { RegisteredServlet registeredServlet = new RegisteredServlet(invocation.getArgument(1)); MockServletWebServer.this.registeredServlets.add(registeredServlet); + this.servletRegistrations.put(invocation.getArgument(0), registeredServlet.getRegistration()); return registeredServlet.getRegistration(); }).when(this.servletContext).addServlet(anyString(), any(Servlet.class)); lenient().doAnswer((invocation) -> { RegisteredFilter registeredFilter = new RegisteredFilter(invocation.getArgument(1)); MockServletWebServer.this.registeredFilters.add(registeredFilter); + this.filterRegistrations.put(invocation.getArgument(0), registeredFilter.getRegistration()); return registeredFilter.getRegistration(); }).when(this.servletContext).addFilter(anyString(), any(Filter.class)); final SessionCookieConfig sessionCookieConfig = new MockSessionCookieConfig(); @@ -98,6 +105,10 @@ private void initialize() { .when(this.servletContext) .getInitParameter(anyString()); given(this.servletContext.getAttributeNames()).willReturn(Collections.emptyEnumeration()); + lenient().when((Map) this.servletContext.getFilterRegistrations()) + .thenReturn(this.filterRegistrations); + lenient().when((Map) this.servletContext.getServletRegistrations()) + .thenReturn(this.servletRegistrations); for (Initializer initializer : this.initializers) { initializer.onStartup(this.servletContext); } @@ -115,6 +126,8 @@ public void start() throws WebServerException { public void stop() { this.servletContext = null; this.registeredServlets.clear(); + this.filterRegistrations.clear(); + this.registeredFilters.clear(); } public ServletContext getServletContext() { diff --git a/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/MockServletWebServerFactory.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/MockServletWebServerFactory.java new file mode 100644 index 000000000000..a2d2f016347d --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/MockServletWebServerFactory.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.server.servlet; + +import jakarta.servlet.ServletContext; + +import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.servlet.MockServletWebServer.RegisteredFilter; +import org.springframework.boot.web.server.servlet.MockServletWebServer.RegisteredServlet; +import org.springframework.boot.web.servlet.ServletContextInitializer; + +import static org.mockito.Mockito.spy; + +/** + * Mock {@link ServletWebServerFactory}. + * + * @author Phillip Webb + * @author Andy Wilkinson + */ +public class MockServletWebServerFactory extends AbstractConfigurableWebServerFactory + implements ConfigurableServletWebServerFactory { + + private final ServletWebServerSettings settings = new ServletWebServerSettings(); + + private MockServletWebServer webServer; + + @Override + public WebServer getWebServer(ServletContextInitializer... initializers) { + this.webServer = spy( + new MockServletWebServer(ServletContextInitializers.from(this.settings, initializers), getPort())); + return this.webServer; + } + + public MockServletWebServer getWebServer() { + return this.webServer; + } + + public ServletContext getServletContext() { + return (getWebServer() != null) ? getWebServer().getServletContext() : null; + } + + public RegisteredServlet getRegisteredServlet(int index) { + return (getWebServer() != null) ? getWebServer().getRegisteredServlet(index) : null; + } + + public RegisteredFilter getRegisteredFilter(int index) { + return (getWebServer() != null) ? getWebServer().getRegisteredFilters(index) : null; + } + + @Override + public ServletWebServerSettings getSettings() { + return this.settings; + } + +} diff --git a/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/servlet/context/AbstractServletWebServerMvcIntegrationTests.java b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/servlet/context/AbstractServletWebServerMvcIntegrationTests.java new file mode 100644 index 000000000000..3877babf4747 --- /dev/null +++ b/spring-boot-project/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/servlet/context/AbstractServletWebServerMvcIntegrationTests.java @@ -0,0 +1,172 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.servlet.context; + +import java.net.URI; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.ClientHttpRequest; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Base class for integration testing of {@link ServletWebServerApplicationContext} and + * {@link WebServer}s running Spring MVC. + * + * @author Phillip Webb + * @author Ivan Sopov + */ +public abstract class AbstractServletWebServerMvcIntegrationTests { + + private AnnotationConfigServletWebServerApplicationContext context; + + private Class webServerConfiguration; + + protected AbstractServletWebServerMvcIntegrationTests(Class webServerConfiguration) { + this.webServerConfiguration = webServerConfiguration; + } + + @AfterEach + void closeContext() { + try { + this.context.close(); + } + catch (Exception ex) { + // Ignore + } + } + + @Test + void basicConfig() throws Exception { + this.context = new AnnotationConfigServletWebServerApplicationContext(this.webServerConfiguration, + Config.class); + doTest(this.context, "/hello"); + } + + @Test + @WithResource(name = "conf.properties", content = "context=/example") + void advancedConfig() throws Exception { + this.context = new AnnotationConfigServletWebServerApplicationContext(this.webServerConfiguration, + AdvancedConfig.class); + doTest(this.context, "/example/spring/hello"); + } + + private void doTest(AnnotationConfigServletWebServerApplicationContext context, String resourcePath) + throws Exception { + SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory(); + ClientHttpRequest request = clientHttpRequestFactory.createRequest( + new URI("http://localhost:" + context.getWebServer().getPort() + resourcePath), HttpMethod.GET); + try (ClientHttpResponse response = request.execute()) { + assertThat(response.getBody()).hasContent("Hello World"); + } + } + + @Configuration(proxyBeanMethods = false) + @EnableWebMvc + static class Config { + + @Bean + DispatcherServlet dispatcherServlet() { + return new DispatcherServlet(); + } + + @Bean + HelloWorldController helloWorldController() { + return new HelloWorldController(); + } + + } + + @Configuration(proxyBeanMethods = false) + @EnableWebMvc + @PropertySource("classpath:conf.properties") + static class AdvancedConfig { + + private final Environment env; + + AdvancedConfig(Environment env) { + this.env = env; + } + + @Bean + static WebServerFactoryCustomizerBeanPostProcessor webServerFactoryCustomizerBeanPostProcessor() { + return new WebServerFactoryCustomizerBeanPostProcessor(); + } + + @Bean + WebServerFactoryCustomizer contextPathCustomizer() { + return (factory) -> { + String contextPath = this.env.getProperty("context"); + factory.setContextPath(contextPath); + }; + } + + @Bean + ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) { + ServletRegistrationBean registration = new ServletRegistrationBean<>(dispatcherServlet); + registration.addUrlMappings("/spring/*"); + return registration; + } + + @Bean + DispatcherServlet dispatcherServlet() { + // Can configure dispatcher servlet here as would usually do through + // init-params + return new DispatcherServlet(); + } + + @Bean + HelloWorldController helloWorldController() { + return new HelloWorldController(); + } + + } + + @Controller + static class HelloWorldController { + + @RequestMapping("/hello") + @ResponseBody + String sayHello() { + return "Hello World"; + } + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test-cert.pem b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test-cert.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test-cert.pem rename to spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test-cert.pem diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test-key.pem b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test-key.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/server/test-key.pem rename to spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test-key.pem diff --git a/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test.jks b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test.jks new file mode 100644 index 000000000000..74279d80fbac Binary files /dev/null and b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test.jks differ diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/server/test.p12 b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test.p12 similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/server/test.p12 rename to spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/reactive/test.p12 diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/server/test-cert.pem b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test-cert.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/server/test-cert.pem rename to spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test-cert.pem diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/server/test-key.pem b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test-key.pem similarity index 100% rename from spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/web/servlet/server/test-key.pem rename to spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test-key.pem diff --git a/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test.jks b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test.jks new file mode 100644 index 000000000000..74279d80fbac Binary files /dev/null and b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test.jks differ diff --git a/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test.p12 b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test.p12 new file mode 100644 index 000000000000..e1255f26f665 Binary files /dev/null and b/spring-boot-project/spring-boot-web-server/src/testFixtures/resources/org/springframework/boot/web/server/servlet/test.p12 differ diff --git a/spring-boot-project/spring-boot-webclient/build.gradle b/spring-boot-project/spring-boot-webclient/build.gradle new file mode 100644 index 000000000000..0def707066fb --- /dev/null +++ b/spring-boot-project/spring-boot-webclient/build.gradle @@ -0,0 +1,48 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot WebClient" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-http-client")) + api("org.springframework:spring-web") + + implementation(project(":spring-boot-project:spring-boot-http-codec")) + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-reactor-netty")) + optional("org.apache.httpcomponents.client5:httpclient5") + optional("org.apache.httpcomponents.core5:httpcore5-reactive") + optional("org.eclipse.jetty:jetty-reactive-httpclient") + optional("org.springframework:spring-webflux") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("io.micrometer:micrometer-observation-test") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/function/client/WebClientCustomizer.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/WebClientCustomizer.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/function/client/WebClientCustomizer.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/WebClientCustomizer.java index 96a6f9838932..6bf7adb06977 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/function/client/WebClientCustomizer.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/WebClientCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.function.client; +package org.springframework.boot.webclient; import org.springframework.web.reactive.function.client.WebClient; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/AutoConfiguredWebClientSsl.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/AutoConfiguredWebClientSsl.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/AutoConfiguredWebClientSsl.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/AutoConfiguredWebClientSsl.java index 6cfc14415391..01addca759f9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/AutoConfiguredWebClientSsl.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/AutoConfiguredWebClientSsl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.function.client; +package org.springframework.boot.webclient.autoconfigure; import java.util.function.Consumer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfiguration.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientAutoConfiguration.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfiguration.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientAutoConfiguration.java index 30ad8b62d50a..cf902189bf11 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.function.client; +package org.springframework.boot.webclient.autoconfigure; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -23,13 +23,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorAutoConfiguration; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; +import org.springframework.boot.http.client.autoconfigure.reactive.ClientHttpConnectorAutoConfiguration; import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; +import org.springframework.boot.http.codec.CodecCustomizer; +import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.codec.CodecCustomizer; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.boot.webclient.WebClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; @@ -48,9 +48,9 @@ * * @author Brian Clozel * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { CodecsAutoConfiguration.class, ClientHttpConnectorAutoConfiguration.class }) +@AutoConfiguration(after = { ClientHttpConnectorAutoConfiguration.class, CodecsAutoConfiguration.class }) @ConditionalOnClass(WebClient.class) public class WebClientAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientCodecCustomizer.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientCodecCustomizer.java similarity index 84% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientCodecCustomizer.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientCodecCustomizer.java index e725ceb865c8..dfedf81ef3b7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientCodecCustomizer.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientCodecCustomizer.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.function.client; +package org.springframework.boot.webclient.autoconfigure; import java.util.List; -import org.springframework.boot.web.codec.CodecCustomizer; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.boot.http.codec.CodecCustomizer; +import org.springframework.boot.webclient.WebClientCustomizer; import org.springframework.web.reactive.function.client.WebClient; /** * {@link WebClientCustomizer} that configures codecs for the HTTP client. * * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ public class WebClientCodecCustomizer implements WebClientCustomizer { diff --git a/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientObservationAutoConfiguration.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientObservationAutoConfiguration.java new file mode 100644 index 000000000000..5f950ebd19a3 --- /dev/null +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientObservationAutoConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webclient.autoconfigure; + +import io.micrometer.observation.ObservationRegistry; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.observation.autoconfigure.ObservationProperties; +import org.springframework.boot.webclient.observation.ObservationWebClientCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.web.reactive.function.client.ClientRequestObservationConvention; +import org.springframework.web.reactive.function.client.DefaultClientRequestObservationConvention; +import org.springframework.web.reactive.function.client.WebClient; + +/** + * Configure the instrumentation of {@link WebClient}. + * + * @author Brian Clozel + * @since 4.0.0 + */ +@AutoConfiguration(beforeName = "org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration") +@ConditionalOnClass({ WebClient.class, ObservationWebClientCustomizer.class, ObservationRegistry.class, + ObservationProperties.class }) +@EnableConfigurationProperties(ObservationProperties.class) +public class WebClientObservationAutoConfiguration { + + @Bean + ObservationWebClientCustomizer observationWebClientCustomizer(ObservationRegistry observationRegistry, + ObjectProvider customConvention, + ObservationProperties observationProperties) { + String name = observationProperties.getHttp().getClient().getRequests().getName(); + ClientRequestObservationConvention observationConvention = customConvention + .getIfAvailable(() -> new DefaultClientRequestObservationConvention(name)); + return new ObservationWebClientCustomizer(observationRegistry, observationConvention); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientSsl.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientSsl.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientSsl.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientSsl.java index daab430cf286..e33b54d56282 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientSsl.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/WebClientSsl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.function.client; +package org.springframework.boot.webclient.autoconfigure; import java.util.function.Consumer; @@ -38,7 +38,7 @@ * {@link WebClient.Builder#clientConnector configured} {@link ClientHttpConnector}. * * @author Phillip Webb - * @since 3.1.0 + * @since 4.0.0 */ public interface WebClientSsl { diff --git a/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/package-info.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/package-info.java new file mode 100644 index 000000000000..e02cfd7d466a --- /dev/null +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Framework's functional web client. + */ +package org.springframework.boot.webclient.autoconfigure; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/AbstractHttpReactiveClientServiceProperties.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/AbstractHttpReactiveClientServiceProperties.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/AbstractHttpReactiveClientServiceProperties.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/AbstractHttpReactiveClientServiceProperties.java index de2a182af874..3bc428552599 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/AbstractHttpReactiveClientServiceProperties.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/AbstractHttpReactiveClientServiceProperties.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive.service; +package org.springframework.boot.webclient.autoconfigure.service; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.springframework.boot.autoconfigure.http.client.reactive.AbstractClientHttpConnectorProperties; +import org.springframework.boot.http.client.autoconfigure.reactive.AbstractClientHttpConnectorProperties; /** * {@link AbstractClientHttpConnectorProperties} for reactive HTTP Service clients. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpClientServiceProperties.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpClientServiceProperties.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpClientServiceProperties.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpClientServiceProperties.java index 266e7cbd249e..2e5791d5dd86 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpClientServiceProperties.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpClientServiceProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive.service; +package org.springframework.boot.webclient.autoconfigure.service; import java.util.LinkedHashMap; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpServiceClientAutoConfiguration.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpServiceClientAutoConfiguration.java similarity index 89% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpServiceClientAutoConfiguration.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpServiceClientAutoConfiguration.java index e77fbba25583..10eb52c3559b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpServiceClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpServiceClientAutoConfiguration.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive.service; +package org.springframework.boot.webclient.autoconfigure.service; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorAutoConfiguration; -import org.springframework.boot.autoconfigure.http.client.reactive.HttpReactiveClientProperties; -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.http.client.autoconfigure.reactive.ClientHttpConnectorAutoConfiguration; +import org.springframework.boot.http.client.autoconfigure.reactive.HttpReactiveClientProperties; import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.boot.webclient.WebClientCustomizer; +import org.springframework.boot.webclient.autoconfigure.WebClientAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.web.reactive.function.client.support.WebClientAdapter; import org.springframework.web.service.registry.HttpServiceProxyRegistry; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/WebClientCustomizerHttpServiceGroupConfigurer.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/WebClientCustomizerHttpServiceGroupConfigurer.java similarity index 86% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/WebClientCustomizerHttpServiceGroupConfigurer.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/WebClientCustomizerHttpServiceGroupConfigurer.java index b5b3f3ef799f..032c94773dc1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/WebClientCustomizerHttpServiceGroupConfigurer.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/WebClientCustomizerHttpServiceGroupConfigurer.java @@ -14,11 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive.service; +package org.springframework.boot.webclient.autoconfigure.service; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.web.client.RestClientCustomizer; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.boot.webclient.WebClientCustomizer; import org.springframework.web.client.RestClient; import org.springframework.web.client.support.RestClientHttpServiceGroupConfigurer; import org.springframework.web.reactive.function.client.WebClient; @@ -27,7 +26,7 @@ /** * A {@link RestClientHttpServiceGroupConfigurer} to apply auto-configured - * {@link RestClientCustomizer} beans to the group's {@link RestClient}. + * {@link WebClientCustomizer} beans to the group's {@link RestClient}. * * @author Olga Maciaszek-Sharma * @author Phillip Webb diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/WebClientPropertiesHttpServiceGroupConfigurer.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/WebClientPropertiesHttpServiceGroupConfigurer.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/WebClientPropertiesHttpServiceGroupConfigurer.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/WebClientPropertiesHttpServiceGroupConfigurer.java index c1bfa53619c8..1081991cff94 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/client/reactive/service/WebClientPropertiesHttpServiceGroupConfigurer.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/WebClientPropertiesHttpServiceGroupConfigurer.java @@ -14,17 +14,16 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive.service; +package org.springframework.boot.webclient.autoconfigure.service; import java.util.List; import java.util.Map; import java.util.function.Consumer; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.http.client.HttpClientProperties; -import org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectors; -import org.springframework.boot.autoconfigure.http.client.reactive.HttpReactiveClientProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.http.client.autoconfigure.reactive.ClientHttpConnectors; +import org.springframework.boot.http.client.autoconfigure.reactive.HttpReactiveClientProperties; import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; import org.springframework.boot.ssl.SslBundles; @@ -39,7 +38,7 @@ /** * A {@link RestClientHttpServiceGroupConfigurer} that configures the group and its - * underlying {@link RestClient} using {@link HttpClientProperties}. + * underlying {@link RestClient} using {@link HttpReactiveClientProperties}. * * @author Olga Maciaszek-Sharma * @author Phillip Webb diff --git a/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/package-info.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/package-info.java new file mode 100644 index 000000000000..40a27e5241a0 --- /dev/null +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/autoconfigure/service/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-Configuration for Spring's Reactive HTTP Service Interface Clients. + */ +package org.springframework.boot.webclient.autoconfigure.service; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/ObservationWebClientCustomizer.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/observation/ObservationWebClientCustomizer.java similarity index 91% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/ObservationWebClientCustomizer.java rename to spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/observation/ObservationWebClientCustomizer.java index 7197e89c4bde..b8ed7a370149 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/ObservationWebClientCustomizer.java +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/observation/ObservationWebClientCustomizer.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.reactive.client; +package org.springframework.boot.webclient.observation; import io.micrometer.observation.ObservationRegistry; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.boot.webclient.WebClientCustomizer; import org.springframework.web.reactive.function.client.ClientRequestObservationConvention; import org.springframework.web.reactive.function.client.WebClient; @@ -27,7 +27,7 @@ * observations. * * @author Brian Clozel - * @since 3.0.0 + * @since 4.0.0 */ public class ObservationWebClientCustomizer implements WebClientCustomizer { diff --git a/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/observation/package-info.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/observation/package-info.java new file mode 100644 index 000000000000..da275c440ad1 --- /dev/null +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/observation/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Observation integration for WebClient. + */ +package org.springframework.boot.webclient.observation; diff --git a/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/package-info.java b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/package-info.java new file mode 100644 index 000000000000..813f14245f59 --- /dev/null +++ b/spring-boot-project/spring-boot-webclient/src/main/java/org/springframework/boot/webclient/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring WebFlux WebClient support abstractions. + */ +package org.springframework.boot.webclient; diff --git a/spring-boot-project/spring-boot-webclient/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-webclient/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..fabe2e8d2f2d --- /dev/null +++ b/spring-boot-project/spring-boot-webclient/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +org.springframework.boot.webclient.autoconfigure.WebClientAutoConfiguration +org.springframework.boot.webclient.autoconfigure.WebClientObservationAutoConfiguration +org.springframework.boot.webclient.autoconfigure.service.ReactiveHttpServiceClientAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/WebClientAutoConfigurationTests.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/WebClientAutoConfigurationTests.java index a11dcb70c354..0c6c819ba4d1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/WebClientAutoConfigurationTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.function.client; +package org.springframework.boot.webclient.autoconfigure; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration; +import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.web.codec.CodecCustomizer; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.boot.webclient.WebClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.codec.CodecConfigurer; @@ -42,7 +42,7 @@ class WebClientAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( - org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorAutoConfiguration.class, + org.springframework.boot.http.client.autoconfigure.reactive.ClientHttpConnectorAutoConfiguration.class, WebClientAutoConfiguration.class, SslAutoConfiguration.class)); @Test diff --git a/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/WebClientObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/WebClientObservationAutoConfigurationTests.java new file mode 100644 index 000000000000..6908e856581b --- /dev/null +++ b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/WebClientObservationAutoConfigurationTests.java @@ -0,0 +1,145 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webclient.autoconfigure; + +import java.time.Duration; + +import io.micrometer.common.KeyValues; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.Observation.Context; +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.tck.TestObservationRegistry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.webclient.observation.ObservationWebClientCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.client.reactive.ClientHttpConnector; +import org.springframework.mock.http.client.reactive.MockClientHttpResponse; +import org.springframework.web.reactive.function.client.ClientRequestObservationContext; +import org.springframework.web.reactive.function.client.DefaultClientRequestObservationConvention; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link WebClientObservationAutoConfiguration}. + * + * @author Brian Clozel + * @author Stephane Nicoll + */ +@ExtendWith(OutputCaptureExtension.class) +class WebClientObservationAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(ObservationRegistry.class, TestObservationRegistry::create) + .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class, WebClientAutoConfiguration.class)) + .withUserConfiguration(WebClientObservationAutoConfiguration.class); + + @Test + void contributesCustomizerBean() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ObservationWebClientCustomizer.class)); + } + + @Test + void webClientCreatedWithBuilderIsInstrumented() { + this.contextRunner.run((context) -> { + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + WebClient.Builder builder = context.getBean(WebClient.Builder.class); + validateWebClient(builder, registry); + }); + } + + @Test + void shouldUseCustomConventionIfAvailable() { + this.contextRunner.withUserConfiguration(CustomConvention.class).run((context) -> { + TestObservationRegistry registry = context.getBean(TestObservationRegistry.class); + WebClient.Builder builder = context.getBean(WebClient.Builder.class); + WebClient webClient = mockWebClient(builder); + assertThat(registry).doesNotHaveAnyObservation(); + webClient.get() + .uri("https://example.org/projects/{project}", "spring-boot") + .retrieve() + .toBodilessEntity() + .block(Duration.ofSeconds(30)); + assertThat(registry).hasObservationWithNameEqualTo("http.client.requests") + .that() + .hasLowCardinalityKeyValue("project", "spring-boot"); + }); + } + + private void validateWebClient(WebClient.Builder builder, TestObservationRegistry registry) { + WebClient webClient = mockWebClient(builder); + assertThat(registry).doesNotHaveAnyObservation(); + webClient.get() + .uri("https://example.org/projects/{project}", "spring-boot") + .retrieve() + .toBodilessEntity() + .block(Duration.ofSeconds(30)); + assertThat(registry).hasObservationWithNameEqualTo("http.client.requests") + .that() + .hasLowCardinalityKeyValue("uri", "/projects/{project}"); + } + + private WebClient mockWebClient(WebClient.Builder builder) { + ClientHttpConnector connector = mock(ClientHttpConnector.class); + given(connector.connect(any(), any(), any())).willReturn(Mono.just(new MockClientHttpResponse(HttpStatus.OK))); + return builder.clientConnector(connector).build(); + } + + @Configuration(proxyBeanMethods = false) + static class CustomConventionConfig { + + @Bean + CustomConvention customConvention() { + return new CustomConvention(); + } + + } + + static class CustomConvention extends DefaultClientRequestObservationConvention { + + @Override + public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) { + return super.getLowCardinalityKeyValues(context).and("project", "spring-boot"); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MetricsConfiguration { + + @Bean + MeterObservationHandler meterObservationHandler(MeterRegistry registry) { + return new DefaultMeterObservationHandler(registry); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpClientServicePropertiesTests.java b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpClientServicePropertiesTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpClientServicePropertiesTests.java rename to spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpClientServicePropertiesTests.java index d0b19b8b0b10..83d21deae72f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpClientServicePropertiesTests.java +++ b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpClientServicePropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive.service; +package org.springframework.boot.webclient.autoconfigure.service; import java.time.Duration; import java.util.List; @@ -22,10 +22,10 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.http.client.reactive.AbstractClientHttpConnectorProperties.Connector; -import org.springframework.boot.autoconfigure.http.client.reactive.service.ReactiveHttpClientServiceProperties.Group; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.autoconfigure.reactive.AbstractClientHttpConnectorProperties.Connector; +import org.springframework.boot.webclient.autoconfigure.service.ReactiveHttpClientServiceProperties.Group; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.mock.env.MockEnvironment; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpServiceClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpServiceClientAutoConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpServiceClientAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpServiceClientAutoConfigurationTests.java index b61673e4f50b..b7eba382559f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/client/reactive/service/ReactiveHttpServiceClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/autoconfigure/service/ReactiveHttpServiceClientAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.http.client.reactive.service; +package org.springframework.boot.webclient.autoconfigure.service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; @@ -28,14 +28,13 @@ import org.springframework.aop.Advisor; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.client.reactive.ClientHttpConnectorAutoConfiguration; -import org.springframework.boot.autoconfigure.http.client.service.HttpServiceClientAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.http.client.autoconfigure.reactive.ClientHttpConnectorAutoConfiguration; import org.springframework.boot.http.client.reactive.ClientHttpConnectorBuilder; import org.springframework.boot.http.client.reactive.ClientHttpConnectorSettings; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.boot.webclient.WebClientCustomizer; +import org.springframework.boot.webclient.autoconfigure.WebClientAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; @@ -59,9 +58,8 @@ class ReactiveHttpServiceClientAutoConfigurationTests { private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpServiceClientAutoConfiguration.class, - ReactiveHttpServiceClientAutoConfiguration.class, ClientHttpConnectorAutoConfiguration.class, - WebClientAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(ReactiveHttpServiceClientAutoConfiguration.class, + ClientHttpConnectorAutoConfiguration.class, WebClientAutoConfiguration.class)); @Test void configuresClientFromProperties() { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/ObservationWebClientCustomizerTests.java b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/observation/ObservationWebClientCustomizerTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/ObservationWebClientCustomizerTests.java rename to spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/observation/ObservationWebClientCustomizerTests.java index e010e059cced..2238ea091f19 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/ObservationWebClientCustomizerTests.java +++ b/spring-boot-project/spring-boot-webclient/src/test/java/org/springframework/boot/webclient/observation/ObservationWebClientCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.web.reactive.client; +package org.springframework.boot.webclient.observation; import io.micrometer.observation.tck.TestObservationRegistry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-webclient/src/test/resources/org/springframework/boot/http/client/reactive/test.jks b/spring-boot-project/spring-boot-webclient/src/test/resources/org/springframework/boot/http/client/reactive/test.jks new file mode 100644 index 000000000000..74279d80fbac Binary files /dev/null and b/spring-boot-project/spring-boot-webclient/src/test/resources/org/springframework/boot/http/client/reactive/test.jks differ diff --git a/spring-boot-project/spring-boot-webclient/src/test/resources/org/springframework/boot/http/client/reactive/web/autoconfigure/test.jks b/spring-boot-project/spring-boot-webclient/src/test/resources/org/springframework/boot/http/client/reactive/web/autoconfigure/test.jks new file mode 100644 index 000000000000..0fc3e802f754 Binary files /dev/null and b/spring-boot-project/spring-boot-webclient/src/test/resources/org/springframework/boot/http/client/reactive/web/autoconfigure/test.jks differ diff --git a/spring-boot-project/spring-boot-webflux/build.gradle b/spring-boot-project/spring-boot-webflux/build.gradle new file mode 100644 index 000000000000..c478672e7357 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/build.gradle @@ -0,0 +1,63 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "java-test-fixtures" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot WebFlux" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-webflux") + + implementation(project(":spring-boot-project:spring-boot-http-codec")) + implementation(project(":spring-boot-project:spring-boot-web-server")) + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-observation")) + optional(project(":spring-boot-project:spring-boot-validation")) + optional("com.fasterxml.jackson.core:jackson-databind") + optional("org.springframework.security:spring-security-core") + + testFixturesApi(testFixtures(project(":spring-boot-project:spring-boot-actuator"))) + testFixturesImplementation(project(":spring-boot-project:spring-boot-jackson")) + testFixturesImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) + + testImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-mustache")) + testImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation("io.projectreactor:reactor-test") + testImplementation("org.aspectj:aspectjweaver") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.fasterxml.jackson.core:jackson-databind") + testRuntimeOnly("jakarta.servlet:jakarta.servlet-api") +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMapping.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMapping.java index 7797afcea3a0..0667a3d0704a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; @@ -49,8 +49,8 @@ import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; -import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -85,7 +85,7 @@ * @author Phillip Webb * @author Brian Clozel * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(AbstractWebFluxEndpointHandlerMappingRuntimeHints.class) public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappingInfoHandlerMapping { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java index f1073d4c20ed..b0c743f01c13 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/AdditionalHealthEndpointPathsWebFluxHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import java.util.Collection; import java.util.Collections; @@ -36,7 +36,7 @@ * path. * * @author Madhura Bhave - * @since 2.6.0 + * @since 4.0.0 */ public class AdditionalHealthEndpointPathsWebFluxHandlerMapping extends AbstractWebFluxEndpointHandlerMapping { diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMapping.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMapping.java new file mode 100644 index 000000000000..9ff4429b697c --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMapping.java @@ -0,0 +1,164 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.actuate.endpoint.web; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.reactive.HandlerMapping; +import org.springframework.web.reactive.result.method.RequestMappingInfo; +import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; +import org.springframework.web.util.pattern.PathPattern; + +/** + * {@link HandlerMapping} that exposes + * {@link org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint @ControllerEndpoint} + * and + * {@link org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint @RestControllerEndpoint} + * annotated endpoints over Spring WebFlux. + * + * @author Phillip Webb + * @since 4.0.0 + * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support + */ +@Deprecated(since = "3.3.5", forRemoval = true) +@SuppressWarnings("removal") +public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMapping { + + private static final Set READ_ONLY_ACCESS_REQUEST_METHODS = EnumSet.of(RequestMethod.GET, + RequestMethod.HEAD); + + private final EndpointMapping endpointMapping; + + private final CorsConfiguration corsConfiguration; + + private final Map handlers; + + private final EndpointAccessResolver accessResolver; + + /** + * Create a new {@link ControllerEndpointHandlerMapping} instance providing mappings + * for the specified endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + */ + public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping, + Collection endpoints, CorsConfiguration corsConfiguration) { + this(endpointMapping, endpoints, corsConfiguration, (endpointId, defaultAccess) -> Access.NONE); + } + + /** + * Create a new {@link ControllerEndpointHandlerMapping} instance providing mappings + * for the specified endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param endpointAccessResolver resolver for endpoint access + */ + public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping, + Collection endpoints, CorsConfiguration corsConfiguration, + EndpointAccessResolver endpointAccessResolver) { + Assert.notNull(endpointMapping, "'endpointMapping' must not be null"); + Assert.notNull(endpoints, "'endpoints' must not be null"); + this.endpointMapping = endpointMapping; + this.handlers = getHandlers(endpoints); + this.corsConfiguration = corsConfiguration; + this.accessResolver = endpointAccessResolver; + setOrder(-100); + } + + private Map getHandlers(Collection endpoints) { + Map handlers = new LinkedHashMap<>(); + endpoints.forEach((endpoint) -> handlers.put(endpoint.getController(), endpoint)); + return Collections.unmodifiableMap(handlers); + } + + @Override + protected void initHandlerMethods() { + this.handlers.keySet().forEach(this::detectHandlerMethods); + } + + @Override + protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { + ExposableControllerEndpoint endpoint = this.handlers.get(handler); + Access access = this.accessResolver.accessFor(endpoint.getEndpointId(), endpoint.getDefaultAccess()); + if (access == Access.NONE) { + return; + } + if (access == Access.READ_ONLY) { + mapping = withReadOnlyAccess(access, mapping); + if (CollectionUtils.isEmpty(mapping.getMethodsCondition().getMethods())) { + return; + } + } + mapping = withEndpointMappedPatterns(endpoint, mapping); + super.registerHandlerMethod(handler, method, mapping); + } + + private RequestMappingInfo withReadOnlyAccess(Access access, RequestMappingInfo mapping) { + Set methods = new HashSet<>(mapping.getMethodsCondition().getMethods()); + if (methods.isEmpty()) { + methods.addAll(READ_ONLY_ACCESS_REQUEST_METHODS); + } + else { + methods.retainAll(READ_ONLY_ACCESS_REQUEST_METHODS); + } + return mapping.mutate().methods(methods.toArray(new RequestMethod[0])).build(); + } + + private RequestMappingInfo withEndpointMappedPatterns(ExposableControllerEndpoint endpoint, + RequestMappingInfo mapping) { + Set patterns = mapping.getPatternsCondition().getPatterns(); + if (patterns.isEmpty()) { + patterns = Collections.singleton(getPathPatternParser().parse("")); + } + String[] endpointMappedPatterns = patterns.stream() + .map((pattern) -> getEndpointMappedPattern(endpoint, pattern)) + .toArray(String[]::new); + return mapping.mutate().paths(endpointMappedPatterns).build(); + } + + private String getEndpointMappedPattern(ExposableControllerEndpoint endpoint, PathPattern pattern) { + return this.endpointMapping.createSubPath(endpoint.getRootPath() + pattern); + } + + @Override + protected boolean hasCorsConfigurationSource(Object handler) { + return this.corsConfiguration != null; + } + + @Override + protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mapping) { + return this.corsConfiguration; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMapping.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMapping.java index 9a2f3073972b..acdf3ea60a80 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import java.util.Collection; import java.util.Collections; @@ -32,7 +32,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; @@ -47,7 +47,7 @@ * @author Andy Wilkinson * @author Phillip Webb * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(WebFluxEndpointHandlerMappingRuntimeHints.class) public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandlerMapping implements InitializingBean { diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/package-info.java new file mode 100644 index 000000000000..800e879b1914 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/endpoint/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring WebFlux support for actuator endpoints. + */ +package org.springframework.boot.webflux.actuate.endpoint.web; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilter.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilter.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilter.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilter.java index f5b1603fddf1..1e402bc1acf8 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilter.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.exchanges; import java.security.Principal; import java.util.Set; @@ -35,7 +35,7 @@ * * @author Andy Wilkinson * @author Phillip Webb - * @since 3.0.0 + * @since 4.0.0 */ public class HttpExchangesWebFilter implements WebFilter, Ordered { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequest.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequest.java index 9adc7efa6798..63bdebff43de 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequest.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.exchanges; import java.net.InetAddress; import java.net.InetSocketAddress; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpResponse.java similarity index 96% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpResponse.java index cc93c8bc9602..dcca41210b6b 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpResponse.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.exchanges; import java.util.Collections; import java.util.LinkedHashMap; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/package-info.java new file mode 100644 index 000000000000..3175301f3b57 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/exchanges/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator HTTP exchanges support for reactive servers. + * + * @see org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository + */ +package org.springframework.boot.webflux.actuate.exchanges; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlerMappingDescription.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlerMappingDescription.java similarity index 85% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlerMappingDescription.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlerMappingDescription.java index 4619b05a5fc7..4b7ba4acedb0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlerMappingDescription.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlerMappingDescription.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.reactive; +package org.springframework.boot.webflux.actuate.mappings; -import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.reactive.DispatcherHandler; /** - * A description of a mapping known to a {@link DispatcherServlet}. + * A description of a mapping known to a {@link DispatcherHandler}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class DispatcherHandlerMappingDescription { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlerMappingDetails.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlerMappingDetails.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlerMappingDetails.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlerMappingDetails.java index 6e51d7475edd..9ea925e815c4 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlerMappingDetails.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlerMappingDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.reactive; +package org.springframework.boot.webflux.actuate.mappings; import org.springframework.boot.actuate.web.mappings.HandlerMethodDescription; import org.springframework.web.reactive.DispatcherHandler; @@ -23,7 +23,7 @@ * Details of a {@link DispatcherHandler} mapping. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class DispatcherHandlerMappingDetails { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProvider.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlersMappingDescriptionProvider.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProvider.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlersMappingDescriptionProvider.java index 24ef4f2a3829..72b22f97c138 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProvider.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlersMappingDescriptionProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.reactive; +package org.springframework.boot.webflux.actuate.mappings; import java.util.ArrayList; import java.util.Arrays; @@ -32,7 +32,7 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.web.mappings.HandlerMethodDescription; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.DispatcherHandlersMappingDescriptionProviderRuntimeHints; +import org.springframework.boot.webflux.actuate.mappings.DispatcherHandlersMappingDescriptionProvider.DispatcherHandlersMappingDescriptionProviderRuntimeHints; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.core.io.Resource; @@ -55,7 +55,7 @@ * HandlerMappings} that are known to a {@link DispatcherHandler}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(DispatcherHandlersMappingDescriptionProviderRuntimeHints.class) public class DispatcherHandlersMappingDescriptionProvider implements MappingDescriptionProvider { diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/HandlerFunctionDescription.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/HandlerFunctionDescription.java new file mode 100644 index 000000000000..1e0ab8d2bca0 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/HandlerFunctionDescription.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.actuate.mappings; + +import org.springframework.web.reactive.function.server.HandlerFunction; + +/** + * Description of a {@link HandlerFunction}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class HandlerFunctionDescription { + + private final String className; + + HandlerFunctionDescription(HandlerFunction handlerFunction) { + this.className = getHandlerFunctionClassName(handlerFunction); + } + + private static String getHandlerFunctionClassName(HandlerFunction handlerFunction) { + Class functionClass = handlerFunction.getClass(); + String canonicalName = functionClass.getCanonicalName(); + return (canonicalName != null) ? canonicalName : functionClass.getName(); + } + + public String getClassName() { + return this.className; + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/RequestMappingConditionsDescription.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/RequestMappingConditionsDescription.java new file mode 100644 index 000000000000..0446896bfd3b --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/RequestMappingConditionsDescription.java @@ -0,0 +1,158 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.actuate.mappings; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.reactive.result.condition.MediaTypeExpression; +import org.springframework.web.reactive.result.condition.NameValueExpression; +import org.springframework.web.reactive.result.method.RequestMappingInfo; +import org.springframework.web.util.pattern.PathPattern; + +/** + * Description of the conditions of a {@link RequestMappingInfo}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class RequestMappingConditionsDescription { + + private final List consumes; + + private final List headers; + + private final Set methods; + + private final List params; + + private final Set patterns; + + private final List produces; + + RequestMappingConditionsDescription(RequestMappingInfo requestMapping) { + this.consumes = requestMapping.getConsumesCondition() + .getExpressions() + .stream() + .map(MediaTypeExpressionDescription::new) + .toList(); + this.headers = requestMapping.getHeadersCondition() + .getExpressions() + .stream() + .map(NameValueExpressionDescription::new) + .toList(); + this.methods = requestMapping.getMethodsCondition().getMethods(); + this.params = requestMapping.getParamsCondition() + .getExpressions() + .stream() + .map(NameValueExpressionDescription::new) + .toList(); + this.patterns = requestMapping.getPatternsCondition() + .getPatterns() + .stream() + .map(PathPattern::getPatternString) + .collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet)); + this.produces = requestMapping.getProducesCondition() + .getExpressions() + .stream() + .map(MediaTypeExpressionDescription::new) + .toList(); + } + + public List getConsumes() { + return this.consumes; + } + + public List getHeaders() { + return this.headers; + } + + public Set getMethods() { + return this.methods; + } + + public List getParams() { + return this.params; + } + + public Set getPatterns() { + return this.patterns; + } + + public List getProduces() { + return this.produces; + } + + /** + * A description of a {@link MediaTypeExpression} in a request mapping condition. + */ + public static class MediaTypeExpressionDescription { + + private final String mediaType; + + private final boolean negated; + + MediaTypeExpressionDescription(MediaTypeExpression expression) { + this.mediaType = expression.getMediaType().toString(); + this.negated = expression.isNegated(); + } + + public String getMediaType() { + return this.mediaType; + } + + public boolean isNegated() { + return this.negated; + } + + } + + /** + * A description of a {@link NameValueExpression} in a request mapping condition. + */ + public static class NameValueExpressionDescription { + + private final String name; + + private final Object value; + + private final boolean negated; + + NameValueExpressionDescription(NameValueExpression expression) { + this.name = expression.getName(); + this.value = expression.getValue(); + this.negated = expression.isNegated(); + } + + public String getName() { + return this.name; + } + + public Object getValue() { + return this.value; + } + + public boolean isNegated() { + return this.negated; + } + + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/package-info.java new file mode 100644 index 000000000000..69daa3cbc8e6 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/actuate/mappings/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator reactive request mappings support. + */ +package org.springframework.boot.webflux.actuate.mappings; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfiguration.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfiguration.java index 6a65592624af..200ace48ee6c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.util.Collections; import java.util.Map; @@ -42,7 +42,7 @@ * @author Brian Clozel * @author Stephane Nicoll * @author Lasse Wulff - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(after = { WebFluxAutoConfiguration.class }) @ConditionalOnClass({ DispatcherHandler.class, HttpHandler.class }) diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ProblemDetailsExceptionHandler.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ProblemDetailsExceptionHandler.java new file mode 100644 index 000000000000..de3859951d1b --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ProblemDetailsExceptionHandler.java @@ -0,0 +1,31 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.reactive.result.method.annotation.ResponseEntityExceptionHandler; + +/** + * {@code @ControllerAdvice} annotated {@link ResponseEntityExceptionHandler} that is + * auto-configured for problem details support. + * + * @author Brian Clozel + */ +@ControllerAdvice +class ProblemDetailsExceptionHandler extends ResponseEntityExceptionHandler { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartAutoConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartAutoConfiguration.java index 1ae58ee1e0a2..650372d58f95 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.io.IOException; import java.nio.file.Path; @@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.codec.CodecCustomizer; +import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader; @@ -41,7 +41,7 @@ * * @author Chris Bono * @author Brian Clozel - * @since 2.6.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnClass({ DefaultPartHttpMessageReader.class, WebFluxConfigurer.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartProperties.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartProperties.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartProperties.java index b9ab5c5649a2..57b90b83df7a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartProperties.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -30,7 +30,7 @@ * and the {@link PartEventHttpMessageReader}. * * @author Chris Bono - * @since 2.6.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.webflux.multipart") public class ReactiveMultipartProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ResourceChainResourceHandlerRegistrationCustomizer.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ResourceChainResourceHandlerRegistrationCustomizer.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ResourceChainResourceHandlerRegistrationCustomizer.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ResourceChainResourceHandlerRegistrationCustomizer.java index 54ddacfcbb31..397f0f654ca6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ResourceChainResourceHandlerRegistrationCustomizer.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ResourceChainResourceHandlerRegistrationCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import org.springframework.boot.autoconfigure.web.WebProperties.Resources; import org.springframework.web.reactive.config.ResourceChainRegistration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ResourceHandlerRegistrationCustomizer.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ResourceHandlerRegistrationCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ResourceHandlerRegistrationCustomizer.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ResourceHandlerRegistrationCustomizer.java index 5b93ee389715..d4d8e1c2175b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ResourceHandlerRegistrationCustomizer.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/ResourceHandlerRegistrationCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import org.springframework.web.reactive.config.ResourceHandlerRegistration; @@ -22,7 +22,7 @@ * Callback interface that can be used to customize {@link ResourceHandlerRegistration}. * * @author Brian Clozel - * @since 2.1.0 + * @since 4.0.0 */ @FunctionalInterface public interface ResourceHandlerRegistrationCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxAutoConfiguration.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxAutoConfiguration.java index d4f932fb00ed..209e237b1b08 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.time.Duration; import java.util.List; @@ -32,24 +32,23 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; import org.springframework.boot.autoconfigure.thread.Threading; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; -import org.springframework.boot.autoconfigure.validation.ValidatorAdapter; import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.autoconfigure.web.WebProperties.Resources; import org.springframework.boot.autoconfigure.web.WebResourcesRuntimeHints; import org.springframework.boot.autoconfigure.web.format.DateTimeFormatters; import org.springframework.boot.autoconfigure.web.format.WebConversionService; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties.Format; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.convert.ApplicationConversionService; -import org.springframework.boot.web.codec.CodecCustomizer; -import org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter; +import org.springframework.boot.http.codec.CodecCustomizer; +import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; +import org.springframework.boot.validation.autoconfigure.ValidatorAdapter; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webflux.autoconfigure.WebFluxProperties.Format; +import org.springframework.boot.webflux.filter.OrderedHiddenHttpMethodFilter; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -104,11 +103,12 @@ * @author Artsiom Yudovin * @author Chris Bono * @author Weix Sun - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { ReactiveWebServerFactoryAutoConfiguration.class, CodecsAutoConfiguration.class, - ReactiveMultipartAutoConfiguration.class, ValidationAutoConfiguration.class, - WebSessionIdResolverAutoConfiguration.class }) +@AutoConfiguration( + after = { ReactiveMultipartAutoConfiguration.class, WebSessionIdResolverAutoConfiguration.class, + CodecsAutoConfiguration.class }, + afterName = "org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) @ConditionalOnClass(WebFluxConfigurer.class) @ConditionalOnMissingBean({ WebFluxConfigurationSupport.class }) @@ -291,7 +291,9 @@ public FormattingConversionService webFluxConversionService() { @Bean @Override public Validator webFluxValidator() { - if (!ClassUtils.isPresent("jakarta.validation.Validator", getClass().getClassLoader())) { + if (!ClassUtils.isPresent("jakarta.validation.Validator", getClass().getClassLoader()) + || !ClassUtils.isPresent("org.springframework.boot.validation.autoconfigure.ValidatorAdapter", + getClass().getClassLoader())) { return super.webFluxValidator(); } return ValidatorAdapter.get(getApplicationContext(), getValidator()); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxObservationAutoConfiguration.java similarity index 82% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxObservationAutoConfiguration.java index 00d85cd962e8..052b72f30be4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxObservationAutoConfiguration.java @@ -14,18 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; -import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -33,6 +28,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.OnlyOnceLoggingDenyMeterFilter; +import org.springframework.boot.metrics.autoconfigure.MetricsProperties; +import org.springframework.boot.observation.autoconfigure.ObservationProperties; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention; @@ -46,9 +44,11 @@ * @author Jon Schneider * @author Dmytro Nosan * @author Moritz Halbritter - * @since 3.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { SimpleMetricsExportAutoConfiguration.class, ObservationAutoConfiguration.class }) +@AutoConfiguration(afterName = { + "org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration", + "org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration" }) @ConditionalOnClass({ Observation.class, MeterRegistry.class }) @ConditionalOnBean({ ObservationRegistry.class, MeterRegistry.class }) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxProperties.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxProperties.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxProperties.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxProperties.java index ea738fdc9130..640339f9db27 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxProperties.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.StringUtils; @@ -24,7 +24,7 @@ * * @author Brian Clozel * @author Vedran Pavic - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.webflux") public class WebFluxProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxRegistrations.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxRegistrations.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxRegistrations.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxRegistrations.java index 2ed1d6afb878..257bb59d330a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxRegistrations.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxRegistrations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; @@ -28,8 +28,8 @@ * to choose from redundant WebFlux components. * * @author Artsiom Yudovin - * @since 2.1.0 - * @see org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration.EnableWebFluxConfiguration + * @since 4.0.0 + * @see org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration.EnableWebFluxConfiguration */ public interface WebFluxRegistrations { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebHttpHandlerBuilderCustomizer.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebHttpHandlerBuilderCustomizer.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebHttpHandlerBuilderCustomizer.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebHttpHandlerBuilderCustomizer.java index d96839342626..119cf6323400 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebHttpHandlerBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebHttpHandlerBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; @@ -22,7 +22,7 @@ * Callback interface used to customize a {@link WebHttpHandlerBuilder}. * * @author Lasse Wulff - * @since 3.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface WebHttpHandlerBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebSessionIdResolverAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebSessionIdResolverAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebSessionIdResolverAutoConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebSessionIdResolverAutoConfiguration.java index a42eb48e80a4..4326c9fd579c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebSessionIdResolverAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebSessionIdResolverAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import reactor.core.publisher.Mono; @@ -23,11 +23,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.web.server.Cookie; import org.springframework.boot.web.server.Cookie.SameSite; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.context.annotation.Bean; import org.springframework.http.ResponseCookie.ResponseCookieBuilder; import org.springframework.util.StringUtils; @@ -41,7 +41,7 @@ * @author Phillip Webb * @author Brian Clozel * @author Weix Sun - * @since 2.6.0 + * @since 4.0.0 */ @AutoConfiguration @ConditionalOnWebApplication(type = Type.REACTIVE) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WelcomePageRouterFunctionFactory.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WelcomePageRouterFunctionFactory.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WelcomePageRouterFunctionFactory.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WelcomePageRouterFunctionFactory.java index 43acd9405ec0..458ceeecb5e3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WelcomePageRouterFunctionFactory.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WelcomePageRouterFunctionFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.util.Arrays; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointExtensionAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointExtensionAutoConfiguration.java new file mode 100644 index 000000000000..6e3d185a5471 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointExtensionAutoConfiguration.java @@ -0,0 +1,65 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web; + +import java.util.Collection; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; +import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; +import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.HealthEndpointGroups; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.webflux.actuate.endpoint.web.AdditionalHealthEndpointPathsWebFluxHandlerMapping; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for {@link HealthEndpoint} web + * extension with Spring WebFlux. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnClass({ HealthEndpoint.class, Health.class }) +@ConditionalOnBean({ WebEndpointsSupplier.class, HealthEndpointGroups.class }) +@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB) +public class WebFluxHealthEndpointExtensionAutoConfiguration { + + @Bean + AdditionalHealthEndpointPathsWebFluxHandlerMapping healthEndpointWebFluxHandlerMapping( + WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) { + Collection webEndpoints = webEndpointsSupplier.getEndpoints(); + ExposableWebEndpoint health = webEndpoints.stream() + .filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)) + .findFirst() + .orElse(null); + return new AdditionalHealthEndpointPathsWebFluxHandlerMapping(new EndpointMapping(""), health, + groups.getAllWithAdditionalPath(WebServerNamespace.SERVER)); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/package-info.java new file mode 100644 index 000000000000..ffbe43f225cb --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring WebFlux actuator web endpoint support. + */ +package org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointManagementContextConfiguration.java similarity index 90% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointManagementContextConfiguration.java index 60f9bb55df13..263dacf2cc97 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/reactive/WebFluxEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointManagementContextConfiguration.java @@ -14,13 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive; +package org.springframework.boot.webflux.autoconfigure.actuate.web; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.function.Supplier; import com.fasterxml.jackson.databind.ObjectMapper; @@ -47,8 +48,6 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.endpoint.web.reactive.AdditionalHealthEndpointPathsWebFluxHandlerMapping; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -57,6 +56,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.webflux.actuate.endpoint.web.AdditionalHealthEndpointPathsWebFluxHandlerMapping; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Role; import org.springframework.core.codec.Encoder; @@ -66,6 +67,7 @@ import org.springframework.http.codec.HttpMessageWriter; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.util.MimeType; import org.springframework.util.StringUtils; import org.springframework.util.function.SingletonSupplier; import org.springframework.web.reactive.DispatcherHandler; @@ -76,7 +78,7 @@ * * @author Andy Wilkinson * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ @ManagementContextConfiguration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = Type.REACTIVE) @@ -128,12 +130,12 @@ public AdditionalHealthEndpointPathsWebFluxHandlerMapping managementHealthEndpoi @ConditionalOnMissingBean @SuppressWarnings("removal") @Deprecated(since = "3.3.5", forRemoval = true) - public org.springframework.boot.actuate.endpoint.web.reactive.ControllerEndpointHandlerMapping controllerEndpointHandlerMapping( + public org.springframework.boot.webflux.actuate.endpoint.web.ControllerEndpointHandlerMapping controllerEndpointHandlerMapping( org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier controllerEndpointsSupplier, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, EndpointAccessResolver endpointAccessResolver) { EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath()); - return new org.springframework.boot.actuate.endpoint.web.reactive.ControllerEndpointHandlerMapping( + return new org.springframework.boot.webflux.actuate.endpoint.web.ControllerEndpointHandlerMapping( endpointMapping, controllerEndpointsSupplier.getEndpoints(), corsProperties.toCorsConfiguration(), endpointAccessResolver); } @@ -183,13 +185,18 @@ private void process(ServerCodecConfigurer configurer) { @SuppressWarnings({ "removal", "deprecation" }) private void process(Encoder encoder) { if (encoder instanceof org.springframework.http.codec.json.Jackson2JsonEncoder jackson2JsonEncoder) { - jackson2JsonEncoder.registerObjectMappersForType(OperationResponseBody.class, (associations) -> { - ObjectMapper objectMapper = this.endpointObjectMapper.get().get(); - MEDIA_TYPES.forEach((mimeType) -> associations.put(mimeType, objectMapper)); - }); + this.endpointObjectMapper.get() + .getSupportedTypes() + .forEach((type) -> jackson2JsonEncoder.registerObjectMappersForType(type, + this::registerForAllMimeTypes)); } } + private void registerForAllMimeTypes(Map registrar) { + ObjectMapper objectMapper = this.endpointObjectMapper.get().get(); + MEDIA_TYPES.forEach((mimeType) -> registrar.put(mimeType, objectMapper)); + } + } } diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxHttpExchangesAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxHttpExchangesAutoConfiguration.java new file mode 100644 index 000000000000..27bebdf33168 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxHttpExchangesAutoConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesProperties; +import org.springframework.boot.actuate.web.exchanges.HttpExchange; +import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.webflux.actuate.exchanges.HttpExchangesWebFilter; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} to record {@link HttpExchange HTTP + * exchanges}. + * + * @author Dave Syer + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnBooleanProperty(name = "management.httpexchanges.recording.enabled", matchIfMissing = true) +@ConditionalOnBean(HttpExchangeRepository.class) +@EnableConfigurationProperties(HttpExchangesProperties.class) +public class WebFluxHttpExchangesAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + HttpExchangesWebFilter httpExchangesWebFilter(HttpExchangeRepository repository, + HttpExchangesProperties properties) { + return new HttpExchangesWebFilter(repository, properties.getRecording().getInclude()); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfiguration.java new file mode 100644 index 000000000000..e36f2ed4eac3 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfiguration.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import java.util.Collections; +import java.util.Map; + +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementWebServerFactoryCustomizer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.web.server.ConfigurableWebServerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.http.server.reactive.ContextPathCompositeHandler; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.util.StringUtils; +import org.springframework.web.reactive.DispatcherHandler; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + +/** + * {@link ManagementContextConfiguration @ManagementContextConfiguration} for reactive web + * infrastructure when a separate management context with a web server running on a + * different port is required. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @author Moritz Halbritter + */ +@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnClass(DispatcherHandler.class) +@EnableWebFlux +class WebFluxManagementChildContextConfiguration { + + @Bean + ManagementWebServerFactoryCustomizer reactiveManagementWebServerFactoryCustomizer( + ListableBeanFactory beanFactory) { + return new ManagementWebServerFactoryCustomizer<>(beanFactory); + } + + @Bean + HttpHandler httpHandler(ApplicationContext applicationContext, ManagementServerProperties properties) { + HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build(); + if (StringUtils.hasText(properties.getBasePath())) { + Map handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler); + return new ContextPathCompositeHandler(handlersMap); + } + return httpHandler; + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxMappingsAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxMappingsAutoConfiguration.java new file mode 100644 index 000000000000..beca2d6136cb --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxMappingsAutoConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; +import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.webflux.actuate.mappings.DispatcherHandlersMappingDescriptionProvider; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.web.reactive.DispatcherHandler; + +/** + * {@link EnableAutoConfiguration Auto-configuration} to {@link MappingDescriptionProvider + * describe} WebFlux mappings. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration(after = WebFluxAutoConfiguration.class) +@ConditionalOnClass({ ConditionalOnAvailableEndpoint.class, DispatcherHandler.class, MappingsEndpoint.class }) +@ConditionalOnAvailableEndpoint(MappingsEndpoint.class) +@ConditionalOnBean(DispatcherHandler.class) +@ConditionalOnWebApplication(type = Type.REACTIVE) +public class WebFluxMappingsAutoConfiguration { + + @Bean + DispatcherHandlersMappingDescriptionProvider dispatcherHandlersMappingDescriptionProvider() { + return new DispatcherHandlersMappingDescriptionProvider(); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/package-info.java new file mode 100644 index 000000000000..80a78d66341a --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/actuate/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for WebFlux-based actuator web concerns. + */ +package org.springframework.boot.webflux.autoconfigure.actuate.web; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/AbstractErrorWebExceptionHandler.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/AbstractErrorWebExceptionHandler.java index 08892762e985..27c013816d33 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/AbstractErrorWebExceptionHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.error; +package org.springframework.boot.webflux.autoconfigure.error; import java.util.Collections; import java.util.Date; @@ -28,8 +28,8 @@ import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; import org.springframework.boot.autoconfigure.web.WebProperties.Resources; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.reactive.error.ErrorAttributes; -import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.boot.webflux.error.ErrorAttributes; +import org.springframework.boot.webflux.error.ErrorWebExceptionHandler; import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; import org.springframework.core.log.LogMessage; @@ -55,7 +55,7 @@ * @author Brian Clozel * @author Scott Frederick * @author Moritz Halbritter - * @since 2.0.0 + * @since 4.0.0 * @see ErrorAttributes */ public abstract class AbstractErrorWebExceptionHandler implements ErrorWebExceptionHandler, InitializingBean { @@ -81,7 +81,6 @@ public abstract class AbstractErrorWebExceptionHandler implements ErrorWebExcept * @param errorAttributes the error attributes * @param resources the resources configuration properties * @param applicationContext the application context - * @since 2.4.0 */ public AbstractErrorWebExceptionHandler(ErrorAttributes errorAttributes, Resources resources, ApplicationContext applicationContext) { @@ -174,7 +173,6 @@ protected boolean isBindingErrorsEnabled(ServerRequest request) { * @param request the source request * @return {@code true} if the path attribute has been requested, {@code false} * otherwise - * @since 3.3.0 */ protected boolean isPathEnabled(ServerRequest request) { return getBooleanParameter(request, "path"); @@ -312,7 +310,6 @@ private boolean isDisconnectedClientError(Throwable ex) { * @param request the request that was being handled * @param response the response that was being sent * @param throwable the error to be logged - * @since 2.2.0 */ protected void logError(ServerRequest request, ServerResponse response, Throwable throwable) { if (logger.isDebugEnabled()) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandler.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandler.java index 32477f2b7bef..6cc90dffaefb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.error; +package org.springframework.boot.webflux.autoconfigure.error; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -30,8 +30,8 @@ import org.springframework.boot.autoconfigure.web.WebProperties.Resources; import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; -import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.boot.webflux.error.DefaultErrorAttributes; +import org.springframework.boot.webflux.error.ErrorAttributes; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.http.InvalidMediaTypeException; @@ -78,7 +78,7 @@ * @author Brian Clozel * @author Scott Frederick * @author Moritz Halbritter - * @since 2.0.0 + * @since 4.0.0 */ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { @@ -105,7 +105,6 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa * @param resources the resources configuration properties * @param errorProperties the error configuration properties * @param applicationContext the current application context - * @since 2.4.0 */ public DefaultErrorWebExceptionHandler(ErrorAttributes errorAttributes, Resources resources, ErrorProperties errorProperties, ApplicationContext applicationContext) { @@ -227,7 +226,6 @@ protected boolean isIncludeBindingErrors(ServerRequest request, MediaType produc * @param request the source request * @param produces the media type produced (or {@code MediaType.ALL}) * @return if the path attribute should be included - * @since 3.3.0 */ protected boolean isIncludePath(ServerRequest request, MediaType produces) { return switch (this.errorProperties.getIncludePath()) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/ErrorWebFluxAutoConfiguration.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/ErrorWebFluxAutoConfiguration.java similarity index 85% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/ErrorWebFluxAutoConfiguration.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/ErrorWebFluxAutoConfiguration.java index 3505bedde729..0c3dd28267ca 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/ErrorWebFluxAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/ErrorWebFluxAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.error; +package org.springframework.boot.webflux.autoconfigure.error; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -23,13 +23,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.SearchStrategy; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.WebProperties; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; -import org.springframework.boot.web.reactive.error.ErrorAttributes; -import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.boot.webflux.error.DefaultErrorAttributes; +import org.springframework.boot.webflux.error.ErrorAttributes; +import org.springframework.boot.webflux.error.ErrorWebExceptionHandler; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; @@ -43,7 +43,7 @@ * * @author Brian Clozel * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfiguration(before = WebFluxAutoConfiguration.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) @@ -58,7 +58,7 @@ public ErrorWebFluxAutoConfiguration(ServerProperties serverProperties) { } @Bean - @ConditionalOnMissingBean(value = ErrorWebExceptionHandler.class, search = SearchStrategy.CURRENT) + @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) @Order(-1) public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes, WebProperties webProperties, ObjectProvider viewResolvers, diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/package-info.java new file mode 100644 index 000000000000..62ff790caa31 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/error/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring WebFlux error handling. + */ +package org.springframework.boot.webflux.autoconfigure.error; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/package-info.java new file mode 100644 index 000000000000..c32423bbd6fe --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for reactive web servers and Spring WebFlux. + */ +package org.springframework.boot.webflux.autoconfigure; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/DefaultErrorAttributes.java new file mode 100644 index 000000000000..b43349895c31 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/DefaultErrorAttributes.java @@ -0,0 +1,160 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.error; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; + +import org.springframework.boot.web.error.Error; +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.error.ErrorAttributeOptions.Include; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; +import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; +import org.springframework.http.HttpStatus; +import org.springframework.util.StringUtils; +import org.springframework.validation.BindingResult; +import org.springframework.validation.method.MethodValidationResult; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.web.server.ServerWebExchange; + +/** + * Default implementation of {@link ErrorAttributes}. Provides the following attributes + * when possible: + *

      + *
    • timestamp - The time that the errors were extracted
    • + *
    • status - The status code
    • + *
    • error - The error reason
    • + *
    • exception - The class name of the root exception (if configured)
    • + *
    • message - The exception message (if configured)
    • + *
    • errors - Any validation errors wrapped in {@link Error}, derived from a + * {@link BindingResult} or {@link MethodValidationResult} exception (if configured)
    • + *
    • trace - The exception stack trace (if configured)
    • + *
    • path - The URL path when the exception was raised
    • + *
    • requestId - Unique ID associated with the current request
    • + *
    + * + * @author Brian Clozel + * @author Stephane Nicoll + * @author Michele Mancioppi + * @author Scott Frederick + * @author Moritz Halbritter + * @author Yanming Zhou + * @author Yongjun Hong + * @since 4.0.0 + * @see ErrorAttributes + */ +public class DefaultErrorAttributes implements ErrorAttributes { + + private static final String ERROR_INTERNAL_ATTRIBUTE = DefaultErrorAttributes.class.getName() + ".ERROR"; + + @Override + public Map getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { + Map errorAttributes = getErrorAttributes(request, options.isIncluded(Include.STACK_TRACE)); + options.retainIncluded(errorAttributes); + return errorAttributes; + } + + private Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) { + Map errorAttributes = new LinkedHashMap<>(); + errorAttributes.put("timestamp", new Date()); + errorAttributes.put("path", request.requestPath().value()); + Throwable error = getError(request); + MergedAnnotation responseStatusAnnotation = MergedAnnotations + .from(error.getClass(), SearchStrategy.TYPE_HIERARCHY) + .get(ResponseStatus.class); + HttpStatus errorStatus = determineHttpStatus(error, responseStatusAnnotation); + errorAttributes.put("status", errorStatus.value()); + errorAttributes.put("error", errorStatus.getReasonPhrase()); + errorAttributes.put("requestId", request.exchange().getRequest().getId()); + handleException(errorAttributes, error, responseStatusAnnotation, includeStackTrace); + return errorAttributes; + } + + private HttpStatus determineHttpStatus(Throwable error, MergedAnnotation responseStatusAnnotation) { + if (error instanceof ResponseStatusException responseStatusException) { + HttpStatus httpStatus = HttpStatus.resolve(responseStatusException.getStatusCode().value()); + if (httpStatus != null) { + return httpStatus; + } + } + return responseStatusAnnotation.getValue("code", HttpStatus.class).orElse(HttpStatus.INTERNAL_SERVER_ERROR); + } + + private void addStackTrace(Map errorAttributes, Throwable error) { + StringWriter stackTrace = new StringWriter(); + error.printStackTrace(new PrintWriter(stackTrace)); + stackTrace.flush(); + errorAttributes.put("trace", stackTrace.toString()); + } + + private void handleException(Map errorAttributes, Throwable error, + MergedAnnotation responseStatusAnnotation, boolean includeStackTrace) { + Throwable exception; + if (error instanceof BindingResult bindingResult) { + exception = error; + errorAttributes.put("message", error.getMessage()); + errorAttributes.put("errors", Error.wrap(bindingResult.getAllErrors())); + } + else if (error instanceof MethodValidationResult methodValidationResult) { + exception = error; + errorAttributes.put("message", getErrorMessage(methodValidationResult)); + errorAttributes.put("errors", Error.wrap(methodValidationResult.getAllErrors())); + } + else if (error instanceof ResponseStatusException responseStatusException) { + exception = (responseStatusException.getCause() != null) ? responseStatusException.getCause() : error; + errorAttributes.put("message", responseStatusException.getReason()); + if (exception instanceof BindingResult bindingResult) { + errorAttributes.put("errors", Error.wrap(bindingResult.getAllErrors())); + } + } + else { + exception = error; + String reason = responseStatusAnnotation.getValue("reason", String.class).orElse(""); + String message = StringUtils.hasText(reason) ? reason : error.getMessage(); + errorAttributes.put("message", (message != null) ? message : ""); + } + errorAttributes.put("exception", exception.getClass().getName()); + if (includeStackTrace) { + addStackTrace(errorAttributes, exception); + } + } + + private String getErrorMessage(MethodValidationResult methodValidationResult) { + return "Validation failed for method='%s'. Error count: %s".formatted(methodValidationResult.getMethod(), + methodValidationResult.getAllErrors().size()); + } + + @Override + public Throwable getError(ServerRequest request) { + Optional error = request.attribute(ERROR_INTERNAL_ATTRIBUTE); + return (Throwable) error + .orElseThrow(() -> new IllegalStateException("Missing exception attribute in ServerWebExchange")); + } + + @Override + public void storeErrorInformation(Throwable error, ServerWebExchange exchange) { + exchange.getAttributes().putIfAbsent(ERROR_INTERNAL_ATTRIBUTE, error); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/ErrorAttributes.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/ErrorAttributes.java new file mode 100644 index 000000000000..effa46f8e8b1 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/ErrorAttributes.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.error; + +import java.util.Collections; +import java.util.Map; + +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.ServerWebExchange; + +/** + * Provides access to error attributes which can be logged or presented to the user. + * + * @author Brian Clozel + * @author Scott Frederick + * @since 4.0.0 + * @see DefaultErrorAttributes + */ +public interface ErrorAttributes { + + /** + * Return a {@link Map} of the error attributes. The map can be used as the model of + * an error page, or returned as a {@link ServerResponse} body. + * @param request the source request + * @param options options for error attribute contents + * @return a map of error attributes + */ + default Map getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { + return Collections.emptyMap(); + } + + /** + * Return the underlying cause of the error or {@code null} if the error cannot be + * extracted. + * @param request the source ServerRequest + * @return the {@link Exception} that caused the error or {@code null} + */ + Throwable getError(ServerRequest request); + + /** + * Store the given error information in the current {@link ServerWebExchange}. + * @param error the {@link Exception} that caused the error + * @param exchange the source exchange + */ + void storeErrorInformation(Throwable error, ServerWebExchange exchange); + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorWebExceptionHandler.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/ErrorWebExceptionHandler.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorWebExceptionHandler.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/ErrorWebExceptionHandler.java index 4a17baabd6ed..87d9da083c62 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/ErrorWebExceptionHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.error; +package org.springframework.boot.webflux.error; import org.springframework.web.server.WebExceptionHandler; @@ -23,7 +23,7 @@ * errors. * * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface ErrorWebExceptionHandler extends WebExceptionHandler { diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/package-info.java new file mode 100644 index 000000000000..0a1dd17f0253 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/error/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring WebFlux error handling infrastructure. + */ +package org.springframework.boot.webflux.error; diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/OrderedHiddenHttpMethodFilter.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/OrderedHiddenHttpMethodFilter.java new file mode 100644 index 000000000000..fea7d5cb0031 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/OrderedHiddenHttpMethodFilter.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.filter; + +import org.springframework.core.Ordered; +import org.springframework.web.filter.reactive.HiddenHttpMethodFilter; + +/** + * {@link HiddenHttpMethodFilter} that also implements {@link Ordered}. + * + * @author Artsiom Yudovin + * @since 4.0.0 + */ +public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter implements OrderedWebFilter { + + /** + * The default order is high to ensure the filter is applied before Spring Security. + */ + public static final int DEFAULT_ORDER = REQUEST_WRAPPER_FILTER_MAX_ORDER - 10000; + + private int order = DEFAULT_ORDER; + + @Override + public int getOrder() { + return this.order; + } + + /** + * Set the order for this filter. + * @param order the order to set + */ + public void setOrder(int order) { + this.order = order; + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedWebFilter.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/OrderedWebFilter.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedWebFilter.java rename to spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/OrderedWebFilter.java index f8751a2c4ca6..057a170d5434 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedWebFilter.java +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/OrderedWebFilter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.filter; +package org.springframework.boot.webflux.filter; import org.springframework.core.Ordered; import org.springframework.web.server.WebFilter; @@ -23,7 +23,7 @@ * An {@link Ordered} {@link org.springframework.web.server.WebFilter}. * * @author Phillip Webb - * @since 2.1.0 + * @since 4.0.0 */ public interface OrderedWebFilter extends WebFilter, Ordered { diff --git a/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/package-info.java b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/package-info.java new file mode 100644 index 000000000000..1ca0ef6eeff1 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/filter/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring Boot specific {@link org.springframework.web.server.WebFilter} implementations. + */ +package org.springframework.boot.webflux.filter; diff --git a/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..bb00b3730caf --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,83 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.webflux.hiddenmethod.filter.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Spring's HiddenHttpMethodFilter.", + "defaultValue": false + }, + { + "name": "spring.webflux.multipart.streaming", + "type": "java.lang.Boolean", + "deprecation": { + "reason": "Replaced by the PartEventHttpMessageReader and the PartEvent API.", + "level": "error" + } + } + ], + "hints": [ + { + "name": "spring.webflux.format.date", + "values": [ + { + "value": "dd/MM/yyyy", + "description": "Example date format. Any format supported by DateTimeFormatter.parse can be used." + }, + { + "value": "iso", + "description": "ISO-8601 extended local date format." + } + ], + "providers": [ + { + "name": "any" + } + ] + }, + { + "name": "spring.webflux.format.date-time", + "values": [ + { + "value": "yyyy-MM-dd HH:mm:ss", + "description": "Example date-time format. Any format supported by DateTimeFormatter.parse can be used." + }, + { + "value": "iso", + "description": "ISO-8601 extended local date-time format." + }, + { + "value": "iso-offset", + "description": "ISO offset date-time format." + } + ], + "providers": [ + { + "name": "any" + } + ] + }, + { + "name": "spring.webflux.format.time", + "values": [ + { + "value": "HH:mm:ss", + "description": "Example time format. Any format supported by DateTimeFormatter.parse can be used." + }, + { + "value": "iso", + "description": "ISO-8601 extended local time format." + }, + { + "value": "iso-offset", + "description": "ISO offset time format." + } + ], + "providers": [ + { + "name": "any" + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..fff9048a6d9b --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxEndpointManagementContextConfiguration +org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxManagementChildContextConfiguration diff --git a/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..f585fb51f9d6 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,9 @@ +org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration +org.springframework.boot.webflux.autoconfigure.ReactiveMultipartAutoConfiguration +org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration +org.springframework.boot.webflux.autoconfigure.WebFluxObservationAutoConfiguration +org.springframework.boot.webflux.autoconfigure.WebSessionIdResolverAutoConfiguration +org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web.WebFluxHealthEndpointExtensionAutoConfiguration +org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxHttpExchangesAutoConfiguration +org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxMappingsAutoConfiguration +org.springframework.boot.webflux.autoconfigure.error.ErrorWebFluxAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMappingTests.java similarity index 75% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMappingTests.java index 9264a463b444..0b81c6272a6a 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/AbstractWebFluxEndpointHandlerMappingTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.TypeReference; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; @@ -39,11 +39,11 @@ void shouldRegisterHints() { getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection() .onType(TypeReference - .of("org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.WriteOperationHandler"))) + .of("org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping.WriteOperationHandler"))) .accepts(runtimeHints); assertThat(RuntimeHintsPredicates.reflection() .onType(TypeReference - .of("org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.ReadOperationHandler"))) + .of("org.springframework.boot.webflux.actuate.endpoint.web.AbstractWebFluxEndpointHandlerMapping.ReadOperationHandler"))) .accepts(runtimeHints); } diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java new file mode 100644 index 000000000000..7f2f01c16796 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java @@ -0,0 +1,169 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.actuate.endpoint.web; + +import java.time.Duration; +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; +import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint; +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.http.HttpMethod; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.server.MethodNotAllowedException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link ControllerEndpointHandlerMapping}. + * + * @author Phillip Webb + * @author Stephane Nicoll + * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support + */ +@Deprecated(since = "3.3.5", forRemoval = true) +@SuppressWarnings("removal") +class ControllerEndpointHandlerMappingTests { + + private final StaticApplicationContext context = new StaticApplicationContext(); + + @Test + void mappingWithNoPrefix() { + ExposableControllerEndpoint first = firstEndpoint(); + ExposableControllerEndpoint second = secondEndpoint(); + ControllerEndpointHandlerMapping mapping = createMapping("", first, second); + assertThat(getHandler(mapping, HttpMethod.GET, "/first")).isEqualTo(handlerOf(first.getController(), "get")); + assertThat(getHandler(mapping, HttpMethod.POST, "/second")) + .isEqualTo(handlerOf(second.getController(), "save")); + assertThat(getHandler(mapping, HttpMethod.GET, "/third")).isNull(); + } + + @Test + void mappingWithPrefix() { + ExposableControllerEndpoint first = firstEndpoint(); + ExposableControllerEndpoint second = secondEndpoint(); + ControllerEndpointHandlerMapping mapping = createMapping("actuator", first, second); + assertThat(getHandler(mapping, HttpMethod.GET, "/actuator/first")) + .isEqualTo(handlerOf(first.getController(), "get")); + assertThat(getHandler(mapping, HttpMethod.POST, "/actuator/second")) + .isEqualTo(handlerOf(second.getController(), "save")); + assertThat(getHandler(mapping, HttpMethod.GET, "/first")).isNull(); + assertThat(getHandler(mapping, HttpMethod.GET, "/second")).isNull(); + } + + @Test + void mappingWithNoPath() { + ExposableControllerEndpoint pathless = pathlessEndpoint(); + ControllerEndpointHandlerMapping mapping = createMapping("actuator", pathless); + assertThat(getHandler(mapping, HttpMethod.GET, "/actuator/pathless")) + .isEqualTo(handlerOf(pathless.getController(), "get")); + assertThat(getHandler(mapping, HttpMethod.GET, "/pathless")).isNull(); + assertThat(getHandler(mapping, HttpMethod.GET, "/")).isNull(); + } + + @Test + void mappingNarrowedToMethod() { + ExposableControllerEndpoint first = firstEndpoint(); + ControllerEndpointHandlerMapping mapping = createMapping("actuator", first); + assertThatExceptionOfType(MethodNotAllowedException.class) + .isThrownBy(() -> getHandler(mapping, HttpMethod.POST, "/actuator/first")); + } + + private Object getHandler(ControllerEndpointHandlerMapping mapping, HttpMethod method, String requestURI) { + return mapping.getHandler(exchange(method, requestURI)).block(Duration.ofSeconds(30)); + } + + private ControllerEndpointHandlerMapping createMapping(String prefix, ExposableControllerEndpoint... endpoints) { + ControllerEndpointHandlerMapping mapping = new ControllerEndpointHandlerMapping(new EndpointMapping(prefix), + Arrays.asList(endpoints), null, (endpointId, defaultAccess) -> Access.UNRESTRICTED); + mapping.setApplicationContext(this.context); + mapping.afterPropertiesSet(); + return mapping; + } + + private HandlerMethod handlerOf(Object source, String methodName) { + return new HandlerMethod(source, ReflectionUtils.findMethod(source.getClass(), methodName)); + } + + private MockServerWebExchange exchange(HttpMethod method, String requestURI) { + return MockServerWebExchange.from(MockServerHttpRequest.method(method, requestURI).build()); + } + + private ExposableControllerEndpoint firstEndpoint() { + return mockEndpoint(EndpointId.of("first"), new FirstTestMvcEndpoint()); + } + + private ExposableControllerEndpoint secondEndpoint() { + return mockEndpoint(EndpointId.of("second"), new SecondTestMvcEndpoint()); + } + + private ExposableControllerEndpoint pathlessEndpoint() { + return mockEndpoint(EndpointId.of("pathless"), new PathlessControllerEndpoint()); + } + + private ExposableControllerEndpoint mockEndpoint(EndpointId id, Object controller) { + ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class); + given(endpoint.getEndpointId()).willReturn(id); + given(endpoint.getController()).willReturn(controller); + given(endpoint.getRootPath()).willReturn(id.toString()); + return endpoint; + } + + @ControllerEndpoint(id = "first") + static class FirstTestMvcEndpoint { + + @GetMapping("/") + String get() { + return "test"; + } + + } + + @ControllerEndpoint(id = "second") + static class SecondTestMvcEndpoint { + + @PostMapping("/") + void save() { + + } + + } + + @ControllerEndpoint(id = "pathless") + static class PathlessControllerEndpoint { + + @GetMapping + String get() { + return "test"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMappingTests.java similarity index 82% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMappingTests.java index 9349334ee0d1..80ad47a0acec 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/WebFluxEndpointHandlerMappingTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.reactive; +package org.springframework.boot.webflux.actuate.endpoint.web; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.web.Link; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxLinksHandler; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping.WebFluxLinksHandler; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterIntegrationTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterIntegrationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterIntegrationTests.java index 6a40fddade0d..b7cdd6c1a187 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.exchanges; import java.util.EnumSet; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterTests.java index 54c95711cee2..83e1c866714a 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/HttpExchangesWebFilterTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/HttpExchangesWebFilterTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.exchanges; import java.security.Principal; import java.time.Duration; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequestTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequestTests.java index 253387fca697..0c5d6c027a82 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/exchanges/reactive/RecordableServerHttpRequestTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/exchanges/RecordableServerHttpRequestTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.exchanges.reactive; +package org.springframework.boot.webflux.actuate.exchanges; import java.net.InetSocketAddress; import java.net.URI; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlersMappingDescriptionProviderTests.java similarity index 86% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlersMappingDescriptionProviderTests.java index 6e574bc285e5..b3381afe2423 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/mappings/DispatcherHandlersMappingDescriptionProviderTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.reactive; +package org.springframework.boot.webflux.actuate.mappings; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.DispatcherHandlersMappingDescriptionProviderRuntimeHints; +import org.springframework.boot.webflux.actuate.mappings.DispatcherHandlersMappingDescriptionProvider.DispatcherHandlersMappingDescriptionProviderRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java index dfcbf77833af..c1c5541dda80 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartAutoConfigurationTests.java index 3f515c10e3c2..6d95c34939b8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartAutoConfigurationTests.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.nio.charset.StandardCharsets; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.codec.CodecCustomizer; import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader; import org.springframework.http.codec.multipart.PartEventHttpMessageReader; import org.springframework.http.codec.support.DefaultServerCodecConfigurer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartPropertiesTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartPropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartPropertiesTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartPropertiesTests.java index 7be52320ba2e..b95ed2ed3be3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveMultipartPropertiesTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/ReactiveMultipartPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WebFluxAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WebFluxAutoConfigurationTests.java index 3b441b6dc968..356049579b85 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WebFluxAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.time.Duration; import java.time.LocalDateTime; @@ -46,25 +46,25 @@ import org.springframework.aop.support.AopUtils; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; -import org.springframework.boot.autoconfigure.validation.ValidatorAdapter; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration.WebFluxConfig; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfigurationTests.OrderedControllerAdviceBeansConfiguration.HighestOrderedControllerAdvice; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfigurationTests.OrderedControllerAdviceBeansConfiguration.LowestOrderedControllerAdvice; +import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.codec.CodecCustomizer; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter; -import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory; +import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration; +import org.springframework.boot.validation.autoconfigure.ValidatorAdapter; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration.WebFluxConfig; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfigurationTests.OrderedControllerAdviceBeansConfiguration.HighestOrderedControllerAdvice; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfigurationTests.OrderedControllerAdviceBeansConfiguration.LowestOrderedControllerAdvice; +import org.springframework.boot.webflux.filter.OrderedHiddenHttpMethodFilter; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Import; import org.springframework.context.i18n.LocaleContext; import org.springframework.core.Ordered; @@ -707,7 +707,7 @@ void problemDetailsEnabledAddsExceptionHandler() { @Test void problemDetailsExceptionHandlerDoesNotPreventProxying() { - this.contextRunner.withConfiguration(AutoConfigurations.of(AopAutoConfiguration.class)) + this.contextRunner.withUserConfiguration(AopConfiguration.class) .withBean(ExceptionHandlerInterceptor.class) .withPropertyValues("spring.webflux.problemdetails.enabled:true") .run((context) -> assertThat(context).getBean(ProblemDetailsExceptionHandler.class) @@ -1149,6 +1149,12 @@ void exceptionHandlerIntercept(JoinPoint joinPoint, Object returnValue) { } + @Configuration(proxyBeanMethods = false) + @EnableAspectJAutoProxy(proxyTargetClass = true) + static class AopConfiguration { + + } + @Configuration(proxyBeanMethods = false) static class CustomApplicationTaskExecutorConfig { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxPropertiesTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WebFluxPropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxPropertiesTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WebFluxPropertiesTests.java index ca36322a5d45..73c16f76e77c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxPropertiesTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WebFluxPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WelcomePageRouterFunctionFactoryTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WelcomePageRouterFunctionFactoryTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WelcomePageRouterFunctionFactoryTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WelcomePageRouterFunctionFactoryTests.java index 4819a646d0ca..a19ecc1eb96f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WelcomePageRouterFunctionFactoryTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WelcomePageRouterFunctionFactoryTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive; +package org.springframework.boot.webflux.autoconfigure; import java.nio.charset.StandardCharsets; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointAdditionalPathIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointAdditionalPathIntegrationTests.java new file mode 100644 index 000000000000..e60a92d8b690 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointAdditionalPathIntegrationTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web; + +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.integrationtest.AbstractHealthEndpointAdditionalPathIntegrationTests; +import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration; +import org.springframework.boot.reactor.netty.autoconfigure.actuate.web.NettyReactiveManagementContextAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebApplicationContext; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; + +/** + * Integration tests for Webflux health groups on an additional path. + * + * @author Madhura Bhave + */ +class WebFluxHealthEndpointAdditionalPathIntegrationTests extends + AbstractHealthEndpointAdditionalPathIntegrationTests { + + WebFluxHealthEndpointAdditionalPathIntegrationTests() { + super(new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, CodecsAutoConfiguration.class, + WebFluxAutoConfiguration.class, HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HttpHandlerAutoConfiguration.class, + EndpointAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + WebFluxHealthEndpointExtensionAutoConfiguration.class, + DiskSpaceHealthContributorAutoConfiguration.class, WebEndpointAutoConfiguration.class, + ManagementContextAutoConfiguration.class, NettyReactiveWebServerAutoConfiguration.class, + NettyReactiveManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)) + .withInitializer(new ServerPortInfoApplicationContextInitializer()) + .withPropertyValues("server.port=0")); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointExtensionAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointExtensionAutoConfigurationTests.java new file mode 100644 index 000000000000..c694920340b5 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/endpoint/web/WebFluxHealthEndpointExtensionAutoConfigurationTests.java @@ -0,0 +1,97 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.WithTestEndpointOutcomeExposureContributor; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.health.contributor.ReactiveHealthIndicator; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.webflux.actuate.endpoint.web.AdditionalHealthEndpointPathsWebFluxHandlerMapping; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebFluxHealthEndpointExtensionAutoConfiguration}. + * + * @author Stephane Nicoll + */ +class WebFluxHealthEndpointExtensionAutoConfigurationTests { + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withUserConfiguration(HealthIndicatorsConfiguration.class) + .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + WebFluxHealthEndpointExtensionAutoConfiguration.class)); + + @Test + @WithTestEndpointOutcomeExposureContributor + void additionalReactiveHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)) + .withPropertyValues("management.endpoints.web.exposure.exclude=*", + "management.endpoints.test.exposure.include=*") + .run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context).hasSingleBean(HealthEndpoint.class); + assertThat(context).hasSingleBean(ReactiveHealthEndpointWebExtension.class); + assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty(); + assertThat(context).hasSingleBean(AdditionalHealthEndpointPathsWebFluxHandlerMapping.class); + }); + } + + @Test + @WithTestEndpointOutcomeExposureContributor + void backsOffWithoutWebEndpointInfrastructure() { + this.contextRunner.withConfiguration(AutoConfigurations.of(EndpointAutoConfiguration.class)) + .withPropertyValues("management.endpoints.web.exposure.exclude=*", + "management.endpoints.test.exposure.include=*") + .run((context) -> assertThat(context) + .doesNotHaveBean(AdditionalHealthEndpointPathsWebFluxHandlerMapping.class)); + } + + @Configuration(proxyBeanMethods = false) + static class HealthIndicatorsConfiguration { + + @Bean + ReactiveHealthIndicator simpleHealthIndicator() { + return () -> Mono.just(Health.up().build()); + } + + @Bean + HealthIndicator additionalHealthIndicator() { + return () -> Health.up().build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/ControllerEndpointWebFluxIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/ControllerEndpointWebFluxIntegrationTests.java new file mode 100644 index 000000000000..238643e84c74 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/ControllerEndpointWebFluxIntegrationTests.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; +import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.web.context.reactive.AnnotationConfigReactiveWebApplicationContext; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * Integration tests for the Actuator's WebFlux {@link ControllerEndpoint controller + * endpoints}. + * + * @author Phillip Webb + */ +@SuppressWarnings("removal") +class ControllerEndpointWebFluxIntegrationTests { + + private AnnotationConfigReactiveWebApplicationContext context; + + @AfterEach + void close() { + this.context.close(); + } + + @Test + void endpointsCanBeAccessed() { + this.context = new AnnotationConfigReactiveWebApplicationContext(); + this.context.register(DefaultConfiguration.class, ExampleController.class); + TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context); + this.context.refresh(); + WebTestClient webClient = WebTestClient.bindToApplicationContext(this.context).build(); + webClient.get().uri("/actuator/example").exchange().expectStatus().isOk(); + } + + @ImportAutoConfiguration({ JacksonAutoConfiguration.class, EndpointAutoConfiguration.class, + WebEndpointAutoConfiguration.class, AuditAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, WebFluxAutoConfiguration.class, + ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class }) + static class DefaultConfiguration { + + } + + @RestControllerEndpoint(id = "example") + static class ExampleController { + + @GetMapping("/") + String example() { + return "Example"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointAccessIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointAccessIntegrationTests.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointAccessIntegrationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointAccessIntegrationTests.java index 2980093d64a5..ad4ac56fea52 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointAccessIntegrationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointAccessIntegrationTests.java @@ -14,26 +14,26 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integrationtest; +package org.springframework.boot.webflux.autoconfigure.actuate.web; import java.time.Duration; import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.web.server.reactive.context.ReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.test.web.reactive.server.EntityExchangeResult; @@ -53,11 +53,11 @@ class WebFluxEndpointAccessIntegrationTests { private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner( AnnotationConfigReactiveWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class, + .withConfiguration(AutoConfigurations.of(NettyReactiveWebServerAutoConfiguration.class, HttpHandlerAutoConfiguration.class, JacksonAutoConfiguration.class, CodecsAutoConfiguration.class, WebFluxAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ManagementContextAutoConfiguration.class, ReactiveManagementContextAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL)) + ManagementContextAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(BeansEndpointAutoConfiguration.class)) .withUserConfiguration(CustomWebFluxEndpoint.class) .withPropertyValues("server.port:0"); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointCorsIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointCorsIntegrationTests.java similarity index 91% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointCorsIntegrationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointCorsIntegrationTests.java index 7a84c42e6c9e..7741dd3ebbe7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebFluxEndpointCorsIntegrationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointCorsIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integrationtest; +package org.springframework.boot.webflux.autoconfigure.actuate.web; import java.util.function.Consumer; @@ -23,17 +23,15 @@ import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; import org.springframework.http.HttpHeaders; import org.springframework.test.web.reactive.server.WebTestClient; @@ -50,7 +48,7 @@ class WebFluxEndpointCorsIntegrationTests { .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, CodecsAutoConfiguration.class, WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class, - ReactiveManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)) + BeansEndpointAutoConfiguration.class)) .withPropertyValues("management.endpoints.web.exposure.include:*"); @Test diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointIntegrationTests.java new file mode 100644 index 000000000000..105b4ca9a09b --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointIntegrationTests.java @@ -0,0 +1,187 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.web.reactive.server.WebTestClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for the WebFlux actuator endpoints. + * + * @author Andy Wilkinson + */ +class WebFluxEndpointIntegrationTests { + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, CodecsAutoConfiguration.class, + WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class, EndpointAutoConfiguration.class, + WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class, + BeansEndpointAutoConfiguration.class)) + .withUserConfiguration(EndpointsConfiguration.class); + + @Test + void linksAreProvidedToAllEndpointTypes() { + this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include:*").run((context) -> { + WebTestClient client = createWebTestClient(context); + client.get() + .uri("/actuator") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("_links.beans") + .isNotEmpty() + .jsonPath("_links.restcontroller") + .isNotEmpty() + .jsonPath("_links.controller") + .isNotEmpty(); + }); + } + + @Test + void linksPageIsNotAvailableWhenDisabled() { + this.contextRunner.withPropertyValues("management.endpoints.web.discovery.enabled=false").run((context) -> { + WebTestClient client = createWebTestClient(context); + client.get().uri("/actuator").exchange().expectStatus().isNotFound(); + }); + } + + @Test + void endpointObjectMapperCanBeApplied() { + this.contextRunner.withUserConfiguration(EndpointObjectMapperConfiguration.class) + .withPropertyValues("management.endpoints.web.exposure.include:*") + .run((context) -> { + WebTestClient client = createWebTestClient(context); + client.get() + .uri("/actuator/beans") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .consumeWith((result) -> { + String json = new String(result.getResponseBody(), StandardCharsets.UTF_8); + assertThat(json).contains("\"scope\":\"notelgnis\""); + }); + }); + } + + private WebTestClient createWebTestClient(ApplicationContext context) { + return WebTestClient.bindToApplicationContext(context) + .configureClient() + .baseUrl("https://spring.example.org") + .build(); + } + + @org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint(id = "controller") + @SuppressWarnings("removal") + static class TestControllerEndpoint { + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "restcontroller") + @SuppressWarnings("removal") + static class TestRestControllerEndpoint { + + } + + @Configuration(proxyBeanMethods = false) + static class EndpointsConfiguration { + + @Bean + TestControllerEndpoint testControllerEndpoint() { + return new TestControllerEndpoint(); + } + + @Bean + TestRestControllerEndpoint testRestControllerEndpoint() { + return new TestRestControllerEndpoint(); + } + + } + + @Configuration + @SuppressWarnings({ "deprecation", "removal" }) + static class EndpointObjectMapperConfiguration { + + @Bean + EndpointObjectMapper endpointObjectMapper() { + SimpleModule module = new SimpleModule(); + module.addSerializer(String.class, new ReverseStringSerializer()); + ObjectMapper objectMapper = org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.json() + .modules(module) + .build(); + return () -> objectMapper; + } + + static class ReverseStringSerializer extends StdScalarSerializer { + + ReverseStringSerializer() { + super(String.class, false); + } + + @Override + public boolean isEmpty(SerializerProvider prov, Object value) { + return ((String) value).isEmpty(); + } + + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException { + serialize(value, gen); + } + + @Override + public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, + TypeSerializer typeSer) throws IOException { + serialize(value, gen); + } + + private void serialize(Object value, JsonGenerator gen) throws IOException { + StringBuilder builder = new StringBuilder((String) value); + gen.writeString(builder.reverse().toString()); + } + + } + + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxHttpExchangesAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxHttpExchangesAutoConfigurationTests.java new file mode 100644 index 000000000000..75c9384fc249 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxHttpExchangesAutoConfigurationTests.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import java.util.EnumSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; +import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; +import org.springframework.boot.actuate.web.exchanges.Include; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.webflux.actuate.exchanges.HttpExchangesWebFilter; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebFluxHttpExchangesAutoConfiguration}. + * + * @author Andy Wilkinson + * @author Madhura Bhave + */ +class WebFluxHttpExchangesAutoConfigurationTests { + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(WebFluxHttpExchangesAutoConfiguration.class)); + + @Test + void whenRecordingIsDisabledThenFilterIsNotCreated() { + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class) + .withPropertyValues("management.httpexchanges.recording.enabled=false") + .run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesWebFilter.class)); + } + + @Test + void whenNoRepositoryIsDefinedThenFilterIsNotCreated() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(HttpExchangesWebFilter.class)); + } + + @Test + void filterIsCreated() { + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class) + .run((context) -> assertThat(context).hasSingleBean(HttpExchangesWebFilter.class)); + } + + @Test + void usesUserProvidedWebFilter() { + InMemoryHttpExchangeRepository repository = new InMemoryHttpExchangeRepository(); + this.contextRunner.withBean(InMemoryHttpExchangeRepository.class, () -> repository) + .withBean(CustomHttpExchangesWebFilter.class, + () -> new CustomHttpExchangesWebFilter(repository, EnumSet.allOf(Include.class))) + .run((context) -> { + assertThat(context).hasSingleBean(HttpExchangesWebFilter.class); + assertThat(context.getBean(HttpExchangesWebFilter.class)) + .isInstanceOf(CustomHttpExchangesWebFilter.class); + }); + } + + private static final class CustomHttpExchangesWebFilter extends HttpExchangesWebFilter { + + private CustomHttpExchangesWebFilter(HttpExchangeRepository repository, Set includes) { + super(repository, includes); + } + + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationIntegrationTests.java new file mode 100644 index 000000000000..e20c88bf66cc --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationIntegrationTests.java @@ -0,0 +1,170 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import org.apache.catalina.Valve; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.valves.AccessLogValve; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.convert.ApplicationConversionService; +import org.springframework.boot.env.ConfigTreePropertySource; +import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatReactiveManagementContextAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.reactive.TomcatReactiveWebServerAutoConfiguration; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; +import org.springframework.boot.web.server.context.WebServerInitializedEvent; +import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.convert.support.ConfigurableConversionService; +import org.springframework.http.MediaType; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link WebFluxManagementChildContextConfiguration}. + * + * @author Andy Wilkinson + */ +class WebFluxManagementChildContextConfigurationIntegrationTests { + + private final List webServers = new ArrayList<>(); + + private final ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner( + AnnotationConfigReactiveWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, + TomcatReactiveWebServerAutoConfiguration.class, TomcatReactiveManagementContextAutoConfiguration.class, + WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class, HttpHandlerAutoConfiguration.class, + WebFluxAutoConfiguration.class)) + .withUserConfiguration(SucceedingEndpoint.class) + .withInitializer(new ServerPortInfoApplicationContextInitializer()) + .withInitializer((context) -> context.addApplicationListener( + (ApplicationListener) (event) -> this.webServers.add(event.getWebServer()))) + .withPropertyValues("server.port=0", "management.server.port=0", "management.endpoints.web.exposure.include=*"); + + @TempDir + Path temp; + + @Test + void endpointsAreBeneathActuatorByDefault() { + this.runner.withPropertyValues("management.server.port:0").run(withWebTestClient((client) -> { + String body = client.get() + .uri("actuator/success") + .accept(MediaType.APPLICATION_JSON) + .exchangeToMono((response) -> response.bodyToMono(String.class)) + .block(); + assertThat(body).isEqualTo("Success"); + })); + } + + @Test + void whenManagementServerBasePathIsConfiguredThenEndpointsAreBeneathThatPath() { + this.runner.withPropertyValues("management.server.port:0", "management.server.base-path:/manage") + .run(withWebTestClient((client) -> { + String body = client.get() + .uri("manage/actuator/success") + .accept(MediaType.APPLICATION_JSON) + .exchangeToMono((response) -> response.bodyToMono(String.class)) + .block(); + assertThat(body).isEqualTo("Success"); + })); + } + + @Test // gh-32941 + void whenManagementServerPortLoadedFromConfigTree() { + this.runner.withInitializer(this::addConfigTreePropertySource) + .run((context) -> assertThat(context).hasNotFailed()); + } + + @Test + void accessLogHasManagementServerSpecificPrefix() { + this.runner.withPropertyValues("server.tomcat.accesslog.enabled=true").run((context) -> { + AccessLogValve accessLogValve = findAccessLogValve(); + assertThat(accessLogValve).isNotNull(); + assertThat(accessLogValve.getPrefix()).isEqualTo("management_access_log"); + }); + } + + private AccessLogValve findAccessLogValve() { + assertThat(this.webServers).hasSize(2); + Tomcat tomcat = ((TomcatWebServer) this.webServers.get(1)).getTomcat(); + for (Valve valve : tomcat.getEngine().getPipeline().getValves()) { + if (valve instanceof AccessLogValve accessLogValve) { + return accessLogValve; + } + } + return null; + } + + private void addConfigTreePropertySource(ConfigurableApplicationContext applicationContext) { + try { + applicationContext.getEnvironment() + .setConversionService((ConfigurableConversionService) ApplicationConversionService.getSharedInstance()); + Path configtree = this.temp.resolve("configtree"); + Path file = configtree.resolve("management/server/port"); + file.toFile().getParentFile().mkdirs(); + FileCopyUtils.copy("0".getBytes(StandardCharsets.UTF_8), file.toFile()); + ConfigTreePropertySource source = new ConfigTreePropertySource("configtree", configtree); + applicationContext.getEnvironment().getPropertySources().addFirst(source); + } + catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + private ContextConsumer withWebTestClient(Consumer webClient) { + return (context) -> { + String port = context.getEnvironment().getProperty("local.management.port"); + WebClient client = WebClient.create("http://localhost:" + port); + webClient.accept(client); + }; + } + + @Endpoint(id = "success") + static class SucceedingEndpoint { + + @ReadOperation + String fail() { + return "Success"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationTests.java new file mode 100644 index 000000000000..2d0607f5a189 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebFluxManagementChildContextConfiguration}. + * + * @author Moritz Halbritter + */ +class WebFluxManagementChildContextConfigurationTests { + + @Test + // gh-45857 + void failsWithoutManagementServerPropertiesBeanFromParent() { + new ReactiveWebApplicationContextRunner() + .run((parent) -> new ReactiveWebApplicationContextRunner().withParent(parent) + .withUserConfiguration(WebFluxManagementChildContextConfiguration.class) + .run((context) -> assertThat(context).hasFailed())); + } + + @Test + // gh-45857 + void succeedsWithManagementServerPropertiesBeanFromParent() { + new ReactiveWebApplicationContextRunner().withBean(ManagementServerProperties.class) + .run((parent) -> new ReactiveWebApplicationContextRunner().withParent(parent) + .withUserConfiguration(WebFluxManagementChildContextConfiguration.class) + .run((context) -> assertThat(context).hasNotFailed())); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxMappingsAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxMappingsAutoConfigurationTests.java new file mode 100644 index 000000000000..0083745d564a --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxMappingsAutoConfigurationTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.autoconfigure.actuate.web; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.webflux.actuate.mappings.DispatcherHandlersMappingDescriptionProvider; +import org.springframework.web.reactive.DispatcherHandler; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebFluxMappingsAutoConfiguration}. + * + * @author Andy Wilkinson + */ +class WebFluxMappingsAutoConfigurationTests { + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(WebFluxMappingsAutoConfiguration.class)); + + @Test + void whenEndpointIsUnavailableThenDescriptionProviderIsNotCreated() { + this.contextRunner.withBean(DispatcherHandler.class) + .run((context) -> assertThat(context).doesNotHaveBean(DispatcherHandlersMappingDescriptionProvider.class)); + } + + @Test + void whenEndpointIsAvailableButThereIsNoDispatcherHandlerThenDescriptionProviderIsNotCreated() { + this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=mappings") + .run((context) -> assertThat(context).doesNotHaveBean(DispatcherHandlersMappingDescriptionProvider.class)); + } + + @Test + void whenEndpointIsAvailableThenDescriptionProviderIsCreated() { + this.contextRunner.withBean(DispatcherHandler.class) + .withPropertyValues("management.endpoints.web.exposure.include=mappings") + .run((context) -> assertThat(context).hasSingleBean(DispatcherHandlersMappingDescriptionProvider.class)); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandlerIntegrationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandlerIntegrationTests.java index 5f9364c04c7c..92746e71e8a1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandlerIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.error; +package org.springframework.boot.webflux.autoconfigure.error; import java.nio.charset.StandardCharsets; import java.util.HashMap; @@ -32,12 +32,9 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.WebProperties; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration; +import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; @@ -45,9 +42,12 @@ import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; -import org.springframework.boot.web.reactive.error.ErrorAttributes; -import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.boot.webflux.error.DefaultErrorAttributes; +import org.springframework.boot.webflux.error.ErrorAttributes; +import org.springframework.boot.webflux.error.ErrorWebExceptionHandler; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -86,7 +86,7 @@ class DefaultErrorWebExceptionHandlerIntegrationTests { private final LogIdFilter logIdFilter = new LogIdFilter(); private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class, + .withConfiguration(AutoConfigurations.of(NettyReactiveWebServerAutoConfiguration.class, HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class, ErrorWebFluxAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, MustacheAutoConfiguration.class)) .withPropertyValues("spring.main.web-application-type=reactive", "server.port=0") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandlerTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandlerTests.java index 37eb65d87bd3..fe4d5b52bd90 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandlerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.error; +package org.springframework.boot.webflux.autoconfigure.error; import java.util.Collections; import java.util.List; @@ -25,8 +25,8 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.WebProperties.Resources; import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.boot.web.context.reactive.AnnotationConfigReactiveWebApplicationContext; +import org.springframework.boot.webflux.error.ErrorAttributes; import org.springframework.context.ApplicationContext; import org.springframework.http.MediaType; import org.springframework.http.codec.HttpMessageReader; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DummyBody.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DummyBody.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DummyBody.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DummyBody.java index e9f015288ee3..d65f82094863 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DummyBody.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DummyBody.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.reactive.error; +package org.springframework.boot.webflux.autoconfigure.error; import jakarta.validation.constraints.NotNull; diff --git a/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/error/DefaultErrorAttributesTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/error/DefaultErrorAttributesTests.java new file mode 100644 index 000000000000..eeb4f62484cd --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/error/DefaultErrorAttributesTests.java @@ -0,0 +1,405 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.error; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.error.ErrorAttributeOptions.Include; +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpStatus; +import org.springframework.http.codec.HttpMessageReader; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.validation.BindingResult; +import org.springframework.validation.MapBindingResult; +import org.springframework.validation.ObjectError; +import org.springframework.validation.method.MethodValidationResult; +import org.springframework.validation.method.ParameterValidationResult; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.support.WebExchangeBindException; +import org.springframework.web.method.annotation.HandlerMethodValidationException; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.web.server.ServerWebExchange; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link DefaultErrorAttributes}. + * + * @author Brian Clozel + * @author Stephane Nicoll + * @author Scott Frederick + * @author Moritz Halbritter + * @author Yanming Zhou + * @author Yongjun Hong + */ +class DefaultErrorAttributesTests { + + private static final ResponseStatusException NOT_FOUND = new ResponseStatusException(HttpStatus.NOT_FOUND); + + private DefaultErrorAttributes errorAttributes = new DefaultErrorAttributes(); + + private final List> readers = ServerCodecConfigurer.create().getReaders(); + + @Test + void missingExceptionAttribute() { + MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test").build()); + ServerRequest request = ServerRequest.create(exchange, this.readers); + assertThatIllegalStateException() + .isThrownBy(() -> this.errorAttributes.getErrorAttributes(request, ErrorAttributeOptions.defaults())) + .withMessageContaining("Missing exception attribute in ServerWebExchange"); + } + + @Test + void includeTimeStamp() { + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), + ErrorAttributeOptions.defaults()); + assertThat(attributes.get("timestamp")).isInstanceOf(Date.class); + } + + @Test + void defaultStatusCode() { + Error error = new OutOfMemoryError("Test error"); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), + ErrorAttributeOptions.defaults()); + assertThat(attributes).containsEntry("error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); + assertThat(attributes).containsEntry("status", 500); + } + + @Test + void annotatedResponseStatusCode() { + Exception error = new CustomException(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), + ErrorAttributeOptions.defaults()); + assertThat(attributes).containsEntry("error", HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); + assertThat(attributes).doesNotContainKey("message"); + assertThat(attributes).containsEntry("status", HttpStatus.I_AM_A_TEAPOT.value()); + } + + @Test + void annotatedResponseStatusCodeWithExceptionMessage() { + Exception error = new CustomException("Test Message"); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), + ErrorAttributeOptions.of(Include.MESSAGE, Include.STATUS, Include.ERROR)); + assertThat(attributes).containsEntry("error", HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); + assertThat(attributes).containsEntry("message", "Test Message"); + assertThat(attributes).containsEntry("status", HttpStatus.I_AM_A_TEAPOT.value()); + } + + @Test + void annotatedResponseStatusCodeWithCustomReasonPhrase() { + Exception error = new Custom2Exception(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), + ErrorAttributeOptions.of(Include.MESSAGE, Include.STATUS, Include.ERROR)); + assertThat(attributes).containsEntry("error", HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); + assertThat(attributes).containsEntry("status", HttpStatus.I_AM_A_TEAPOT.value()); + assertThat(attributes).containsEntry("message", "Nope!"); + } + + @Test + void includeStatusCode() { + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), + ErrorAttributeOptions.defaults()); + assertThat(attributes).containsEntry("error", HttpStatus.NOT_FOUND.getReasonPhrase()); + assertThat(attributes).containsEntry("status", 404); + } + + @Test + void getError() { + Error error = new OutOfMemoryError("Test error"); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + ServerRequest serverRequest = buildServerRequest(request, error); + Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, + ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).containsEntry("message", "Test error"); + } + + @Test + void excludeMessage() { + Error error = new OutOfMemoryError("Test error"); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + ServerRequest serverRequest = buildServerRequest(request, error); + Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, + ErrorAttributeOptions.defaults()); + assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); + assertThat(attributes).doesNotContainKey("message"); + } + + @Test + void includeException() { + RuntimeException error = new RuntimeException("Test"); + this.errorAttributes = new DefaultErrorAttributes(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + ServerRequest serverRequest = buildServerRequest(request, error); + Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, + ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE)); + assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); + assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); + assertThat(attributes).containsEntry("message", "Test"); + } + + @Test + void processResponseStatusException() { + RuntimeException nested = new RuntimeException("Test"); + ResponseStatusException error = new ResponseStatusException(HttpStatus.BAD_REQUEST, "invalid request", nested); + this.errorAttributes = new DefaultErrorAttributes(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + ServerRequest serverRequest = buildServerRequest(request, error); + Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, + ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE, Include.STATUS)); + assertThat(attributes).containsEntry("status", 400); + assertThat(attributes).containsEntry("message", "invalid request"); + assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); + assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); + } + + @Test + void processResponseStatusExceptionWithNoNestedCause() { + ResponseStatusException error = new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, + "could not process request"); + this.errorAttributes = new DefaultErrorAttributes(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + ServerRequest serverRequest = buildServerRequest(request, error); + Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, + ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE, Include.STATUS)); + assertThat(attributes).containsEntry("status", 406); + assertThat(attributes).containsEntry("message", "could not process request"); + assertThat(attributes).containsEntry("exception", ResponseStatusException.class.getName()); + assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); + } + + @Test + void notIncludeTrace() { + RuntimeException ex = new RuntimeException("Test"); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), + ErrorAttributeOptions.defaults()); + assertThat(attributes).doesNotContainKey("trace"); + } + + @Test + void includeTrace() { + RuntimeException ex = new RuntimeException("Test"); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), + ErrorAttributeOptions.of(Include.STACK_TRACE)); + assertThat(attributes.get("trace").toString()).startsWith("java.lang"); + } + + @Test + void includePathByDefault() { + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), + ErrorAttributeOptions.defaults()); + assertThat(attributes).containsEntry("path", "/test"); + } + + @Test + void includePath() { + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), + ErrorAttributeOptions.of(Include.PATH)); + assertThat(attributes).containsEntry("path", "/test"); + } + + @Test + void pathShouldIncludeContext() { + MockServerHttpRequest request = MockServerHttpRequest.get("/context/test").contextPath("/context").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), + ErrorAttributeOptions.of(Include.PATH)); + assertThat(attributes).containsEntry("path", "/context/test"); + } + + @Test + void excludePath() { + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), + ErrorAttributeOptions.of()); + assertThat(attributes).doesNotContainEntry("path", "/test"); + } + + @Test + void includeLogPrefix() { + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + ServerRequest serverRequest = buildServerRequest(request, NOT_FOUND); + Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, + ErrorAttributeOptions.defaults()); + assertThat(attributes).containsEntry("requestId", serverRequest.exchange().getRequest().getId()); + } + + @Test + void extractBindingResultErrors() throws Exception { + Method method = getClass().getDeclaredMethod("method", String.class); + MethodParameter stringParam = new MethodParameter(method, 0); + BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); + bindingResult.addError(new ObjectError("c", "d")); + Exception ex = new WebExchangeBindException(stringParam, bindingResult); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), + ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); + assertThat(attributes.get("message")).asString() + .startsWith("Validation failed for argument at index 0 in method: " + "int " + getClass().getName() + + ".method(java.lang.String), with 1 error(s)"); + assertThat(attributes).containsEntry("errors", + org.springframework.boot.web.error.Error.wrap(bindingResult.getAllErrors())); + } + + @Test + void extractBindingResultErrorsThatCausedAResponseStatusException() throws Exception { + Method method = getClass().getDeclaredMethod("method", String.class); + MethodParameter stringParam = new MethodParameter(method, 0); + BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); + bindingResult.addError(new ObjectError("c", "d")); + Exception ex = new WebExchangeBindException(stringParam, bindingResult); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes( + buildServerRequest(request, new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid", ex)), + ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); + assertThat(attributes.get("message")).isEqualTo("Invalid"); + assertThat(attributes).containsEntry("errors", + org.springframework.boot.web.error.Error.wrap(bindingResult.getAllErrors())); + } + + @Test + void extractMethodValidationResultErrors() throws Exception { + Object target = "test"; + Method method = String.class.getMethod("substring", int.class); + MethodParameter parameter = new MethodParameter(method, 0); + MethodValidationResult methodValidationResult = MethodValidationResult.create(target, method, + List.of(new ParameterValidationResult(parameter, -1, + List.of(new ObjectError("beginIndex", "beginIndex is negative")), null, null, null, + (error, sourceType) -> { + throw new IllegalArgumentException("No source object of the given type"); + }))); + HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), + ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); + assertThat(attributes.get("message")).asString() + .isEqualTo( + "Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1"); + assertThat(attributes).containsEntry("errors", + org.springframework.boot.web.error.Error.wrap(methodValidationResult.getAllErrors())); + } + + @Test + void extractBindingResultErrorsExcludeMessageAndErrors() throws Exception { + Method method = getClass().getDeclaredMethod("method", String.class); + MethodParameter stringParam = new MethodParameter(method, 0); + BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); + bindingResult.addError(new ObjectError("c", "d")); + Exception ex = new WebExchangeBindException(stringParam, bindingResult); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), + ErrorAttributeOptions.defaults()); + assertThat(attributes).doesNotContainKey("message"); + assertThat(attributes).doesNotContainKey("errors"); + } + + @Test + void extractParameterValidationResultErrors() throws Exception { + Object target = "test"; + Method method = String.class.getMethod("substring", int.class); + MethodParameter parameter = new MethodParameter(method, 0); + ParameterValidationResult parameterValidationResult = new ParameterValidationResult(parameter, -1, + List.of(new ObjectError("beginIndex", "beginIndex is negative")), null, null, null, + (error, sourceType) -> { + throw new IllegalArgumentException("No source object of the given type"); + }); + MethodValidationResult methodValidationResult = MethodValidationResult.create(target, method, + List.of(parameterValidationResult)); + HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), + ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); + assertThat(attributes.get("message")).asString() + .isEqualTo( + "Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1"); + assertThat(attributes).containsEntry("errors", + org.springframework.boot.web.error.Error.wrap(methodValidationResult.getAllErrors())); + } + + @Test + void excludeStatus() { + ResponseStatusException error = new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, + "could not process request"); + this.errorAttributes = new DefaultErrorAttributes(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + ServerRequest serverRequest = buildServerRequest(request, error); + Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, + ErrorAttributeOptions.defaults().excluding(Include.STATUS)); + assertThat(attributes).doesNotContainKey("status"); + } + + @Test + void excludeError() { + ResponseStatusException error = new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, + "could not process request"); + this.errorAttributes = new DefaultErrorAttributes(); + MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); + ServerRequest serverRequest = buildServerRequest(request, error); + Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, + ErrorAttributeOptions.defaults().excluding(Include.ERROR)); + assertThat(attributes).doesNotContainKey("error"); + } + + private ServerRequest buildServerRequest(MockServerHttpRequest request, Throwable error) { + ServerWebExchange exchange = MockServerWebExchange.from(request); + this.errorAttributes.storeErrorInformation(error, exchange); + return ServerRequest.create(exchange, this.readers); + } + + int method(String firstParam) { + return 42; + } + + @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) + static class CustomException extends RuntimeException { + + CustomException() { + } + + CustomException(String message) { + super(message); + } + + } + + @ResponseStatus(value = HttpStatus.I_AM_A_TEAPOT, reason = "Nope!") + static class Custom2Exception extends RuntimeException { + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/observation/autoconfigure/WebFluxObservationAutoConfigurationTests.java similarity index 86% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/observation/autoconfigure/WebFluxObservationAutoConfigurationTests.java index 4e43b9164ac9..4752df80dfc6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/reactive/WebFluxObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/observation/autoconfigure/WebFluxObservationAutoConfigurationTests.java @@ -14,27 +14,29 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation.web.reactive; +package org.springframework.boot.webflux.observation.autoconfigure; import java.time.Duration; import java.time.temporal.ChronoUnit; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.autoconfigure.metrics.web.TestController; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.WebFluxObservationAutoConfiguration; import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention; import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -51,7 +53,7 @@ class WebFluxObservationAutoConfigurationTests { private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .with(MetricsRun.simple()) + .withBean(SimpleMeterRegistry.class) .withConfiguration( AutoConfigurations.of(ObservationAutoConfiguration.class, WebFluxObservationAutoConfiguration.class)); @@ -130,4 +132,24 @@ private MeterRegistry getInitializedMeterRegistry(AssertableReactiveWebApplicati return meterRegistry; } + @RestController + static class TestController { + + @GetMapping("test0") + String test0() { + return "test0"; + } + + @GetMapping("test1") + String test1() { + return "test1"; + } + + @GetMapping("test2") + String test2() { + return "test2"; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/404.mustache b/spring-boot-project/spring-boot-webflux/src/test/resources/org/springframework/boot/webflux/autoconfigure/error/templates/error/404.mustache similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/404.mustache rename to spring-boot-project/spring-boot-webflux/src/test/resources/org/springframework/boot/webflux/autoconfigure/error/templates/error/404.mustache diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/4xx.mustache b/spring-boot-project/spring-boot-webflux/src/test/resources/org/springframework/boot/webflux/autoconfigure/error/templates/error/4xx.mustache similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/4xx.mustache rename to spring-boot-project/spring-boot-webflux/src/test/resources/org/springframework/boot/webflux/autoconfigure/error/templates/error/4xx.mustache diff --git a/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java new file mode 100644 index 000000000000..324cae7ecf26 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.actuate.endpoint.web.test; + +import java.util.Collections; + +import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; +import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + +/** + * Endpoint configuration for WebFlux. + * + * @author Andy Wilkinson + * @author Stephane Nicoll + */ +@Configuration(proxyBeanMethods = false) +@ImportAutoConfiguration({ JacksonAutoConfiguration.class, WebFluxAutoConfiguration.class }) +class WebFluxEndpointConfiguration { + + private final ApplicationContext applicationContext; + + WebFluxEndpointConfiguration(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Bean + NettyReactiveWebServerFactory netty() { + return new NettyReactiveWebServerFactory(0); + } + + @Bean + HttpHandler httpHandler(ApplicationContext applicationContext) { + return WebHttpHandlerBuilder.applicationContext(applicationContext).build(); + } + + @Bean + WebFluxEndpointHandlerMapping webEndpointReactiveHandlerMapping() { + EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; + WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, + new ConversionServiceParameterValueMapper(), endpointMediaTypes, Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + return new WebFluxEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), + endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), + true); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxWebEndpointInfrastructureProvider.java b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxWebEndpointInfrastructureProvider.java new file mode 100644 index 000000000000..9556b1056173 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxWebEndpointInfrastructureProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webflux.actuate.endpoint.web.test; + +import java.util.List; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider; +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; + +/** + * {@link WebEndpointInfrastructureProvider} for WebFlux. + * + * @author Stephane Nicoll + */ +class WebFluxWebEndpointInfrastructureProvider implements WebEndpointInfrastructureProvider { + + @Override + public boolean supports(Infrastructure infrastructure) { + return infrastructure == Infrastructure.WEBFLUX; + } + + @Override + public List> getInfrastructureConfiguration(Infrastructure infrastructure) { + return List.of(WebFluxEndpointConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/testFixtures/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-webflux/src/testFixtures/resources/META-INF/spring.factories new file mode 100644 index 000000000000..cfd660e3b2a0 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/testFixtures/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider=\ +org.springframework.boot.webflux.actuate.endpoint.web.test.WebFluxWebEndpointInfrastructureProvider diff --git a/spring-boot-project/spring-boot-webmvc/build.gradle b/spring-boot-project/spring-boot-webmvc/build.gradle new file mode 100644 index 000000000000..7682416597ae --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/build.gradle @@ -0,0 +1,70 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "java-test-fixtures" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Web MVC" + +dependencies { + api(project(":spring-boot-project:spring-boot-servlet")) + api("org.springframework:spring-web") + api("org.springframework:spring-webmvc") + + compileOnly("jakarta.servlet:jakarta.servlet-api") + + implementation(project(":spring-boot-project:spring-boot-http-converter")) + + optional(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-health")) + optional(project(":spring-boot-project:spring-boot-metrics")) + optional(project(":spring-boot-project:spring-boot-observation")) + optional(project(":spring-boot-project:spring-boot-tomcat")) + optional(project(":spring-boot-project:spring-boot-undertow")) + optional(project(":spring-boot-project:spring-boot-validation")) + optional(project(":spring-boot-project:spring-boot-web-server")) + optional("com.fasterxml.jackson.core:jackson-databind") + optional("io.projectreactor:reactor-core") + + testFixturesApi(testFixtures(project(":spring-boot-project:spring-boot-actuator"))) + testFixturesImplementation(project(":spring-boot-project:spring-boot-http-converter")) + testFixturesImplementation(project(":spring-boot-project:spring-boot-jackson")) + + testImplementation(project(":spring-boot-project:spring-boot-freemarker")) + testImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-restclient")) + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-web-server-test")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-actuator-autoconfigure"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) + testImplementation("io.micrometer:micrometer-observation-test") + testImplementation("jakarta.servlet:jakarta.servlet-api") + testImplementation("org.aspectj:aspectjweaver") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("com.fasterxml.jackson.core:jackson-databind") + testRuntimeOnly("org.apache.tomcat.embed:tomcat-embed-jasper") +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/AbstractWebMvcEndpointHandlerMapping.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/AbstractWebMvcEndpointHandlerMapping.java index 141f859791dd..ec15ea953dbe 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/AbstractWebMvcEndpointHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.servlet; +package org.springframework.boot.webmvc.actuate.endpoint.web; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; @@ -50,8 +50,8 @@ import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.AbstractWebMvcEndpointHandlerMappingRuntimeHints; -import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.boot.webmvc.actuate.endpoint.web.AbstractWebMvcEndpointHandlerMapping.AbstractWebMvcEndpointHandlerMappingRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -84,7 +84,7 @@ * @author Madhura Bhave * @author Phillip Webb * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(AbstractWebMvcEndpointHandlerMappingRuntimeHints.class) public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappingInfoHandlerMapping @@ -316,15 +316,8 @@ public Object handle(HttpServletRequest request, @RequestBody(required = false) ServletSecurityContext securityContext = new ServletSecurityContext(request); ProducibleOperationArgumentResolver producibleOperationArgumentResolver = new ProducibleOperationArgumentResolver( () -> headers.get("Accept")); - OperationArgumentResolver serverNamespaceArgumentResolver = OperationArgumentResolver - .of(WebServerNamespace.class, () -> { - WebApplicationContext applicationContext = WebApplicationContextUtils - .getRequiredWebApplicationContext(request.getServletContext()); - return WebServerNamespace - .from(WebServerApplicationContext.getServerNamespace(applicationContext)); - }); InvocationContext invocationContext = new InvocationContext(securityContext, arguments, - serverNamespaceArgumentResolver, producibleOperationArgumentResolver); + serverNamespaceArgumentResolver(request), producibleOperationArgumentResolver); return handleResult(this.operation.invoke(invocationContext), HttpMethod.valueOf(request.getMethod())); } catch (InvalidEndpointRequestException ex) { @@ -332,6 +325,17 @@ public Object handle(HttpServletRequest request, @RequestBody(required = false) } } + private OperationArgumentResolver serverNamespaceArgumentResolver(HttpServletRequest request) { + if (ClassUtils.isPresent("org.springframework.boot.web.server.context.WebServerApplicationContext", null)) { + return OperationArgumentResolver.of(WebServerNamespace.class, () -> { + WebApplicationContext applicationContext = WebApplicationContextUtils + .getRequiredWebApplicationContext(request.getServletContext()); + return WebServerNamespace.from(WebServerApplicationContext.getServerNamespace(applicationContext)); + }); + } + return OperationArgumentResolver.of(WebServerNamespace.class, () -> null); + } + @Override public String toString() { return "Actuator web endpoint '" + this.operation.getId() + "'"; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AdditionalHealthEndpointPathsWebMvcHandlerMapping.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/AdditionalHealthEndpointPathsWebMvcHandlerMapping.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AdditionalHealthEndpointPathsWebMvcHandlerMapping.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/AdditionalHealthEndpointPathsWebMvcHandlerMapping.java index d2b1f8cb297a..114217fe1250 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AdditionalHealthEndpointPathsWebMvcHandlerMapping.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/AdditionalHealthEndpointPathsWebMvcHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.servlet; +package org.springframework.boot.webmvc.actuate.endpoint.web; import java.util.Collection; import java.util.Collections; @@ -33,7 +33,7 @@ * path. * * @author Madhura Bhave - * @since 2.6.0 + * @since 4.0.0 */ public class AdditionalHealthEndpointPathsWebMvcHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/ControllerEndpointHandlerMapping.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/ControllerEndpointHandlerMapping.java new file mode 100644 index 000000000000..f39aaa8f1006 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/ControllerEndpointHandlerMapping.java @@ -0,0 +1,165 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.actuate.endpoint.web; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import org.springframework.web.util.pattern.PathPattern; + +/** + * {@link HandlerMapping} that exposes + * {@link org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint @ControllerEndpoint} + * and + * {@link org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint @RestControllerEndpoint} + * annotated endpoints over Spring MVC. + * + * @author Phillip Webb + * @since 4.0.0 + * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support + */ +@Deprecated(since = "3.3.5", forRemoval = true) +@SuppressWarnings("removal") +public class ControllerEndpointHandlerMapping extends RequestMappingHandlerMapping { + + private static final Set READ_ONLY_ACCESS_REQUEST_METHODS = EnumSet.of(RequestMethod.GET, + RequestMethod.HEAD); + + private final EndpointMapping endpointMapping; + + private final CorsConfiguration corsConfiguration; + + private final Map handlers; + + private final EndpointAccessResolver accessResolver; + + /** + * Create a new {@link ControllerEndpointHandlerMapping} instance providing mappings + * for the specified endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + */ + public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping, + Collection endpoints, CorsConfiguration corsConfiguration) { + this(endpointMapping, endpoints, corsConfiguration, (endpointId, defaultAccess) -> Access.NONE); + } + + /** + * Create a new {@link ControllerEndpointHandlerMapping} instance providing mappings + * for the specified endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param endpointAccessResolver resolver for endpoint access + */ + public ControllerEndpointHandlerMapping(EndpointMapping endpointMapping, + Collection endpoints, CorsConfiguration corsConfiguration, + EndpointAccessResolver endpointAccessResolver) { + Assert.notNull(endpointMapping, "'endpointMapping' must not be null"); + Assert.notNull(endpoints, "'endpoints' must not be null"); + this.endpointMapping = endpointMapping; + this.handlers = getHandlers(endpoints); + this.corsConfiguration = corsConfiguration; + this.accessResolver = endpointAccessResolver; + setOrder(-100); + } + + private Map getHandlers(Collection endpoints) { + Map handlers = new LinkedHashMap<>(); + endpoints.forEach((endpoint) -> handlers.put(endpoint.getController(), endpoint)); + return Collections.unmodifiableMap(handlers); + } + + @Override + protected void initHandlerMethods() { + this.handlers.keySet().forEach(this::detectHandlerMethods); + } + + @Override + protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { + ExposableControllerEndpoint endpoint = this.handlers.get(handler); + Access access = this.accessResolver.accessFor(endpoint.getEndpointId(), endpoint.getDefaultAccess()); + if (access == Access.NONE) { + return; + } + if (access == Access.READ_ONLY) { + mapping = withReadOnlyAccess(access, mapping); + if (CollectionUtils.isEmpty(mapping.getMethodsCondition().getMethods())) { + return; + } + } + mapping = withEndpointMappedPatterns(endpoint, mapping); + super.registerHandlerMethod(handler, method, mapping); + } + + private RequestMappingInfo withReadOnlyAccess(Access access, RequestMappingInfo mapping) { + Set methods = mapping.getMethodsCondition().getMethods(); + Set modifiedMethods = new HashSet<>(methods); + if (modifiedMethods.isEmpty()) { + modifiedMethods.addAll(READ_ONLY_ACCESS_REQUEST_METHODS); + } + else { + modifiedMethods.retainAll(READ_ONLY_ACCESS_REQUEST_METHODS); + } + return mapping.mutate().methods(modifiedMethods.toArray(new RequestMethod[0])).build(); + } + + private RequestMappingInfo withEndpointMappedPatterns(ExposableControllerEndpoint endpoint, + RequestMappingInfo mapping) { + Set patterns = mapping.getPathPatternsCondition().getPatterns(); + if (patterns.isEmpty()) { + patterns = Collections.singleton(getPatternParser().parse("")); + } + String[] endpointMappedPatterns = patterns.stream() + .map((pattern) -> getEndpointMappedPattern(endpoint, pattern)) + .toArray(String[]::new); + return mapping.mutate().paths(endpointMappedPatterns).build(); + } + + private String getEndpointMappedPattern(ExposableControllerEndpoint endpoint, PathPattern pattern) { + return this.endpointMapping.createSubPath(endpoint.getRootPath() + pattern); + } + + @Override + protected boolean hasCorsConfigurationSource(Object handler) { + return this.corsConfiguration != null; + } + + @Override + protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mapping) { + return this.corsConfiguration; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/WebMvcEndpointHandlerMapping.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/WebMvcEndpointHandlerMapping.java index 2963b5446ff0..10b48b506c32 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/WebMvcEndpointHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.servlet; +package org.springframework.boot.webmvc.actuate.endpoint.web; import java.util.Collection; import java.util.Collections; @@ -34,7 +34,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.WebMvcEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping.WebMvcEndpointHandlerMappingRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; @@ -46,7 +46,7 @@ * * @author Andy Wilkinson * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(WebMvcEndpointHandlerMappingRuntimeHints.class) public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/package-info.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/package-info.java new file mode 100644 index 000000000000..8c780cafcb42 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/endpoint/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring MVC support for actuator endpoints. + */ +package org.springframework.boot.webmvc.actuate.endpoint.web; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletHandlerMappings.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletHandlerMappings.java similarity index 80% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletHandlerMappings.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletHandlerMappings.java index 58b6477ec4af..b9c343a25072 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletHandlerMappings.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletHandlerMappings.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.webmvc.actuate.mappings; import java.util.Collections; import java.util.List; @@ -26,10 +26,11 @@ import org.apache.catalina.Context; import org.apache.catalina.core.StandardWrapper; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServer; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.undertow.servlet.UndertowServletWebServer; import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.util.ClassUtils; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.HandlerMapping; @@ -43,6 +44,13 @@ */ final class DispatcherServletHandlerMappings { + private static final boolean TOMCAT_WEB_SERVER_PRESENT = ClassUtils.isPresent( + "org.springframework.boot.tomcat.TomcatWebServer", DispatcherServletHandlerMappings.class.getClassLoader()); + + private static final boolean UNDERTOW_WEB_SERVER_PRESENT = ClassUtils.isPresent( + "org.springframework.boot.undertow.UndertowWebServer", + DispatcherServletHandlerMappings.class.getClassLoader()); + private final String name; private final DispatcherServlet dispatcherServlet; @@ -70,10 +78,10 @@ private void initializeDispatcherServletIfPossible() { return; } WebServer webServer = webServerApplicationContext.getWebServer(); - if (webServer instanceof UndertowServletWebServer undertowServletWebServer) { + if (UNDERTOW_WEB_SERVER_PRESENT && webServer instanceof UndertowServletWebServer undertowServletWebServer) { new UndertowServletInitializer(undertowServletWebServer).initializeServlet(this.name); } - else if (webServer instanceof TomcatWebServer tomcatWebServer) { + else if (TOMCAT_WEB_SERVER_PRESENT && webServer instanceof TomcatWebServer tomcatWebServer) { new TomcatServletInitializer(tomcatWebServer).initializeServlet(this.name); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletMappingDescription.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletMappingDescription.java similarity index 94% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletMappingDescription.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletMappingDescription.java index b40aa9f481a5..8ad05a65e620 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletMappingDescription.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletMappingDescription.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.webmvc.actuate.mappings; import org.springframework.web.servlet.DispatcherServlet; @@ -22,7 +22,7 @@ * A description of a mapping known to a {@link DispatcherServlet}. * * @author Andy Wilkinson - * @since 2.0.0 + * @since 4.0.0 */ public class DispatcherServletMappingDescription { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletMappingDetails.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletMappingDetails.java similarity index 95% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletMappingDetails.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletMappingDetails.java index c85811107347..930ae0eb226c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletMappingDetails.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletMappingDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.webmvc.actuate.mappings; import org.springframework.boot.actuate.web.mappings.HandlerMethodDescription; import org.springframework.web.servlet.DispatcherServlet; @@ -24,7 +24,7 @@ * * @author Andy Wilkinson * @author Xiong Tang - * @since 2.0.0 + * @since 4.0.0 */ public class DispatcherServletMappingDetails { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProvider.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletsMappingDescriptionProvider.java similarity index 97% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProvider.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletsMappingDescriptionProvider.java index cc96b8e0f717..fd839c018b8a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProvider.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletsMappingDescriptionProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.webmvc.actuate.mappings; import java.util.ArrayList; import java.util.Collections; @@ -34,8 +34,8 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.web.mappings.HandlerMethodDescription; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; -import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.DispatcherServletsMappingDescriptionProviderRuntimeHints; import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.boot.webmvc.actuate.mappings.DispatcherServletsMappingDescriptionProvider.DispatcherServletsMappingDescriptionProviderRuntimeHints; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.core.io.Resource; @@ -61,7 +61,7 @@ * @author Andy Wilkinson * @author Stephane Nicoll * @author Xiong Tang - * @since 2.0.0 + * @since 4.0.0 */ @ImportRuntimeHints(DispatcherServletsMappingDescriptionProviderRuntimeHints.class) public class DispatcherServletsMappingDescriptionProvider implements MappingDescriptionProvider { diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/HandlerFunctionDescription.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/HandlerFunctionDescription.java new file mode 100644 index 000000000000..4bc05465da8a --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/HandlerFunctionDescription.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.actuate.mappings; + +import org.springframework.web.servlet.function.HandlerFunction; + +/** + * Description of a {@link HandlerFunction}. + * + * @author Xiong Tang + * @since 4.0.0 + */ +public class HandlerFunctionDescription { + + private final String className; + + HandlerFunctionDescription(HandlerFunction handlerFunction) { + this.className = getHandlerFunctionClassName(handlerFunction); + } + + private static String getHandlerFunctionClassName(HandlerFunction handlerFunction) { + Class functionClass = handlerFunction.getClass(); + String canonicalName = functionClass.getCanonicalName(); + return (canonicalName != null) ? canonicalName : functionClass.getName(); + } + + public String getClassName() { + return this.className; + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/RequestMappingConditionsDescription.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/RequestMappingConditionsDescription.java new file mode 100644 index 000000000000..38384973eda4 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/RequestMappingConditionsDescription.java @@ -0,0 +1,159 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.actuate.mappings; + +import java.util.List; +import java.util.Set; + +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.mvc.condition.MediaTypeExpression; +import org.springframework.web.servlet.mvc.condition.NameValueExpression; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; + +/** + * Description of the conditions of a {@link RequestMappingInfo}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class RequestMappingConditionsDescription { + + private final List consumes; + + private final List headers; + + private final Set methods; + + private final List params; + + private final Set patterns; + + private final List produces; + + RequestMappingConditionsDescription(RequestMappingInfo requestMapping) { + this.consumes = requestMapping.getConsumesCondition() + .getExpressions() + .stream() + .map(MediaTypeExpressionDescription::new) + .toList(); + this.headers = requestMapping.getHeadersCondition() + .getExpressions() + .stream() + .map(NameValueExpressionDescription::new) + .toList(); + this.methods = requestMapping.getMethodsCondition().getMethods(); + this.params = requestMapping.getParamsCondition() + .getExpressions() + .stream() + .map(NameValueExpressionDescription::new) + .toList(); + this.patterns = extractPathPatterns(requestMapping); + this.produces = requestMapping.getProducesCondition() + .getExpressions() + .stream() + .map(MediaTypeExpressionDescription::new) + .toList(); + } + + @SuppressWarnings({ "removal", "deprecation" }) + private Set extractPathPatterns(RequestMappingInfo requestMapping) { + org.springframework.web.servlet.mvc.condition.PatternsRequestCondition patternsCondition = requestMapping + .getPatternsCondition(); + return (patternsCondition != null) ? patternsCondition.getPatterns() + : requestMapping.getPathPatternsCondition().getPatternValues(); + } + + public List getConsumes() { + return this.consumes; + } + + public List getHeaders() { + return this.headers; + } + + public Set getMethods() { + return this.methods; + } + + public List getParams() { + return this.params; + } + + public Set getPatterns() { + return this.patterns; + } + + public List getProduces() { + return this.produces; + } + + /** + * A description of a {@link MediaTypeExpression} in a request mapping condition. + */ + public static class MediaTypeExpressionDescription { + + private final String mediaType; + + private final boolean negated; + + MediaTypeExpressionDescription(MediaTypeExpression expression) { + this.mediaType = expression.getMediaType().toString(); + this.negated = expression.isNegated(); + } + + public String getMediaType() { + return this.mediaType; + } + + public boolean isNegated() { + return this.negated; + } + + } + + /** + * A description of a {@link NameValueExpression} in a request mapping condition. + */ + public static class NameValueExpressionDescription { + + private final String name; + + private final Object value; + + private final boolean negated; + + NameValueExpressionDescription(NameValueExpression expression) { + this.name = expression.getName(); + this.value = expression.getValue(); + this.negated = expression.isNegated(); + } + + public String getName() { + return this.name; + } + + public Object getValue() { + return this.value; + } + + public boolean isNegated() { + return this.negated; + } + + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/package-info.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/package-info.java new file mode 100644 index 000000000000..bfd9d130d2dc --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/actuate/mappings/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Actuator request mappings support for Spring MVC. + */ +package org.springframework.boot.webmvc.actuate.mappings; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletAutoConfiguration.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletAutoConfiguration.java index 45f440149f9f..1523b0f26e9e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.util.Arrays; import java.util.List; @@ -60,10 +60,10 @@ * @author Dave Syer * @author Stephane Nicoll * @author Brian Clozel - * @since 2.0.0 + * @since 4.0.0 */ @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) -@AutoConfiguration(after = ServletWebServerFactoryAutoConfiguration.class) +@AutoConfiguration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass(DispatcherServlet.class) public class DispatcherServletAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletPath.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletPath.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletPath.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletPath.java index bb5377cde8ad..67b9d6c4ad1d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletPath.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletPath.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.web.servlet.DispatcherServlet; @@ -26,7 +26,7 @@ * * @author Madhura Bhave * @author Stephane Nicoll - * @since 2.0.4 + * @since 4.0.0 */ @FunctionalInterface public interface DispatcherServletPath { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletRegistrationBean.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletRegistrationBean.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletRegistrationBean.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletRegistrationBean.java index 73208b392bd5..6e5ad0e6616a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletRegistrationBean.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletRegistrationBean.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.util.Collection; @@ -27,7 +27,7 @@ * registers the servlet and exposes {@link DispatcherServletPath} information. * * @author Phillip Webb - * @since 2.0.4 + * @since 4.0.0 */ public class DispatcherServletRegistrationBean extends ServletRegistrationBean implements DispatcherServletPath { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/JspTemplateAvailabilityProvider.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/JspTemplateAvailabilityProvider.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/JspTemplateAvailabilityProvider.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/JspTemplateAvailabilityProvider.java index e500f59bc244..6857277c6054 100755 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/JspTemplateAvailabilityProvider.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/JspTemplateAvailabilityProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.io.File; @@ -30,7 +30,7 @@ * @author Andy Wilkinson * @author Stephane Nicoll * @author Madhura Bhave - * @since 2.0.0 + * @since 4.0.0 */ public class JspTemplateAvailabilityProvider implements TemplateAvailabilityProvider { diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/ProblemDetailsExceptionHandler.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/ProblemDetailsExceptionHandler.java new file mode 100644 index 000000000000..e7b58087008c --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/ProblemDetailsExceptionHandler.java @@ -0,0 +1,31 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +/** + * {@code @ControllerAdvice} annotated {@link ResponseEntityExceptionHandler} that is + * auto-configured for problem details support. + * + * @author Brian Clozel + */ +@ControllerAdvice +class ProblemDetailsExceptionHandler extends ResponseEntityExceptionHandler { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcAutoConfiguration.java index 465684b8c319..bc4ffeb1addd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.time.Duration; import java.util.List; @@ -37,13 +37,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; -import org.springframework.boot.autoconfigure.validation.ValidatorAdapter; import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.autoconfigure.web.WebProperties.Resources; @@ -51,13 +49,15 @@ import org.springframework.boot.autoconfigure.web.WebResourcesRuntimeHints; import org.springframework.boot.autoconfigure.web.format.DateTimeFormatters; import org.springframework.boot.autoconfigure.web.format.WebConversionService; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.Format; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.convert.ApplicationConversionService; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; +import org.springframework.boot.servlet.filter.OrderedFormContentFilter; +import org.springframework.boot.servlet.filter.OrderedHiddenHttpMethodFilter; +import org.springframework.boot.servlet.filter.OrderedRequestContextFilter; +import org.springframework.boot.validation.autoconfigure.ValidatorAdapter; import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.filter.OrderedFormContentFilter; -import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter; -import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; +import org.springframework.boot.webmvc.autoconfigure.WebMvcProperties.Format; import org.springframework.context.ApplicationContext; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.annotation.Bean; @@ -134,10 +134,10 @@ * @author Bruce Brouwer * @author Artsiom Yudovin * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, - ValidationAutoConfiguration.class }) +@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class }, + afterName = "org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration") @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @@ -515,7 +515,9 @@ public FormattingConversionService mvcConversionService() { @Bean @Override public Validator mvcValidator() { - if (!ClassUtils.isPresent("jakarta.validation.Validator", getClass().getClassLoader())) { + if (!ClassUtils.isPresent("jakarta.validation.Validator", getClass().getClassLoader()) + || !ClassUtils.isPresent("org.springframework.boot.validation.autoconfigure.ValidatorAdapter", + getClass().getClassLoader())) { return super.mvcValidator(); } return ValidatorAdapter.get(getApplicationContext(), getValidator()); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcObservationAutoConfiguration.java similarity index 79% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcObservationAutoConfiguration.java index b2ecd3b25eff..73e35bbe24d1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcObservationAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.config.MeterFilter; @@ -23,20 +23,16 @@ import jakarta.servlet.DispatcherType; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; -import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilterBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.metrics.OnlyOnceLoggingDenyMeterFilter; +import org.springframework.boot.metrics.autoconfigure.MetricsProperties; +import org.springframework.boot.observation.autoconfigure.ObservationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -54,10 +50,13 @@ * @author Brian Clozel * @author Jon Schneider * @author Dmytro Nosan - * @since 3.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, - SimpleMetricsExportAutoConfiguration.class, ObservationAutoConfiguration.class }) +@AutoConfiguration( + afterName = { "org.springframework.boot.metrics.autoconfigure.CompositeMeterRegistryAutoConfiguration", + "org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration", + "org.springframework.boot.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration", + "org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration" }) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass({ DispatcherServlet.class, Observation.class }) @ConditionalOnBean(ObservationRegistry.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcProperties.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcProperties.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcProperties.java index 53bdfde1eedd..675db7998290 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcProperties.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.time.Duration; import java.util.ArrayList; @@ -36,7 +36,7 @@ * @author Eddú Meléndez * @author Brian Clozel * @author Vedran Pavic - * @since 2.0.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.mvc") public class WebMvcProperties { @@ -424,8 +424,6 @@ public void setDateTime(String dateTime) { /** * Matching strategy options. - * - * @since 2.4.0 */ public enum MatchingStrategy { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcRegistrations.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcRegistrations.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcRegistrations.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcRegistrations.java index db660b5aa32c..4bde71dae0c7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcRegistrations.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WebMvcRegistrations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -34,8 +34,8 @@ * impossible to choose from redundant MVC components. * * @author Brian Clozel - * @since 2.0.0 - * @see org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration + * @since 4.0.0 + * @see org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration.EnableWebMvcConfiguration */ public interface WebMvcRegistrations { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePage.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePage.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePage.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePage.java index ee24479e4769..b648bc29a32f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePage.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePage.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; import org.springframework.context.ApplicationContext; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMapping.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageHandlerMapping.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMapping.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageHandlerMapping.java index ce8bf84793aa..8be5fac7f346 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMapping.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.util.Collections; import java.util.List; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMapping.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageNotAcceptableHandlerMapping.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMapping.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageNotAcceptableHandlerMapping.java index b7391118def0..5189da21c1fa 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMapping.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageNotAcceptableHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/WebMvcHealthEndpointExtensionAutoConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/WebMvcHealthEndpointExtensionAutoConfiguration.java new file mode 100644 index 000000000000..414675e458ea --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/WebMvcHealthEndpointExtensionAutoConfiguration.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web; + +import java.util.Collection; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; +import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; +import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; +import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.HealthEndpointGroups; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.webmvc.actuate.endpoint.web.AdditionalHealthEndpointPathsWebMvcHandlerMapping; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for {@link HealthEndpoint} web + * extension with Spring MVC. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnClass(HealthEndpoint.class) +@ConditionalOnBean({ HealthEndpoint.class, WebEndpointsSupplier.class, HealthEndpointGroups.class }) +@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB) +public class WebMvcHealthEndpointExtensionAutoConfiguration { + + @Bean + public AdditionalHealthEndpointPathsWebMvcHandlerMapping healthEndpointWebMvcHandlerMapping( + WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) { + ExposableWebEndpoint health = getHealthEndpoint(webEndpointsSupplier); + return new AdditionalHealthEndpointPathsWebMvcHandlerMapping(health, + groups.getAllWithAdditionalPath(WebServerNamespace.SERVER)); + } + + private static ExposableWebEndpoint getHealthEndpoint(WebEndpointsSupplier webEndpointsSupplier) { + Collection webEndpoints = webEndpointsSupplier.getEndpoints(); + return webEndpoints.stream() + .filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID)) + .findFirst() + .orElse(null); + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/package-info.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/package-info.java new file mode 100644 index 000000000000..8ab6c3a1979e --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring MVC actuator web endpoint support. + */ +package org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerAdapter.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerAdapter.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerAdapter.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerAdapter.java index 4c85b3457427..9cf64682582e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerAdapter.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolver.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerExceptionResolver.java similarity index 95% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolver.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerExceptionResolver.java index c6ccb5ff100c..0901445d028c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolver.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerExceptionResolver.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import java.util.ArrayList; import java.util.List; @@ -26,7 +26,7 @@ import org.springframework.beans.factory.HierarchicalBeanFactory; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; +import org.springframework.boot.webmvc.error.DefaultErrorAttributes; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerMapping.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerMapping.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerMapping.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerMapping.java index b0006df02406..84dd53c9f3ef 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerMapping.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import java.util.ArrayList; import java.util.List; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementErrorEndpoint.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ManagementErrorEndpoint.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementErrorEndpoint.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ManagementErrorEndpoint.java index 3ea6a137ceee..b76b627ea14a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementErrorEndpoint.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ManagementErrorEndpoint.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import java.util.Map; import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.boot.webmvc.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorController; import org.springframework.stereotype.Controller; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.RequestMapping; @@ -37,7 +37,7 @@ * @author Dave Syer * @author Scott Frederick * @author Moritz Halbritter - * @since 2.0.0 + * @since 4.0.0 */ @Controller public class ManagementErrorEndpoint { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfiguration.java similarity index 89% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfiguration.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfiguration.java index 47bc039d097d..f0fbadf17494 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfiguration.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; @@ -24,14 +24,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean; -import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.servlet.filter.OrderedRequestContextFilter; +import org.springframework.boot.web.error.ErrorPage; import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletRegistrationBean; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.context.annotation.Bean; import org.springframework.core.Ordered; import org.springframework.web.context.request.RequestContextListener; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfiguration.java similarity index 81% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfiguration.java index 61bc56ed1d5e..1452690924fb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfiguration.java @@ -14,13 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; @@ -43,16 +44,16 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; -import org.springframework.boot.actuate.endpoint.web.servlet.AdditionalHealthEndpointPathsWebMvcHandlerMapping; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpointGroups; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.webmvc.actuate.endpoint.web.AdditionalHealthEndpointPathsWebMvcHandlerMapping; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Role; import org.springframework.core.env.Environment; @@ -68,11 +69,11 @@ * * @author Andy Wilkinson * @author Phillip Webb - * @since 2.0.0 + * @author Stephane Nicoll + * @since 4.0.0 */ @ManagementContextConfiguration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = Type.SERVLET) -@ConditionalOnClass(DispatcherServlet.class) @ConditionalOnBean({ DispatcherServlet.class, WebEndpointsSupplier.class }) @EnableConfigurationProperties(CorsEndpointProperties.class) public class WebMvcEndpointManagementContextConfiguration { @@ -80,7 +81,7 @@ public class WebMvcEndpointManagementContextConfiguration { @Bean @ConditionalOnMissingBean @SuppressWarnings("removal") - public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, + WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier servletEndpointsSupplier, org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, @@ -108,7 +109,7 @@ private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProp @ConditionalOnManagementPort(ManagementPortType.DIFFERENT) @ConditionalOnBean(HealthEndpoint.class) @ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB) - public AdditionalHealthEndpointPathsWebMvcHandlerMapping managementHealthEndpointWebMvcHandlerMapping( + AdditionalHealthEndpointPathsWebMvcHandlerMapping managementHealthEndpointWebMvcHandlerMapping( WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups groups) { Collection webEndpoints = webEndpointsSupplier.getEndpoints(); ExposableWebEndpoint healthEndpoint = webEndpoints.stream() @@ -127,16 +128,27 @@ private boolean isHealthEndpoint(ExposableWebEndpoint endpoint) { @ConditionalOnMissingBean @SuppressWarnings("removal") @Deprecated(since = "3.3.5", forRemoval = true) - public org.springframework.boot.actuate.endpoint.web.servlet.ControllerEndpointHandlerMapping controllerEndpointHandlerMapping( + org.springframework.boot.webmvc.actuate.endpoint.web.ControllerEndpointHandlerMapping controllerEndpointHandlerMapping( org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier controllerEndpointsSupplier, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, EndpointAccessResolver endpointAccessResolver) { EndpointMapping endpointMapping = new EndpointMapping(webEndpointProperties.getBasePath()); - return new org.springframework.boot.actuate.endpoint.web.servlet.ControllerEndpointHandlerMapping( + return new org.springframework.boot.webmvc.actuate.endpoint.web.ControllerEndpointHandlerMapping( endpointMapping, controllerEndpointsSupplier.getEndpoints(), corsProperties.toCorsConfiguration(), endpointAccessResolver); } + @Bean + @SuppressWarnings("removal") + org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar servletEndpointRegistrar( + WebEndpointProperties properties, + org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier servletEndpointsSupplier, + DispatcherServletPath dispatcherServletPath, EndpointAccessResolver endpointAccessResolver) { + return new org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar( + dispatcherServletPath.getRelativePath(properties.getBasePath()), + servletEndpointsSupplier.getEndpoints(), endpointAccessResolver); + } + @Bean @ConditionalOnBean(EndpointObjectMapper.class) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) @@ -172,12 +184,15 @@ public void configureMessageConverters(List> converters) } } - @SuppressWarnings({ "removal", "deprecation" }) + @SuppressWarnings("removal") private void configure(org.springframework.http.converter.json.MappingJackson2HttpMessageConverter converter) { - converter.registerObjectMappersForType(OperationResponseBody.class, (associations) -> { - ObjectMapper objectMapper = this.endpointObjectMapper.get(); - MEDIA_TYPES.forEach((mimeType) -> associations.put(mimeType, objectMapper)); - }); + this.endpointObjectMapper.getSupportedTypes() + .forEach((type) -> converter.registerObjectMappersForType(type, this::registerForAllMimeTypes)); + } + + private void registerForAllMimeTypes(Map registrar) { + ObjectMapper objectMapper = this.endpointObjectMapper.get(); + MEDIA_TYPES.forEach((mimeType) -> registrar.put(mimeType, objectMapper)); } } diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcMappingsAutoConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcMappingsAutoConfiguration.java new file mode 100644 index 000000000000..73746f087371 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcMappingsAutoConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.web; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; +import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.webmvc.actuate.mappings.DispatcherServletsMappingDescriptionProvider; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.DispatcherServlet; + +/** + * {@link EnableAutoConfiguration Auto-configuration} to describe Web MVC + * {@link MappingDescriptionProvider mappings}. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +@AutoConfiguration(after = DispatcherServletAutoConfiguration.class) +@ConditionalOnClass({ ConditionalOnAvailableEndpoint.class, DispatcherServlet.class, MappingsEndpoint.class }) +@ConditionalOnAvailableEndpoint(MappingsEndpoint.class) +@ConditionalOnBean(DispatcherServlet.class) +@ConditionalOnWebApplication(type = Type.SERVLET) +public class WebMvcMappingsAutoConfiguration { + + @Bean + DispatcherServletsMappingDescriptionProvider dispatcherServletMappingDescriptionProvider() { + return new DispatcherServletsMappingDescriptionProvider(); + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/package-info.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/package-info.java new file mode 100644 index 000000000000..c361242cee38 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring MVC-based actuator infrastructure. + */ +package org.springframework.boot.webmvc.autoconfigure.actuate.web; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/AbstractErrorController.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/AbstractErrorController.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/AbstractErrorController.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/AbstractErrorController.java index 030f939bef71..74a2da8a9e65 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/AbstractErrorController.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/AbstractErrorController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.util.ArrayList; import java.util.List; @@ -25,8 +25,8 @@ import jakarta.servlet.http.HttpServletResponse; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.boot.webmvc.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorController; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; @@ -42,7 +42,7 @@ * @author Phillip Webb * @author Scott Frederick * @author Moritz Halbritter - * @since 1.3.0 + * @since 4.0.0 * @see ErrorAttributes */ public abstract class AbstractErrorController implements ErrorController { @@ -106,7 +106,6 @@ protected boolean getErrorsParameter(HttpServletRequest request) { * Returns whether the path parameter is set. * @param request the request * @return whether the path parameter is set - * @since 3.3.0 */ protected boolean getPathParameter(HttpServletRequest request) { return getBooleanParameter(request, "path"); @@ -142,7 +141,6 @@ protected HttpStatus getStatus(HttpServletRequest request) { * @param model the suggested model * @return a specific {@link ModelAndView} or {@code null} if the default should be * used - * @since 1.4.0 */ protected ModelAndView resolveErrorView(HttpServletRequest request, HttpServletResponse response, HttpStatus status, Map model) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorController.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorController.java index f08f65a1c3fc..3b600cd36589 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.util.Collections; import java.util.List; @@ -26,8 +26,8 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; +import org.springframework.boot.web.error.ErrorPageRegistrar; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -41,8 +41,9 @@ /** * Basic global error {@link Controller @Controller}, rendering {@link ErrorAttributes}. * More specific errors can be handled either using Spring MVC abstractions (e.g. - * {@code @ExceptionHandler}) or by adding servlet - * {@link AbstractServletWebServerFactory#setErrorPages server error pages}. + * {@code @ExceptionHandler}) or by + * {@link ErrorPageRegistrar#registerErrorPages(org.springframework.boot.web.error.ErrorPageRegistry) + * registering error pages}. * * @author Dave Syer * @author Phillip Webb @@ -50,7 +51,7 @@ * @author Stephane Nicoll * @author Scott Frederick * @author Moritz Halbritter - * @since 1.0.0 + * @since 4.0.0 * @see ErrorAttributes * @see ErrorProperties */ @@ -173,7 +174,6 @@ protected boolean isIncludeBindingErrors(HttpServletRequest request, MediaType p * @param request the source request * @param produces the media type produced (or {@code MediaType.ALL}) * @return if the path attribute should be included - * @since 3.3.0 */ protected boolean isIncludePath(HttpServletRequest request, MediaType produces) { return switch (getErrorProperties().getIncludePath()) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewResolver.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewResolver.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewResolver.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewResolver.java index f38662d6b093..c59c69529fcb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewResolver.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewResolver.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.util.Collections; import java.util.EnumMap; @@ -53,7 +53,7 @@ * * @author Phillip Webb * @author Andy Wilkinson - * @since 1.4.0 + * @since 4.0.0 */ public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered { @@ -78,7 +78,6 @@ public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered { * Create a new {@link DefaultErrorViewResolver} instance. * @param applicationContext the source application context * @param resources resource properties - * @since 2.4.0 */ public DefaultErrorViewResolver(ApplicationContext applicationContext, Resources resources) { Assert.notNull(applicationContext, "'applicationContext' must not be null"); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorMvcAutoConfiguration.java similarity index 91% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorMvcAutoConfiguration.java index fa107c415c55..e2d2152cb448 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorMvcAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.nio.charset.StandardCharsets; import java.util.Map; @@ -44,20 +44,19 @@ import org.springframework.boot.autoconfigure.condition.SpringBootCondition; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.autoconfigure.web.WebProperties.Resources; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.server.ErrorPage; -import org.springframework.boot.web.server.ErrorPageRegistrar; -import org.springframework.boot.web.server.ErrorPageRegistry; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.boot.web.error.ErrorPage; +import org.springframework.boot.web.error.ErrorPageRegistrar; +import org.springframework.boot.web.error.ErrorPageRegistry; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcProperties; +import org.springframework.boot.webmvc.error.DefaultErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorController; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; @@ -80,12 +79,12 @@ * @author Stephane Nicoll * @author Brian Clozel * @author Scott Frederick - * @since 1.0.0 + * @since 4.0.0 */ // Load before the main WebMvcAutoConfiguration so that the error View is available @AutoConfiguration(before = WebMvcAutoConfiguration.class) @ConditionalOnWebApplication(type = Type.SERVLET) -@ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) +@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, ServerProperties.class }) @EnableConfigurationProperties({ ServerProperties.class, WebMvcProperties.class }) public class ErrorMvcAutoConfiguration { @@ -253,7 +252,7 @@ public String getContentType() { } /** - * {@link WebServerFactoryCustomizer} that configures the server's error pages. + * {@link ErrorPageRegistrar} that configures the server's error pages. */ static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorViewResolver.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorViewResolver.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorViewResolver.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorViewResolver.java index a79552d84410..5c5e0fd5a111 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorViewResolver.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorViewResolver.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.util.Map; @@ -27,7 +27,7 @@ * Interface that can be implemented by beans that resolve error views. * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 */ @FunctionalInterface public interface ErrorViewResolver { diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/package-info.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/package-info.java new file mode 100644 index 000000000000..d89587dc7430 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/error/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring MVC error handling. + */ +package org.springframework.boot.webmvc.autoconfigure.error; diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/package-info.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/package-info.java new file mode 100644 index 000000000000..dbd8caf8c846 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring MVC. + */ +package org.springframework.boot.webmvc.autoconfigure; diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/DefaultErrorAttributes.java new file mode 100644 index 000000000000..4f70c0968910 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/DefaultErrorAttributes.java @@ -0,0 +1,237 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.error; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.springframework.boot.web.error.Error; +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.error.ErrorAttributeOptions.Include; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; +import org.springframework.validation.BindingResult; +import org.springframework.validation.method.MethodValidationResult; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ModelAndView; + +/** + * Default implementation of {@link ErrorAttributes}. Provides the following attributes + * when possible: + *
      + *
    • timestamp - The time that the errors were extracted
    • + *
    • status - The status code
    • + *
    • error - The error reason
    • + *
    • exception - The class name of the root exception (if configured)
    • + *
    • message - The exception message (if configured)
    • + *
    • errors - Any validation errors wrapped in {@link Error}, derived from a + * {@link BindingResult} or {@link MethodValidationResult} exception (if configured)
    • + *
    • trace - The exception stack trace (if configured)
    • + *
    • path - The URL path when the exception was raised
    • + *
    + * + * @author Phillip Webb + * @author Dave Syer + * @author Stephane Nicoll + * @author Vedran Pavic + * @author Scott Frederick + * @author Moritz Halbritter + * @author Yanming Zhou + * @author Yongjun Hong + * @since 4.0.0 + * @see ErrorAttributes + */ +@Order(Ordered.HIGHEST_PRECEDENCE) +public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered { + + private static final String ERROR_INTERNAL_ATTRIBUTE = DefaultErrorAttributes.class.getName() + ".ERROR"; + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + + @Override + public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, + Exception ex) { + storeErrorAttributes(request, ex); + return null; + } + + private void storeErrorAttributes(HttpServletRequest request, Exception ex) { + request.setAttribute(ERROR_INTERNAL_ATTRIBUTE, ex); + } + + @Override + public Map getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { + Map errorAttributes = getErrorAttributes(webRequest, options.isIncluded(Include.STACK_TRACE)); + options.retainIncluded(errorAttributes); + return errorAttributes; + } + + private Map getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { + Map errorAttributes = new LinkedHashMap<>(); + errorAttributes.put("timestamp", new Date()); + addStatus(errorAttributes, webRequest); + addErrorDetails(errorAttributes, webRequest, includeStackTrace); + addPath(errorAttributes, webRequest); + return errorAttributes; + } + + private void addStatus(Map errorAttributes, RequestAttributes requestAttributes) { + Integer status = getAttribute(requestAttributes, RequestDispatcher.ERROR_STATUS_CODE); + if (status == null) { + errorAttributes.put("status", 999); + errorAttributes.put("error", "None"); + return; + } + errorAttributes.put("status", status); + try { + errorAttributes.put("error", HttpStatus.valueOf(status).getReasonPhrase()); + } + catch (Exception ex) { + // Unable to obtain a reason + errorAttributes.put("error", "Http Status " + status); + } + } + + private void addErrorDetails(Map errorAttributes, WebRequest webRequest, + boolean includeStackTrace) { + Throwable error = getError(webRequest); + if (error != null) { + while (error instanceof ServletException && error.getCause() != null) { + error = error.getCause(); + } + errorAttributes.put("exception", error.getClass().getName()); + if (includeStackTrace) { + addStackTrace(errorAttributes, error); + } + } + addErrorMessage(errorAttributes, webRequest, error); + } + + private void addErrorMessage(Map errorAttributes, WebRequest webRequest, Throwable error) { + BindingResult bindingResult = extractBindingResult(error); + if (bindingResult != null) { + addMessageAndErrorsFromBindingResult(errorAttributes, bindingResult); + return; + } + MethodValidationResult methodValidationResult = extractMethodValidationResult(error); + if (methodValidationResult != null) { + addMessageAndErrorsFromMethodValidationResult(errorAttributes, methodValidationResult); + return; + } + addExceptionErrorMessage(errorAttributes, webRequest, error); + } + + private void addMessageAndErrorsFromBindingResult(Map errorAttributes, BindingResult result) { + errorAttributes.put("message", "Validation failed for object='%s'. Error count: %s" + .formatted(result.getObjectName(), result.getAllErrors().size())); + errorAttributes.put("errors", Error.wrap(result.getAllErrors())); + } + + private void addMessageAndErrorsFromMethodValidationResult(Map errorAttributes, + MethodValidationResult result) { + errorAttributes.put("message", "Validation failed for method='%s'. Error count: %s" + .formatted(result.getMethod(), result.getAllErrors().size())); + errorAttributes.put("errors", Error.wrap(result.getAllErrors())); + } + + private void addExceptionErrorMessage(Map errorAttributes, WebRequest webRequest, Throwable error) { + errorAttributes.put("message", getMessage(webRequest, error)); + } + + /** + * Returns the message to be included as the value of the {@code message} error + * attribute. By default the returned message is the first of the following that is + * not empty: + *
      + *
    1. Value of the {@link RequestDispatcher#ERROR_MESSAGE} request attribute. + *
    2. Message of the given {@code error}. + *
    3. {@code No message available}. + *
    + * @param webRequest current request + * @param error current error, if any + * @return message to include in the error attributes + */ + protected String getMessage(WebRequest webRequest, Throwable error) { + Object message = getAttribute(webRequest, RequestDispatcher.ERROR_MESSAGE); + if (!ObjectUtils.isEmpty(message)) { + return message.toString(); + } + if (error != null && StringUtils.hasLength(error.getMessage())) { + return error.getMessage(); + } + return "No message available"; + } + + private BindingResult extractBindingResult(Throwable error) { + if (error instanceof BindingResult bindingResult) { + return bindingResult; + } + return null; + } + + private MethodValidationResult extractMethodValidationResult(Throwable error) { + if (error instanceof MethodValidationResult methodValidationResult) { + return methodValidationResult; + } + return null; + } + + private void addStackTrace(Map errorAttributes, Throwable error) { + StringWriter stackTrace = new StringWriter(); + error.printStackTrace(new PrintWriter(stackTrace)); + stackTrace.flush(); + errorAttributes.put("trace", stackTrace.toString()); + } + + private void addPath(Map errorAttributes, RequestAttributes requestAttributes) { + String path = getAttribute(requestAttributes, RequestDispatcher.ERROR_REQUEST_URI); + if (path != null) { + errorAttributes.put("path", path); + } + } + + @Override + public Throwable getError(WebRequest webRequest) { + Throwable exception = getAttribute(webRequest, ERROR_INTERNAL_ATTRIBUTE); + if (exception == null) { + exception = getAttribute(webRequest, RequestDispatcher.ERROR_EXCEPTION); + } + return exception; + } + + @SuppressWarnings("unchecked") + private T getAttribute(RequestAttributes requestAttributes, String name) { + return (T) requestAttributes.getAttribute(name, RequestAttributes.SCOPE_REQUEST); + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/ErrorAttributes.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/ErrorAttributes.java new file mode 100644 index 000000000000..a4ac3455abc0 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/ErrorAttributes.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.error; + +import java.util.Collections; +import java.util.Map; + +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.ModelAndView; + +/** + * Provides access to error attributes which can be logged or presented to the user. + * + * @author Phillip Webb + * @author Scott Frederick + * @since 4.0.0 + * @see DefaultErrorAttributes + */ +public interface ErrorAttributes { + + /** + * Returns a {@link Map} of the error attributes. The map can be used as the model of + * an error page {@link ModelAndView}, or returned as a + * {@link ResponseBody @ResponseBody}. + * @param webRequest the source request + * @param options options for error attribute contents + * @return a map of error attributes + */ + default Map getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { + return Collections.emptyMap(); + } + + /** + * Return the underlying cause of the error or {@code null} if the error cannot be + * extracted. + * @param webRequest the source request + * @return the {@link Exception} that caused the error or {@code null} + */ + Throwable getError(WebRequest webRequest); + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorController.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/ErrorController.java similarity index 92% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorController.java rename to spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/ErrorController.java index 9f441ea7f277..35ae5bb0eb57 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorController.java +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/ErrorController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.error; +package org.springframework.boot.webmvc.error; import org.springframework.stereotype.Controller; @@ -24,7 +24,7 @@ * * @author Phillip Webb * @author Scott Frederick - * @since 2.0.0 + * @since 4.0.0 */ public interface ErrorController { diff --git a/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/package-info.java b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/package-info.java new file mode 100644 index 000000000000..5803d52711da --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/java/org/springframework/boot/webmvc/error/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring MVC error handling infrastructure. + */ +package org.springframework.boot.webmvc.error; diff --git a/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..d62e279feb9c --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,156 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.mvc.date-format", + "type": "java.lang.String", + "description": "Date format to use, for example 'dd/MM/yyyy'.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.mvc.favicon.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable resolution of favicon.ico.", + "deprecation": { + "level": "error" + } + }, + { + "name": "spring.mvc.formcontent.filter.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Spring's FormContentFilter.", + "defaultValue": true + }, + { + "name": "spring.mvc.formcontent.putfilter.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Spring's HttpPutFormContentFilter.", + "defaultValue": true, + "deprecation": { + "replacement": "spring.mvc.formcontent.filter.enabled", + "level": "error" + } + }, + { + "name": "spring.mvc.hiddenmethod.filter.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Spring's HiddenHttpMethodFilter.", + "defaultValue": false + }, + { + "name": "spring.mvc.ignore-default-model-on-redirect", + "deprecation": { + "reason": "Deprecated for removal in Spring MVC.", + "level": "error" + } + }, + { + "name": "spring.mvc.locale", + "type": "java.util.Locale", + "deprecation": { + "replacement": "spring.web.locale", + "level": "error" + } + }, + { + "name": "spring.mvc.locale-resolver", + "type": "org.springframework.boot.autoconfigure.web.WebProperties$LocaleResolver", + "deprecation": { + "replacement": "spring.web.locale-resolver", + "level": "error" + } + }, + { + "name": "spring.mvc.throw-exception-if-no-handler-found", + "deprecation": { + "reason": "DispatcherServlet property is deprecated for removal and should no longer need to be configured.", + "level": "error" + } + } + ], + "hints": [ + { + "name": "spring.mvc.converters.preferred-json-mapper", + "values": [ + { + "value": "gson" + }, + { + "value": "jackson" + }, + { + "value": "jsonb" + } + ], + "providers": [ + { + "name": "any" + } + ] + }, + { + "name": "spring.mvc.format.date", + "values": [ + { + "value": "dd/MM/yyyy", + "description": "Example date format. Any format supported by DateTimeFormatter.parse can be used." + }, + { + "value": "iso", + "description": "ISO-8601 extended local date format." + } + ], + "providers": [ + { + "name": "any" + } + ] + }, + { + "name": "spring.mvc.format.date-time", + "values": [ + { + "value": "yyyy-MM-dd HH:mm:ss", + "description": "Example date-time format. Any format supported by DateTimeFormatter.parse can be used." + }, + { + "value": "iso", + "description": "ISO-8601 extended local date-time format." + }, + { + "value": "iso-offset", + "description": "ISO offset date-time format." + } + ], + "providers": [ + { + "name": "any" + } + ] + }, + { + "name": "spring.mvc.format.time", + "values": [ + { + "value": "HH:mm:ss", + "description": "Example time format. Any format supported by DateTimeFormatter.parse can be used." + }, + { + "value": "iso", + "description": "ISO-8601 extended local time format." + }, + { + "value": "iso-offset", + "description": "ISO offset time format." + } + ], + "providers": [ + { + "name": "any" + } + ] + } + ] +} diff --git a/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..128c571ee37e --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Template Availability Providers +org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ +org.springframework.boot.webmvc.autoconfigure.JspTemplateAvailabilityProvider diff --git a/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports b/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports new file mode 100644 index 000000000000..011c475176fa --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.webmvc.autoconfigure.actuate.web.WebMvcEndpointManagementContextConfiguration +org.springframework.boot.webmvc.autoconfigure.actuate.web.WebMvcEndpointChildContextConfiguration diff --git a/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..99fd1c88e55d --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,6 @@ +org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration +org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration +org.springframework.boot.webmvc.autoconfigure.WebMvcObservationAutoConfiguration +org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web.WebMvcHealthEndpointExtensionAutoConfiguration +org.springframework.boot.webmvc.autoconfigure.actuate.web.WebMvcMappingsAutoConfiguration +org.springframework.boot.webmvc.autoconfigure.error.ErrorMvcAutoConfiguration diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/autoconfigure/health/WebMvcHealthEndpointExtensionAutoConfigurationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/autoconfigure/health/WebMvcHealthEndpointExtensionAutoConfigurationTests.java new file mode 100644 index 000000000000..0ea35498751a --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/autoconfigure/health/WebMvcHealthEndpointExtensionAutoConfigurationTests.java @@ -0,0 +1,98 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.actuate.autoconfigure.health; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.WithTestEndpointOutcomeExposureContributor; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.health.HealthEndpointWebExtension; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webmvc.actuate.endpoint.web.AdditionalHealthEndpointPathsWebMvcHandlerMapping; +import org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web.WebMvcHealthEndpointExtensionAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.DispatcherServlet; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebMvcHealthEndpointExtensionAutoConfiguration}. + * + * @author Stephane Nicoll + */ +class WebMvcHealthEndpointExtensionAutoConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class, + HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + WebMvcHealthEndpointExtensionAutoConfiguration.class)); + + @Test + @WithTestEndpointOutcomeExposureContributor + void additionalHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)) + .withBean(DispatcherServlet.class) + .withPropertyValues("management.endpoints.web.exposure.exclude=*", + "management.endpoints.test.exposure.include=*") + .run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context).hasSingleBean(HealthEndpoint.class); + assertThat(context).hasSingleBean(HealthEndpointWebExtension.class); + assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty(); + assertThat(context).hasSingleBean(AdditionalHealthEndpointPathsWebMvcHandlerMapping.class); + }); + } + + @Test + @WithTestEndpointOutcomeExposureContributor + void backsOffWithoutWebEndpointInfrastructure() { + this.contextRunner.withConfiguration(AutoConfigurations.of(EndpointAutoConfiguration.class)) + .withBean(DispatcherServlet.class) + .withPropertyValues("management.endpoints.web.exposure.exclude=*", + "management.endpoints.test.exposure.include=*") + .run((context) -> assertThat(context) + .doesNotHaveBean(AdditionalHealthEndpointPathsWebMvcHandlerMapping.class)); + } + + @Configuration(proxyBeanMethods = false) + static class HealthIndicatorsConfiguration { + + @Bean + HealthIndicator simpleHealthIndicator() { + return () -> Health.up().withDetail("counter", 42).build(); + } + + @Bean + HealthIndicator additionalHealthIndicator() { + return () -> Health.up().build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/AbstractWebMvcEndpointHandlerMappingTests.java similarity index 80% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/AbstractWebMvcEndpointHandlerMappingTests.java index d986b6b2c1a8..c6a818cab55f 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/AbstractWebMvcEndpointHandlerMappingTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.servlet; +package org.springframework.boot.webmvc.actuate.endpoint.web; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.TypeReference; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.AbstractWebMvcEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webmvc.actuate.endpoint.web.AbstractWebMvcEndpointHandlerMapping.AbstractWebMvcEndpointHandlerMappingRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; @@ -38,7 +38,7 @@ void shouldRegisterHints() { new AbstractWebMvcEndpointHandlerMappingRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection() .onType(TypeReference - .of("org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler"))) + .of("org.springframework.boot.webmvc.actuate.endpoint.web.AbstractWebMvcEndpointHandlerMapping.OperationHandler"))) .accepts(runtimeHints); } diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java new file mode 100644 index 000000000000..06a69d97017a --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java @@ -0,0 +1,163 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.actuate.endpoint.web; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; +import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint; +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.method.HandlerMethod; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link ControllerEndpointHandlerMapping}. + * + * @author Phillip Webb + * @author Stephane Nicoll + * @deprecated since 3.3.5 in favor of {@code @Endpoint} and {@code @WebEndpoint} support + */ +@Deprecated(since = "3.3.5", forRemoval = true) +@SuppressWarnings("removal") +class ControllerEndpointHandlerMappingTests { + + private final StaticApplicationContext context = new StaticApplicationContext(); + + @Test + void mappingWithNoPrefix() throws Exception { + ExposableControllerEndpoint first = firstEndpoint(); + ExposableControllerEndpoint second = secondEndpoint(); + ControllerEndpointHandlerMapping mapping = createMapping("", first, second); + assertThat(mapping.getHandler(request("GET", "/first")).getHandler()) + .isEqualTo(handlerOf(first.getController(), "get")); + assertThat(mapping.getHandler(request("POST", "/second")).getHandler()) + .isEqualTo(handlerOf(second.getController(), "save")); + assertThat(mapping.getHandler(request("GET", "/third"))).isNull(); + } + + @Test + void mappingWithPrefix() throws Exception { + ExposableControllerEndpoint first = firstEndpoint(); + ExposableControllerEndpoint second = secondEndpoint(); + ControllerEndpointHandlerMapping mapping = createMapping("actuator", first, second); + assertThat(mapping.getHandler(request("GET", "/actuator/first")).getHandler()) + .isEqualTo(handlerOf(first.getController(), "get")); + assertThat(mapping.getHandler(request("POST", "/actuator/second")).getHandler()) + .isEqualTo(handlerOf(second.getController(), "save")); + assertThat(mapping.getHandler(request("GET", "/first"))).isNull(); + assertThat(mapping.getHandler(request("GET", "/second"))).isNull(); + } + + @Test + void mappingNarrowedToMethod() { + ExposableControllerEndpoint first = firstEndpoint(); + ControllerEndpointHandlerMapping mapping = createMapping("actuator", first); + assertThatExceptionOfType(HttpRequestMethodNotSupportedException.class) + .isThrownBy(() -> mapping.getHandler(request("POST", "/actuator/first"))); + } + + @Test + void mappingWithNoPath() throws Exception { + ExposableControllerEndpoint pathless = pathlessEndpoint(); + ControllerEndpointHandlerMapping mapping = createMapping("actuator", pathless); + assertThat(mapping.getHandler(request("GET", "/actuator/pathless")).getHandler()) + .isEqualTo(handlerOf(pathless.getController(), "get")); + assertThat(mapping.getHandler(request("GET", "/pathless"))).isNull(); + assertThat(mapping.getHandler(request("GET", "/"))).isNull(); + } + + private ControllerEndpointHandlerMapping createMapping(String prefix, ExposableControllerEndpoint... endpoints) { + ControllerEndpointHandlerMapping mapping = new ControllerEndpointHandlerMapping(new EndpointMapping(prefix), + Arrays.asList(endpoints), null, (endpointId, defaultAccess) -> Access.UNRESTRICTED); + mapping.setApplicationContext(this.context); + mapping.afterPropertiesSet(); + return mapping; + } + + private HandlerMethod handlerOf(Object source, String methodName) { + return new HandlerMethod(source, ReflectionUtils.findMethod(source.getClass(), methodName)); + } + + private MockHttpServletRequest request(String method, String requestURI) { + return new MockHttpServletRequest(method, requestURI); + } + + private ExposableControllerEndpoint firstEndpoint() { + return mockEndpoint(EndpointId.of("first"), new FirstTestMvcEndpoint()); + } + + private ExposableControllerEndpoint secondEndpoint() { + return mockEndpoint(EndpointId.of("second"), new SecondTestMvcEndpoint()); + } + + private ExposableControllerEndpoint pathlessEndpoint() { + return mockEndpoint(EndpointId.of("pathless"), new PathlessControllerEndpoint()); + } + + private ExposableControllerEndpoint mockEndpoint(EndpointId id, Object controller) { + ExposableControllerEndpoint endpoint = mock(ExposableControllerEndpoint.class); + given(endpoint.getEndpointId()).willReturn(id); + given(endpoint.getController()).willReturn(controller); + given(endpoint.getRootPath()).willReturn(id.toString()); + return endpoint; + } + + @ControllerEndpoint(id = "first") + static class FirstTestMvcEndpoint { + + @GetMapping("/") + String get() { + return "test"; + } + + } + + @ControllerEndpoint(id = "second") + static class SecondTestMvcEndpoint { + + @PostMapping("/") + void save() { + + } + + } + + @ControllerEndpoint(id = "pathless") + static class PathlessControllerEndpoint { + + @GetMapping + String get() { + return "test"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/WebMvcEndpointHandlerMappingTests.java similarity index 82% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/WebMvcEndpointHandlerMappingTests.java index 7b9c36ea7056..248ad35e222f 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/endpoint/web/WebMvcEndpointHandlerMappingTests.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.actuate.endpoint.web.servlet; +package org.springframework.boot.webmvc.actuate.endpoint.web; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.web.Link; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.WebMvcEndpointHandlerMappingRuntimeHints; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.WebMvcLinksHandler; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping.WebMvcEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping.WebMvcLinksHandler; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletsMappingDescriptionProviderTests.java similarity index 86% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletsMappingDescriptionProviderTests.java index d06bc0d45c4e..4f4299e49658 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/actuate/mappings/DispatcherServletsMappingDescriptionProviderTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.actuate.web.mappings.servlet; +package org.springframework.boot.webmvc.actuate.mappings; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.DispatcherServletsMappingDescriptionProviderRuntimeHints; +import org.springframework.boot.webmvc.actuate.mappings.DispatcherServletsMappingDescriptionProvider.DispatcherServletsMappingDescriptionProviderRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletAutoConfigurationTests.java index f86316c4b1ec..a63c3ec95fcb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import jakarta.servlet.MultipartConfigElement; import jakarta.servlet.http.HttpServletRequest; @@ -22,7 +22,6 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.MultipartConfigFactory; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -178,10 +177,8 @@ static class MultipartConfiguration { @Bean MultipartConfigElement multipartConfig() { - MultipartConfigFactory factory = new MultipartConfigFactory(); - factory.setMaxFileSize(DataSize.ofKilobytes(128)); - factory.setMaxRequestSize(DataSize.ofKilobytes(128)); - return factory.createMultipartConfig(); + return new MultipartConfigElement(null, DataSize.ofKilobytes(128).toBytes(), + DataSize.ofKilobytes(128).toBytes(), 0); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletPathTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletPathTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletPathTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletPathTests.java index 0628a4246bb3..449561e9546b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletPathTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletRegistrationBeanTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletRegistrationBeanTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletRegistrationBeanTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletRegistrationBeanTests.java index f80a69d6c26b..82cab554bb4c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletRegistrationBeanTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/DispatcherServletRegistrationBeanTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/JspTemplateAvailabilityProviderTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/JspTemplateAvailabilityProviderTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/JspTemplateAvailabilityProviderTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/JspTemplateAvailabilityProviderTests.java index 53bc9bdcbfff..767d2c1aa966 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/JspTemplateAvailabilityProviderTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/JspTemplateAvailabilityProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcAutoConfigurationTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcAutoConfigurationTests.java index 14811e2fd2fa..619d01b10c2d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.time.LocalDateTime; import java.time.LocalTime; @@ -44,31 +44,31 @@ import org.springframework.aop.support.AopUtils; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; -import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; -import org.springframework.boot.autoconfigure.validation.ValidatorAdapter; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfigurationTests.OrderedControllerAdviceBeansConfiguration.HighestOrderedControllerAdvice; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfigurationTests.OrderedControllerAdviceBeansConfiguration.LowestOrderedControllerAdvice; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConverters; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.servlet.filter.OrderedFormContentFilter; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration; +import org.springframework.boot.validation.autoconfigure.ValidatorAdapter; import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor; +import org.springframework.boot.web.server.servlet.MockServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.filter.OrderedFormContentFilter; -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfigurationTests.OrderedControllerAdviceBeansConfiguration.HighestOrderedControllerAdvice; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfigurationTests.OrderedControllerAdviceBeansConfiguration.LowestOrderedControllerAdvice; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; @@ -981,7 +981,7 @@ void problemDetailsEnabledAddsExceptionHandler() { @Test void problemDetailsExceptionHandlerDoesNotPreventProxying() { - this.contextRunner.withConfiguration(AutoConfigurations.of(AopAutoConfiguration.class)) + this.contextRunner.withUserConfiguration(AopConfiguration.class) .withBean(ExceptionHandlerInterceptor.class) .withPropertyValues("spring.mvc.problemdetails.enabled:true") .run((context) -> assertThat(context).getBean(ProblemDetailsExceptionHandler.class) @@ -1552,6 +1552,12 @@ static class CustomExceptionHandler extends ResponseEntityExceptionHandler { } + @Configuration(proxyBeanMethods = false) + @EnableAspectJAutoProxy(proxyTargetClass = true) + static class AopConfiguration { + + } + @Aspect static class ExceptionHandlerInterceptor { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcObservationAutoConfigurationTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcObservationAutoConfigurationTests.java index f7fb31c67170..d88f05b6c0d3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/web/servlet/WebMvcObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcObservationAutoConfigurationTests.java @@ -14,23 +14,25 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.observation.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.util.EnumSet; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler.IgnoredMeters; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import io.micrometer.observation.Observation.Context; import io.micrometer.observation.tck.TestObservationRegistry; import jakarta.servlet.DispatcherType; import jakarta.servlet.Filter; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.autoconfigure.metrics.web.TestController; -import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.metrics.autoconfigure.MetricsAutoConfiguration; +import org.springframework.boot.observation.autoconfigure.ObservationAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; @@ -41,6 +43,8 @@ import org.springframework.core.Ordered; import org.springframework.http.server.observation.DefaultServerRequestObservationConvention; import org.springframework.test.web.servlet.assertj.MockMvcTester; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.filter.ServerHttpObservationFilter; import static org.assertj.core.api.Assertions.assertThat; @@ -59,12 +63,12 @@ class WebMvcObservationAutoConfigurationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(WebMvcObservationAutoConfiguration.class)); + .withConfiguration( + AutoConfigurations.of(ObservationAutoConfiguration.class, WebMvcObservationAutoConfiguration.class)) + .withBean(SimpleMeterRegistry.class); @Test - void backsOffWhenMeterRegistryIsMissing() { + void backsOffWhenObservationRegistryIsMissing() { new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(WebMvcObservationAutoConfiguration.class)) .run((context) -> assertThat(context).doesNotHaveBean(FilterRegistrationBean.class)); @@ -128,7 +132,7 @@ void filterRegistrationDoesNotBackOffWithOtherFilter() { @Test void afterMaxUrisReachedFurtherUrisAreDenied(CapturedOutput output) { - this.contextRunner.withUserConfiguration(TestController.class) + this.contextRunner.withUserConfiguration(TestController.class, MetricsConfiguration.class) .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, ObservationAutoConfiguration.class, WebMvcAutoConfiguration.class)) .withPropertyValues("management.metrics.web.server.max-uri-tags=2") @@ -141,7 +145,7 @@ void afterMaxUrisReachedFurtherUrisAreDenied(CapturedOutput output) { @Test void afterMaxUrisReachedFurtherUrisAreDeniedWhenUsingCustomObservationName(CapturedOutput output) { - this.contextRunner.withUserConfiguration(TestController.class) + this.contextRunner.withUserConfiguration(TestController.class, MetricsConfiguration.class) .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, ObservationAutoConfiguration.class, WebMvcAutoConfiguration.class)) .withPropertyValues("management.metrics.web.server.max-uri-tags=2", @@ -155,7 +159,7 @@ void afterMaxUrisReachedFurtherUrisAreDeniedWhenUsingCustomObservationName(Captu @Test void shouldNotDenyNorLogIfMaxUrisIsNotReached(CapturedOutput output) { - this.contextRunner.withUserConfiguration(TestController.class) + this.contextRunner.withUserConfiguration(TestController.class, MetricsConfiguration.class) .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, ObservationAutoConfiguration.class, WebMvcAutoConfiguration.class)) .withPropertyValues("management.metrics.web.server.max-uri-tags=5") @@ -237,4 +241,34 @@ static class CustomConvention extends DefaultServerRequestObservationConvention } + @Configuration(proxyBeanMethods = false) + static class MetricsConfiguration { + + @Bean + MeterObservationHandler meterObservationHandler(MeterRegistry registry) { + return new DefaultMeterObservationHandler(registry, IgnoredMeters.LONG_TASK_TIMER); + } + + } + + @RestController + static class TestController { + + @GetMapping("test0") + String test0() { + return "test0"; + } + + @GetMapping("test1") + String test1() { + return "test1"; + } + + @GetMapping("test2") + String test2() { + return "test2"; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcPropertiesTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcPropertiesTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcPropertiesTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcPropertiesTests.java index 9dd3fe981291..c3428c907cb7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcPropertiesTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WebMvcPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.util.Collections; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMappingTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageHandlerMappingTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMappingTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageHandlerMappingTests.java index b4a31ec08a75..5ec3a5cc5b68 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageHandlerMappingTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import java.nio.charset.StandardCharsets; import java.util.Collections; diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageIntegrationTests.java new file mode 100644 index 000000000000..d78380df7322 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageIntegrationTests.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure; + +import java.net.URI; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.test.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for the welcome page. + * + * @author Madhura Bhave + * @author Andy Wilkinson + */ +@WithResource(name = "static/index.html", content = "custom welcome page") +class WelcomePageIntegrationTests { + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withPropertyValues("spring.web.resources.chain.strategy.content.enabled=true", "server.port=0") + .withConfiguration(AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class, + WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class)); + + private final TestRestTemplate template = new TestRestTemplate(); + + @Test + void contentStrategyWithWelcomePage() { + this.contextRunner.run((context) -> { + int port = ((WebServerApplicationContext) context.getSourceApplicationContext()).getWebServer().getPort(); + RequestEntity entity = RequestEntity.get(new URI("http://localhost:" + port + "/")) + .header("Accept", MediaType.ALL.toString()) + .build(); + ResponseEntity content = this.template.exchange(entity, String.class); + assertThat(content.getBody()).contains("custom welcome page"); + assertThat(content.getStatusCode()).isEqualTo(HttpStatus.OK); + }); + } + + @Test + void notAcceptableWelcomePage() { + this.contextRunner.run((context) -> { + int port = ((WebServerApplicationContext) context.getSourceApplicationContext()).getWebServer().getPort(); + RequestEntity entity = RequestEntity.get(new URI("http://localhost:" + port + "/")) + .header("Accept", "spring/boot") + .build(); + ResponseEntity content = this.template.exchange(entity, String.class); + assertThat(content.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE); + }); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMappingTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageNotAcceptableHandlerMappingTests.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMappingTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageNotAcceptableHandlerMappingTests.java index 443d98ad0364..3a68c699abcf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/WelcomePageNotAcceptableHandlerMappingTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure; import org.assertj.core.api.ThrowingConsumer; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/WebMvcHealthEndpointAdditionalPathIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/WebMvcHealthEndpointAdditionalPathIntegrationTests.java new file mode 100644 index 000000000000..d9fbbcb891b1 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/endpoint/web/WebMvcHealthEndpointAdditionalPathIntegrationTests.java @@ -0,0 +1,64 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.integrationtest.AbstractHealthEndpointAdditionalPathIntegrationTests; +import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatServletManagementContextAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.web.context.ConfigurableWebApplicationContext; + +/** + * Integration tests for MVC health groups on an additional path. + * + * @author Madhura Bhave + */ +class WebMvcHealthEndpointAdditionalPathIntegrationTests extends + AbstractHealthEndpointAdditionalPathIntegrationTests { + + WebMvcHealthEndpointAdditionalPathIntegrationTests() { + super(new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, + HealthContributorAutoConfiguration.class, HealthContributorRegistryAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, ManagementContextAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, + TomcatServletManagementContextAutoConfiguration.class, WebMvcAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, + EndpointAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + HealthEndpointAutoConfiguration.class, WebMvcHealthEndpointExtensionAutoConfiguration.class, + DiskSpaceHealthContributorAutoConfiguration.class)) + .withInitializer(new ServerPortInfoApplicationContextInitializer()) + .withPropertyValues("server.port=0")); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolverTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerExceptionResolverTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolverTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerExceptionResolverTests.java index 83e5c291d7e2..2052ec0113f2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolverTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/CompositeHandlerExceptionResolverTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ControllerEndpointWebMvcIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ControllerEndpointWebMvcIntegrationTests.java new file mode 100644 index 000000000000..3b826d68ace1 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ControllerEndpointWebMvcIntegrationTests.java @@ -0,0 +1,97 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.web; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.mock.web.MockServletContext; +import org.springframework.test.web.servlet.assertj.MockMvcTester; +import org.springframework.web.bind.annotation.GetMapping; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for the Actuator's MVC + * {@link org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint + * controller endpoints}. + * + * @author Phillip Webb + * @author Andy Wilkinson + */ +class ControllerEndpointWebMvcIntegrationTests { + + private AnnotationConfigServletWebApplicationContext context; + + @AfterEach + void close() { + this.context.close(); + } + + @Test + void endpointsCanBeAccessed() { + this.context = new AnnotationConfigServletWebApplicationContext(); + this.context.register(DefaultConfiguration.class, ExampleController.class); + TestPropertyValues + .of("management.endpoints.web.base-path:/management", "management.endpoints.web.exposure.include=*") + .applyTo(this.context); + MockMvcTester mvc = createMockMvcTester(); + assertThat(mvc.get().uri("/management/example")).hasStatusOk(); + } + + private MockMvcTester createMockMvcTester() { + this.context.setServletContext(new MockServletContext()); + this.context.refresh(); + return MockMvcTester.from(this.context); + } + + @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, AuditAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class, + ManagementContextAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + BeansEndpointAutoConfiguration.class }) + static class DefaultConfiguration { + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "example") + @SuppressWarnings("removal") + static class ExampleController { + + @GetMapping("/") + String example() { + return "Example"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementErrorEndpointTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ManagementErrorEndpointTests.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementErrorEndpointTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ManagementErrorEndpointTests.java index a1884bac680d..9ef020c291b7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ManagementErrorEndpointTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/ManagementErrorEndpointTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import java.util.Collections; import java.util.Map; @@ -24,8 +24,8 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.DefaultErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.WebRequest; diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointAccessIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointAccessIntegrationTests.java new file mode 100644 index 000000000000..90cf0083c99f --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointAccessIntegrationTests.java @@ -0,0 +1,220 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.web; + +import java.io.IOException; +import java.util.function.Supplier; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.client.RestClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for controlling access to endpoints exposed by Spring MVC. + * + * @author Andy Wilkinson + */ +class WebMvcEndpointAccessIntegrationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(TomcatServletWebServerAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + WebMvcAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, + ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, + HealthContributorAutoConfiguration.class, BeansEndpointAutoConfiguration.class)) + .withUserConfiguration(CustomMvcEndpoint.class, CustomServletEndpoint.class) + .withPropertyValues("server.port:0"); + + @Test + void accessIsUnrestrictedByDefault() { + this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*").run((context) -> { + RestClient client = createClient(context); + assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue(); + assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue(); + assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isTrue(); + assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue(); + assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isTrue(); + }); + } + + @Test + void accessCanBeReadOnlyByDefault() { + this.contextRunner + .withPropertyValues("management.endpoints.web.exposure.include=*", + "management.endpoints.access.default=READ_ONLY") + .run((context) -> { + RestClient client = createClient(context); + assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue(); + assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue(); + assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); + assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue(); + assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse(); + }); + } + + @Test + void accessCanBeNoneByDefault() { + this.contextRunner + .withPropertyValues("management.endpoints.web.exposure.include=*", + "management.endpoints.access.default=NONE") + .run((context) -> { + RestClient client = createClient(context); + assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse(); + assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isFalse(); + assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); + assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isFalse(); + assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse(); + }); + } + + @Test + void accessForOneEndpointCanOverrideTheDefaultAccess() { + this.contextRunner + .withPropertyValues("management.endpoints.web.exposure.include=*", + "management.endpoints.access.default=READ_ONLY", + "management.endpoint.customservlet.access=UNRESTRICTED") + .run((context) -> { + RestClient client = createClient(context); + assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue(); + assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue(); + assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); + assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue(); + assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isTrue(); + }); + } + + @Test + void accessCanBeCappedAtReadOnly() { + this.contextRunner + .withPropertyValues("management.endpoints.web.exposure.include=*", + "management.endpoints.access.default=UNRESTRICTED", + "management.endpoints.access.max-permitted=READ_ONLY") + .run((context) -> { + RestClient client = createClient(context); + assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue(); + assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isTrue(); + assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); + assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue(); + assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse(); + }); + } + + @Test + void accessCanBeCappedAtNone() { + this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*", + "management.endpoints.access.default=UNRESTRICTED", "management.endpoints.access.max-permitted=NONE") + .run((context) -> { + RestClient client = createClient(context); + assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse(); + assertThat(isAccessible(client, HttpMethod.GET, "custommvc")).isFalse(); + assertThat(isAccessible(client, HttpMethod.POST, "custommvc")).isFalse(); + assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isFalse(); + assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse(); + }); + } + + private RestClient createClient(AssertableWebApplicationContext context) { + int port = context.getSourceApplicationContext(ServletWebServerApplicationContext.class) + .getWebServer() + .getPort(); + return RestClient.builder().defaultStatusHandler((status) -> true, (request, response) -> { + }).baseUrl("http://localhost:" + port).build(); + } + + private boolean isAccessible(RestClient client, HttpMethod method, String path) { + path = "/actuator/" + path; + ResponseEntity result = client.method(method).uri(path).retrieve().toEntity(byte[].class); + if (result.getStatusCode() == HttpStatus.OK) { + return true; + } + if (result.getStatusCode() == HttpStatus.NOT_FOUND || result.getStatusCode() == HttpStatus.METHOD_NOT_ALLOWED) { + return false; + } + throw new IllegalStateException( + String.format("Unexpected %s HTTP status for endpoint %s", result.getStatusCode(), path)); + } + + @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "custommvc") + @SuppressWarnings("removal") + static class CustomMvcEndpoint { + + @GetMapping("/") + String get() { + return "get"; + } + + @PostMapping("/") + String post() { + return "post"; + } + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "customservlet") + @SuppressWarnings({ "deprecation", "removal" }) + static class CustomServletEndpoint + implements Supplier { + + @Override + public org.springframework.boot.actuate.endpoint.web.EndpointServlet get() { + return new org.springframework.boot.actuate.endpoint.web.EndpointServlet(new HttpServlet() { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + } + + }); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfigurationIntegrationTests.java similarity index 88% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfigurationIntegrationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfigurationIntegrationTests.java index 562b1de4a6fd..3d1e773da2ef 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -35,16 +35,18 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.boot.env.ConfigTreePropertySource; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.autoconfigure.actuate.web.TomcatServletManagementContextAutoConfiguration; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.error.ErrorMvcAutoConfiguration; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.convert.support.ConfigurableConversionService; @@ -70,9 +72,10 @@ class WebMvcEndpointChildContextConfigurationIntegrationTests { private final WebApplicationContextRunner runner = new WebApplicationContextRunner( AnnotationConfigServletWebServerApplicationContext::new) .withConfiguration(AutoConfigurations.of(ManagementContextAutoConfiguration.class, - ServletWebServerFactoryAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, - WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, ErrorMvcAutoConfiguration.class)) + TomcatServletWebServerAutoConfiguration.class, TomcatServletManagementContextAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, + EndpointAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + ErrorMvcAutoConfiguration.class)) .withUserConfiguration(SucceedingEndpoint.class, FailingEndpoint.class, FailingControllerEndpoint.class) .withInitializer(new ServerPortInfoApplicationContextInitializer()) .withPropertyValues("server.port=0", "management.server.port=0", "management.endpoints.web.exposure.include=*", diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfigurationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfigurationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfigurationTests.java index 707921b271bf..80ea4e2a93fd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointChildContextConfigurationTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.web.servlet; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath; +import org.springframework.boot.servlet.filter.OrderedRequestContextFilter; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestContextListener; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointCorsIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointCorsIntegrationTests.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointCorsIntegrationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointCorsIntegrationTests.java index f8e184ce3fdd..28f43e8a3384 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointCorsIntegrationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointCorsIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.integrationtest; +package org.springframework.boot.webmvc.autoconfigure.actuate.web; import org.assertj.core.api.ThrowingConsumer; import org.junit.jupiter.api.Test; @@ -22,16 +22,15 @@ import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.test.web.servlet.assertj.MockMvcTester; diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointExposureIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointExposureIntegrationTests.java new file mode 100644 index 000000000000..5d75151e1094 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointExposureIntegrationTests.java @@ -0,0 +1,200 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.web; + +import java.io.IOException; +import java.util.function.Supplier; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository; +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration; +import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.ServletHttpExchangesAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; +import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.client.RestClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for Endpoints over Spring MVC. + * + * @author Stephane Nicoll + * @author Phillip Webb + */ +class WebMvcEndpointExposureIntegrationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebServerApplicationContext::new) + .withConfiguration(AutoConfigurations.of(TomcatServletWebServerAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + WebMvcAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, + ManagementContextAutoConfiguration.class, ManagementContextAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, ServletHttpExchangesAutoConfiguration.class, + HealthContributorAutoConfiguration.class, HealthContributorRegistryAutoConfiguration.class, + BeansEndpointAutoConfiguration.class, HealthEndpointAutoConfiguration.class, + ShutdownEndpointAutoConfiguration.class)) + .withUserConfiguration(CustomMvcEndpoint.class, CustomServletEndpoint.class, + HttpExchangeRepositoryConfiguration.class, AuditEventRepositoryConfiguration.class) + .withPropertyValues("server.port:0"); + + @Test + void webEndpointsExceptHealthAreDisabledByDefault() { + this.contextRunner.run((context) -> { + RestClient client = createClient(context); + assertThat(isExposed(client, HttpMethod.GET, "beans")).isFalse(); + assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue(); + assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse(); + }); + } + + @Test + void webEndpointsCanBeExposed() { + WebApplicationContextRunner contextRunner = this.contextRunner + .withPropertyValues("management.endpoints.web.exposure.include=*"); + contextRunner.run((context) -> { + RestClient client = createClient(context); + assertThat(isExposed(client, HttpMethod.GET, "beans")).isTrue(); + assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue(); + assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse(); + }); + } + + @Test + void singleWebEndpointCanBeExposed() { + WebApplicationContextRunner contextRunner = this.contextRunner + .withPropertyValues("management.endpoints.web.exposure.include=beans"); + contextRunner.run((context) -> { + RestClient client = createClient(context); + assertThat(isExposed(client, HttpMethod.GET, "beans")).isTrue(); + assertThat(isExposed(client, HttpMethod.GET, "health")).isFalse(); + assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse(); + }); + } + + @Test + void singleWebEndpointCanBeExcluded() { + WebApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues( + "management.endpoints.web.exposure.include=*", "management.endpoints.web.exposure.exclude=beans"); + contextRunner.run((context) -> { + RestClient client = createClient(context); + assertThat(isExposed(client, HttpMethod.GET, "beans")).isFalse(); + assertThat(isExposed(client, HttpMethod.GET, "health")).isTrue(); + assertThat(isExposed(client, HttpMethod.POST, "shutdown")).isFalse(); + }); + } + + private RestClient createClient(AssertableWebApplicationContext context) { + int port = context.getSourceApplicationContext(ServletWebServerApplicationContext.class) + .getWebServer() + .getPort(); + return RestClient.builder().defaultStatusHandler((status) -> true, (request, response) -> { + }).baseUrl("http://localhost:" + port).build(); + } + + private boolean isExposed(RestClient client, HttpMethod method, String path) { + path = "/actuator/" + path; + ResponseEntity result = client.method(method).uri(path).retrieve().toEntity(byte[].class); + if (result.getStatusCode() == HttpStatus.OK) { + return true; + } + if (result.getStatusCode() == HttpStatus.NOT_FOUND) { + return false; + } + throw new IllegalStateException( + String.format("Unexpected %s HTTP status for endpoint %s", result.getStatusCode(), path)); + } + + @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "custommvc") + @SuppressWarnings("removal") + static class CustomMvcEndpoint { + + @GetMapping("/") + String main() { + return "test"; + } + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "customservlet") + @SuppressWarnings({ "deprecation", "removal" }) + static class CustomServletEndpoint + implements Supplier { + + @Override + public org.springframework.boot.actuate.endpoint.web.EndpointServlet get() { + return new org.springframework.boot.actuate.endpoint.web.EndpointServlet(new HttpServlet() { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + } + + }); + } + + } + + @Configuration(proxyBeanMethods = false) + static class HttpExchangeRepositoryConfiguration { + + @Bean + InMemoryHttpExchangeRepository httpExchangeRepository() { + return new InMemoryHttpExchangeRepository(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class AuditEventRepositoryConfiguration { + + @Bean + InMemoryAuditEventRepository auditEventRepository() { + return new InMemoryAuditEventRepository(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointIntegrationTests.java new file mode 100644 index 000000000000..5e4b278f51ae --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointIntegrationTests.java @@ -0,0 +1,212 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.web; + +import java.io.IOException; +import java.util.function.Supplier; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; +import jakarta.servlet.http.HttpServlet; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockServletContext; +import org.springframework.test.web.servlet.assertj.MockMvcTester; +import org.springframework.web.util.pattern.PathPatternParser; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for the Actuator's MVC endpoints. + * + * @author Andy Wilkinson + */ +class WebMvcEndpointIntegrationTests { + + private AnnotationConfigServletWebApplicationContext context; + + @Test + void webMvcEndpointHandlerMappingIsConfiguredWithPathPatternParser() { + this.context = new AnnotationConfigServletWebApplicationContext(); + this.context.register(DefaultConfiguration.class); + this.context.setServletContext(new MockServletContext()); + this.context.refresh(); + WebMvcEndpointHandlerMapping handlerMapping = this.context.getBean(WebMvcEndpointHandlerMapping.class); + assertThat(handlerMapping.getPatternParser()).isInstanceOf(PathPatternParser.class); + } + + @Test + void linksAreProvidedToAllEndpointTypes() { + this.context = new AnnotationConfigServletWebApplicationContext(); + this.context.register(DefaultConfiguration.class, EndpointsConfiguration.class); + TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context); + MockMvcTester mvc = doCreateMockMvcTester(); + assertThat(mvc.get().uri("/actuator").accept("*/*")).hasStatusOk() + .bodyJson() + .extractingPath("_links") + .asMap() + .containsKeys("beans", "servlet", "restcontroller", "controller"); + } + + @Test + void linksPageIsNotAvailableWhenDisabled() { + this.context = new AnnotationConfigServletWebApplicationContext(); + this.context.register(DefaultConfiguration.class, EndpointsConfiguration.class); + TestPropertyValues.of("management.endpoints.web.discovery.enabled=false").applyTo(this.context); + MockMvcTester mvc = doCreateMockMvcTester(); + assertThat(mvc.get().uri("/actuator").accept("*/*")).hasStatus(HttpStatus.NOT_FOUND); + } + + @Test + void endpointObjectMapperCanBeApplied() { + this.context = new AnnotationConfigServletWebApplicationContext(); + this.context.register(EndpointObjectMapperConfiguration.class, DefaultConfiguration.class); + TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context); + MockMvcTester mvc = doCreateMockMvcTester(); + assertThat(mvc.get().uri("/actuator/beans")).hasStatusOk().bodyText().contains("\"scope\":\"notelgnis\""); + } + + private MockMvcTester doCreateMockMvcTester() { + this.context.setServletContext(new MockServletContext()); + this.context.refresh(); + return MockMvcTester.from(this.context); + } + + @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, + ServletManagementContextAutoConfiguration.class, AuditAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class, + ManagementContextAutoConfiguration.class, AuditAutoConfiguration.class, + DispatcherServletAutoConfiguration.class, BeansEndpointAutoConfiguration.class }) + static class DefaultConfiguration { + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "servlet") + @SuppressWarnings({ "deprecation", "removal" }) + static class TestServletEndpoint + implements Supplier { + + @Override + public org.springframework.boot.actuate.endpoint.web.EndpointServlet get() { + return new org.springframework.boot.actuate.endpoint.web.EndpointServlet(new HttpServlet() { + }); + } + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint(id = "controller") + @SuppressWarnings("removal") + static class TestControllerEndpoint { + + } + + @org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "restcontroller") + @SuppressWarnings("removal") + static class TestRestControllerEndpoint { + + } + + @Configuration(proxyBeanMethods = false) + static class EndpointsConfiguration { + + @Bean + TestServletEndpoint testServletEndpoint() { + return new TestServletEndpoint(); + } + + @Bean + TestControllerEndpoint testControllerEndpoint() { + return new TestControllerEndpoint(); + } + + @Bean + TestRestControllerEndpoint testRestControllerEndpoint() { + return new TestRestControllerEndpoint(); + } + + } + + @Configuration + @SuppressWarnings({ "deprecation", "removal" }) + static class EndpointObjectMapperConfiguration { + + @Bean + EndpointObjectMapper endpointObjectMapper() { + SimpleModule module = new SimpleModule(); + module.addSerializer(String.class, new ReverseStringSerializer()); + ObjectMapper objectMapper = org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.json() + .modules(module) + .build(); + return () -> objectMapper; + } + + static class ReverseStringSerializer extends StdScalarSerializer { + + ReverseStringSerializer() { + super(String.class, false); + } + + @Override + public boolean isEmpty(SerializerProvider prov, Object value) { + return ((String) value).isEmpty(); + } + + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException { + serialize(value, gen); + } + + @Override + public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, + TypeSerializer typeSer) throws IOException { + serialize(value, gen); + } + + private void serialize(Object value, JsonGenerator gen) throws IOException { + StringBuilder builder = new StringBuilder((String) value); + gen.writeString(builder.reverse().toString()); + } + + } + + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfigurationTests.java new file mode 100644 index 000000000000..6d909d91086c --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcEndpointManagementContextConfigurationTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.web; + +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.endpoint.Access; +import org.springframework.boot.actuate.endpoint.EndpointAccessResolver; +import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar; +import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebMvcEndpointManagementContextConfiguration}. + * + * @author Phillip Webb + * @author Madhura Bhave + */ +@SuppressWarnings("removal") +class WebMvcEndpointManagementContextConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withUserConfiguration(TestConfig.class) + .withConfiguration(AutoConfigurations.of(DispatcherServletAutoConfiguration.class, + EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class)); + + @Test + void contextShouldContainServletEndpointRegistrar() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ServletEndpointRegistrar.class); + ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class); + assertThat(bean).hasFieldOrPropertyWithValue("basePath", "/test/actuator"); + }); + } + + @Test + void contextWhenNotServletBasedShouldNotContainServletEndpointRegistrar() { + new ApplicationContextRunner().withUserConfiguration(TestConfig.class) + .run((context) -> assertThat(context).doesNotHaveBean(ServletEndpointRegistrar.class)); + } + + @Configuration(proxyBeanMethods = false) + @ImportAutoConfiguration(WebMvcEndpointManagementContextConfiguration.class) + static class TestConfig { + + @Bean + ServletEndpointsSupplier servletEndpointsSupplier() { + return Collections::emptyList; + } + + @Bean + DispatcherServletPath dispatcherServletPath() { + return () -> "/test"; + } + + @Bean + EndpointAccessResolver endpointAccessResolver() { + return (endpointId, defaultAccess) -> Access.UNRESTRICTED; + } + + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcMappingsAutoConfigurationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcMappingsAutoConfigurationTests.java new file mode 100644 index 000000000000..11a750fc66dd --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/actuate/web/WebMvcMappingsAutoConfigurationTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.autoconfigure.actuate.web; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webmvc.actuate.mappings.DispatcherServletsMappingDescriptionProvider; +import org.springframework.web.servlet.DispatcherServlet; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebMvcMappingsAutoConfiguration}. + * + * @author Andy Wilkinson + */ +class WebMvcMappingsAutoConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(WebMvcMappingsAutoConfiguration.class)); + + @Test + void whenEndpointIsUnavailableThenDescriptionProviderIsNotCreated() { + this.contextRunner.withBean(DispatcherServlet.class) + .run((context) -> assertThat(context).doesNotHaveBean(DispatcherServletsMappingDescriptionProvider.class)); + } + + @Test + void whenEndpointIsAvailableButThereIsNoDispatcherServletThenDescriptionProviderIsNotCreated() { + this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=mappings") + .run((context) -> assertThat(context).doesNotHaveBean(DispatcherServletsMappingDescriptionProvider.class)); + } + + @Test + void whenEndpointIsAvailableThenDescriptionProviderIsCreated() { + this.contextRunner.withBean(DispatcherServlet.class) + .withPropertyValues("management.endpoints.web.exposure.include=mappings") + .run((context) -> assertThat(context).hasSingleBean(DispatcherServletsMappingDescriptionProvider.class)); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerDirectMockMvcTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerDirectMockMvcTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerDirectMockMvcTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerDirectMockMvcTests.java index adbc36c4c2d1..f69323cd03d5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerDirectMockMvcTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerDirectMockMvcTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -32,12 +32,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.test.util.ApplicationContextTestUtils; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Import; @@ -111,7 +111,7 @@ void errorControllerWithAop() { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented - @Import({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, ErrorMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerIntegrationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerIntegrationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerIntegrationTests.java index 5ae103c815f4..48ab4582b462 100755 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerIntegrationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -39,17 +39,17 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.testsupport.classpath.resources.WithResource; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.test.client.TestRestTemplate; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -397,7 +397,7 @@ private void load(Class configuration, String... arguments) { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented - @ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + @ImportAutoConfiguration({ TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, ErrorMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) private @interface MinimalWebConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerMockMvcTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerMockMvcTests.java index 72c002cfc707..9eb1eefd66c9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/BasicErrorControllerMockMvcTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -35,11 +35,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.MethodParameter; @@ -71,7 +70,7 @@ * @author Dave Syer * @author Scott Frederick */ -@SpringBootTest(properties = { "server.error.include-message=always" }) +@SpringBootTest(properties = { "server.error.include-message=always", "debug=true" }) @DirtiesContext class BasicErrorControllerMockMvcTests { @@ -95,7 +94,6 @@ void testErrorWithNotFoundResponseStatus() { assertThat(this.mvc.get().uri("/bang")).hasStatus(HttpStatus.NOT_FOUND) .satisfies((result) -> assertThat(this.mvc.perform(new ErrorDispatcher(result, "/error"))).bodyText() .contains("Expected!")); - } @Test @@ -128,9 +126,9 @@ void testDirectAccessForBrowserClient() { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented - @ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - ErrorMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) + @ImportAutoConfiguration({ DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, ErrorMvcAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class }) private @interface MinimalWebConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewIntegrationTests.java similarity index 82% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewIntegrationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewIntegrationTests.java index e80f247827bf..119bcc5f8be1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewIntegrationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -28,11 +28,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; @@ -96,9 +95,9 @@ static String injectCall() { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented - @Import({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, - WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - ErrorMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) + @Import({ DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, ErrorMvcAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewResolverTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewResolverTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewResolverTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewResolverTests.java index c1b5cd1d98f9..42c5418eaf2a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/DefaultErrorViewResolverTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/DefaultErrorViewResolverTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.util.Collections; import java.util.HashMap; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorMvcAutoConfigurationTests.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorMvcAutoConfigurationTests.java index 36fa0607f4b4..da5d59445a83 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/ErrorMvcAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import java.time.Clock; import java.util.Map; @@ -23,13 +23,13 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.web.context.request.RequestAttributes; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/RemappedErrorViewIntegrationTests.java similarity index 77% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java rename to spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/RemappedErrorViewIntegrationTests.java index 1c7f51986ae8..79aa7b8ee1b5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/autoconfigure/error/RemappedErrorViewIntegrationTests.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.web.servlet.error; +package org.springframework.boot.webmvc.autoconfigure.error; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.server.ErrorPage; -import org.springframework.boot.web.server.ErrorPageRegistrar; -import org.springframework.boot.web.server.ErrorPageRegistry; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.error.ErrorPage; +import org.springframework.boot.web.error.ErrorPageRegistrar; +import org.springframework.boot.web.error.ErrorPageRegistry; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Controller; @@ -69,7 +69,7 @@ void forwardToErrorPage() { @Configuration(proxyBeanMethods = false) @Import({ PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, ErrorMvcAutoConfiguration.class }) @Controller static class TestConfiguration implements ErrorPageRegistrar { diff --git a/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/error/DefaultErrorAttributesTests.java b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/error/DefaultErrorAttributesTests.java new file mode 100644 index 000000000000..6eab881329d3 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/test/java/org/springframework/boot/webmvc/error/DefaultErrorAttributesTests.java @@ -0,0 +1,333 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.error; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import jakarta.servlet.ServletException; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.error.ErrorAttributeOptions.Include; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.util.ReflectionUtils; +import org.springframework.validation.BindException; +import org.springframework.validation.BindingResult; +import org.springframework.validation.MapBindingResult; +import org.springframework.validation.ObjectError; +import org.springframework.validation.method.MethodValidationResult; +import org.springframework.validation.method.ParameterValidationResult; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.method.annotation.HandlerMethodValidationException; +import org.springframework.web.servlet.ModelAndView; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DefaultErrorAttributes}. + * + * @author Phillip Webb + * @author Vedran Pavic + * @author Scott Frederick + * @author Moritz Halbritter + * @author Yanming Zhou + */ +class DefaultErrorAttributesTests { + + private final DefaultErrorAttributes errorAttributes = new DefaultErrorAttributes(); + + private final MockHttpServletRequest request = new MockHttpServletRequest(); + + private final WebRequest webRequest = new ServletWebRequest(this.request); + + @Test + void includeTimeStamp() { + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults()); + assertThat(attributes.get("timestamp")).isInstanceOf(Date.class); + } + + @Test + void specificStatusCode() { + this.request.setAttribute("jakarta.servlet.error.status_code", 404); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults()); + assertThat(attributes).containsEntry("error", HttpStatus.NOT_FOUND.getReasonPhrase()); + assertThat(attributes).containsEntry("status", 404); + } + + @Test + void missingStatusCode() { + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults()); + assertThat(attributes).containsEntry("error", "None"); + assertThat(attributes).containsEntry("status", 999); + } + + @Test + void mvcError() { + RuntimeException ex = new RuntimeException("Test"); + ModelAndView modelAndView = this.errorAttributes.resolveException(this.request, null, null, ex); + this.request.setAttribute("jakarta.servlet.error.exception", new RuntimeException("Ignored")); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); + assertThat(modelAndView).isNull(); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).containsEntry("message", "Test"); + } + + @Test + void servletErrorWithMessage() { + RuntimeException ex = new RuntimeException("Test"); + this.request.setAttribute("jakarta.servlet.error.exception", ex); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).containsEntry("message", "Test"); + } + + @Test + void servletErrorWithoutMessage() { + RuntimeException ex = new RuntimeException("Test"); + this.request.setAttribute("jakarta.servlet.error.exception", ex); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults()); + assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).doesNotContainKey("message"); + } + + @Test + void servletMessageWithMessage() { + this.request.setAttribute("jakarta.servlet.error.message", "Test"); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).containsEntry("message", "Test"); + } + + @Test + void servletMessageWithoutMessage() { + this.request.setAttribute("jakarta.servlet.error.message", "Test"); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults()); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).doesNotContainKey("message"); + } + + @Test + void nullExceptionMessage() { + this.request.setAttribute("jakarta.servlet.error.exception", new RuntimeException()); + this.request.setAttribute("jakarta.servlet.error.message", "Test"); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).containsEntry("message", "Test"); + } + + @Test + void nullExceptionMessageAndServletMessage() { + this.request.setAttribute("jakarta.servlet.error.exception", new RuntimeException()); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).containsEntry("message", "No message available"); + } + + @Test + void unwrapServletException() { + RuntimeException ex = new RuntimeException("Test"); + ServletException wrapped = new ServletException(new ServletException(ex)); + this.request.setAttribute("jakarta.servlet.error.exception", wrapped); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(wrapped); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).containsEntry("message", "Test"); + } + + @Test + void getError() { + Error error = new OutOfMemoryError("Test error"); + this.request.setAttribute("jakarta.servlet.error.exception", error); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(error); + assertThat(attributes).doesNotContainKey("exception"); + assertThat(attributes).containsEntry("message", "Test error"); + } + + @Test + void withBindingErrors() { + BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); + bindingResult.addError(new ObjectError("c", "d")); + Exception ex = new BindException(bindingResult); + testBindingResult(bindingResult, ex, ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); + } + + @Test + void withoutBindingErrors() { + BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); + bindingResult.addError(new ObjectError("c", "d")); + Exception ex = new BindException(bindingResult); + testBindingResult(bindingResult, ex, ErrorAttributeOptions.defaults()); + } + + @Test + void withMethodArgumentNotValidExceptionBindingErrors() { + Method method = ReflectionUtils.findMethod(String.class, "substring", int.class); + MethodParameter parameter = new MethodParameter(method, 0); + BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); + bindingResult.addError(new ObjectError("c", "d")); + Exception ex = new MethodArgumentNotValidException(parameter, bindingResult); + testBindingResult(bindingResult, ex, ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); + } + + @Test + void withHandlerMethodValidationExceptionBindingErrors() { + Object target = "test"; + Method method = ReflectionUtils.findMethod(String.class, "substring", int.class); + MethodParameter parameter = new MethodParameter(method, 0); + MethodValidationResult methodValidationResult = MethodValidationResult.create(target, method, + List.of(new ParameterValidationResult(parameter, -1, + List.of(new ObjectError("beginIndex", "beginIndex is negative")), null, null, null, + (error, sourceType) -> { + throw new IllegalArgumentException("No source object of the given type"); + }))); + HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult); + testErrors(methodValidationResult.getAllErrors(), + "Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1", + ex, ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); + } + + private void testBindingResult(BindingResult bindingResult, Exception ex, ErrorAttributeOptions options) { + testErrors(bindingResult.getAllErrors(), "Validation failed for object='objectName'. Error count: 1", ex, + options); + } + + private void testErrors(List errors, String expectedMessage, Exception ex, + ErrorAttributeOptions options) { + this.request.setAttribute("jakarta.servlet.error.exception", ex); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, options); + if (options.isIncluded(Include.MESSAGE)) { + assertThat(attributes).containsEntry("message", expectedMessage); + } + else { + assertThat(attributes).doesNotContainKey("message"); + } + if (options.isIncluded(Include.BINDING_ERRORS)) { + assertThat(attributes).containsEntry("errors", org.springframework.boot.web.error.Error.wrap(errors)); + } + else { + assertThat(attributes).doesNotContainKey("errors"); + } + } + + @Test + void withExceptionAttribute() { + DefaultErrorAttributes errorAttributes = new DefaultErrorAttributes(); + RuntimeException ex = new RuntimeException("Test"); + this.request.setAttribute("jakarta.servlet.error.exception", ex); + Map attributes = errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE)); + assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); + assertThat(attributes).containsEntry("message", "Test"); + } + + @Test + void withStackTraceAttribute() { + RuntimeException ex = new RuntimeException("Test"); + this.request.setAttribute("jakarta.servlet.error.exception", ex); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.STACK_TRACE)); + assertThat(attributes.get("trace").toString()).startsWith("java.lang"); + } + + @Test + void withoutStackTraceAttribute() { + RuntimeException ex = new RuntimeException("Test"); + this.request.setAttribute("jakarta.servlet.error.exception", ex); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults()); + assertThat(attributes).doesNotContainKey("trace"); + } + + @Test + void shouldIncludePathByDefault() { + this.request.setAttribute("jakarta.servlet.error.request_uri", "path"); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults()); + assertThat(attributes).containsEntry("path", "path"); + } + + @Test + void shouldIncludePath() { + this.request.setAttribute("jakarta.servlet.error.request_uri", "path"); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of(Include.PATH)); + assertThat(attributes).containsEntry("path", "path"); + } + + @Test + void shouldExcludePath() { + this.request.setAttribute("jakarta.servlet.error.request_uri", "path"); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.of()); + assertThat(attributes).doesNotContainEntry("path", "path"); + } + + @Test + void whenGetMessageIsOverriddenThenMessageAttributeContainsValueReturnedFromIt() { + Map attributes = new DefaultErrorAttributes() { + + @Override + protected String getMessage(WebRequest webRequest, Throwable error) { + return "custom message"; + } + + }.getErrorAttributes(this.webRequest, ErrorAttributeOptions.of(Include.MESSAGE)); + assertThat(attributes).containsEntry("message", "custom message"); + } + + @Test + void excludeStatus() { + this.request.setAttribute("jakarta.servlet.error.status_code", 404); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults().excluding(Include.STATUS)); + assertThat(attributes).doesNotContainKey("status"); + } + + @Test + void excludeError() { + this.request.setAttribute("jakarta.servlet.error.status_code", 404); + Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, + ErrorAttributeOptions.defaults().excluding(Include.ERROR)); + assertThat(attributes).doesNotContainKey("error"); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/4xx/error/402.html b/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/4xx/error/402.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/4xx/error/402.html rename to spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/4xx/error/402.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/4xx/error/4xx.html b/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/4xx/error/4xx.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/4xx/error/4xx.html rename to spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/4xx/error/4xx.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/5xx/error/4xx.html b/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/5xx/error/4xx.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/5xx/error/4xx.html rename to spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/5xx/error/4xx.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/5xx/error/5xx.html b/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/5xx/error/5xx.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/5xx/error/5xx.html rename to spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/5xx/error/5xx.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/exact/error/404.html b/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/exact/error/404.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/exact/error/404.html rename to spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/exact/error/404.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/exact/error/4xx.html b/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/exact/error/4xx.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/error/exact/error/4xx.html rename to spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/error/exact/error/4xx.html diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/index.html b/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/index.html similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/servlet/index.html rename to spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/index.html diff --git a/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/static/custom.css b/spring-boot-project/spring-boot-webmvc/src/test/resources/org/springframework/boot/webmvc/autoconfigure/static/custom.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcEndpointConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcEndpointConfiguration.java new file mode 100644 index 000000000000..c7335bcfdb6d --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcEndpointConfiguration.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.actuate.endpoint.web.test; + +import java.util.Collections; + +import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; +import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; +import org.springframework.boot.actuate.endpoint.web.EndpointMapping; +import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; + +/** + * Endpoint configuration for WebMvc. + * + * @author Andy Wilkinson + * @author Stephane Nicoll + */ +@Configuration(proxyBeanMethods = false) +@ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class }) +class WebMvcEndpointConfiguration { + + private final ApplicationContext applicationContext; + + WebMvcEndpointConfiguration(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Bean + TomcatServletWebServerFactory tomcat() { + return new TomcatServletWebServerFactory(0); + } + + @Bean + WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping() { + EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; + WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, + new ConversionServiceParameterValueMapper(), endpointMediaTypes, Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + return new WebMvcEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), + endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), + true); + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcWebEndpointInfrastructureProvider.java b/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcWebEndpointInfrastructureProvider.java new file mode 100644 index 000000000000..9f2fc41428e5 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcWebEndpointInfrastructureProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.webmvc.actuate.endpoint.web.test; + +import java.util.List; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider; +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; + +/** + * {@link WebEndpointInfrastructureProvider} for MVC. + * + * @author Stephane Nicoll + */ +class WebMvcWebEndpointInfrastructureProvider implements WebEndpointInfrastructureProvider { + + @Override + public boolean supports(Infrastructure infrastructure) { + return infrastructure == Infrastructure.MVC; + } + + @Override + public List> getInfrastructureConfiguration(Infrastructure infrastructure) { + return List.of(WebMvcEndpointConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/testFixtures/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-webmvc/src/testFixtures/resources/META-INF/spring.factories new file mode 100644 index 000000000000..5fae52b11754 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/testFixtures/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider=\ +org.springframework.boot.webmvc.actuate.endpoint.web.test.WebMvcWebEndpointInfrastructureProvider diff --git a/spring-boot-project/spring-boot-webservices/build.gradle b/spring-boot-project/spring-boot-webservices/build.gradle new file mode 100644 index 000000000000..98ccc23f6925 --- /dev/null +++ b/spring-boot-project/spring-boot-webservices/build.gradle @@ -0,0 +1,44 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Web Services" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api(project(":spring-boot-project:spring-boot-http-client")) + api("org.springframework:spring-oxm") + api("org.springframework.ws:spring-ws-core") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("jakarta.servlet:jakarta.servlet-api") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation("org.eclipse.jetty:jetty-client") + + testRuntimeOnly("ch.qos.logback:logback-classic") + testRuntimeOnly("io.projectreactor.netty:reactor-netty-http") + testRuntimeOnly("org.apache.httpcomponents.client5:httpclient5") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/OnWsdlLocationsCondition.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/OnWsdlLocationsCondition.java similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/OnWsdlLocationsCondition.java rename to spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/OnWsdlLocationsCondition.java index 9781ce13452c..b7e6eeadb0c7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/OnWsdlLocationsCondition.java +++ b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/OnWsdlLocationsCondition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.webservices; +package org.springframework.boot.webservices.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.OnPropertyListCondition; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/WebServicesAutoConfiguration.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/WebServicesAutoConfiguration.java rename to spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesAutoConfiguration.java index 94ba0bb72f30..477bf23a7ef8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/WebServicesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.webservices; +package org.springframework.boot.webservices.autoconfigure; import java.io.IOException; import java.util.Collections; @@ -33,7 +33,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; @@ -57,9 +56,9 @@ * * @author Vedran Pavic * @author Stephane Nicoll - * @since 1.4.0 + * @since 4.0.0 */ -@AutoConfiguration(after = ServletWebServerFactoryAutoConfiguration.class) +@AutoConfiguration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass(MessageDispatcherServlet.class) @ConditionalOnMissingBean(WsConfigurationSupport.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/WebServicesProperties.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesProperties.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/WebServicesProperties.java rename to spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesProperties.java index 5171edd5b325..a93dd86a9d21 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/WebServicesProperties.java +++ b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/WebServicesProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.webservices; +package org.springframework.boot.webservices.autoconfigure; import java.util.HashMap; import java.util.Map; @@ -27,7 +27,7 @@ * * @author Vedran Pavic * @author Stephane Nicoll - * @since 1.4.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.webservices") public class WebServicesProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/client/WebServiceTemplateAutoConfiguration.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/client/WebServiceTemplateAutoConfiguration.java similarity index 93% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/client/WebServiceTemplateAutoConfiguration.java rename to spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/client/WebServiceTemplateAutoConfiguration.java index 7de090fd2d7d..c02b837a6411 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/webservices/client/WebServiceTemplateAutoConfiguration.java +++ b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/client/WebServiceTemplateAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.webservices.client; +package org.springframework.boot.webservices.autoconfigure.client; import java.util.List; @@ -23,7 +23,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.webservices.client.WebServiceMessageSenderFactory; @@ -38,9 +37,9 @@ * {@link EnableAutoConfiguration Auto-configuration} for {@link WebServiceTemplate}. * * @author Dmytro Nosan - * @since 2.1.0 + * @since 4.0.0 */ -@AutoConfiguration(after = HttpClientAutoConfiguration.class) +@AutoConfiguration @ConditionalOnClass({ WebServiceTemplate.class, Unmarshaller.class, Marshaller.class }) public class WebServiceTemplateAutoConfiguration { diff --git a/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/client/package-info.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/client/package-info.java new file mode 100644 index 000000000000..886110ca10c3 --- /dev/null +++ b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/client/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Web Services Clients. + */ +package org.springframework.boot.webservices.autoconfigure.client; diff --git a/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/package-info.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/package-info.java new file mode 100644 index 000000000000..344d4fd28cb9 --- /dev/null +++ b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Spring Web Services. + */ +package org.springframework.boot.webservices.autoconfigure; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/WebServiceMessageSenderFactory.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/WebServiceMessageSenderFactory.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/WebServiceMessageSenderFactory.java rename to spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/WebServiceMessageSenderFactory.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilder.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilder.java similarity index 99% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilder.java rename to spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilder.java index 445f54ff2cfd..e5f110fdd9a7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilder.java +++ b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilder.java @@ -117,7 +117,6 @@ private WebServiceTemplateBuilder(WebServiceMessageSenderFactory messageSenderFa * @param messageSenderFactory the {@link WebServiceMessageSenderFactory} to use * @return a new builder instance * @since 3.4.0 - * @see HttpWebServiceMessageSenderBuilder */ public WebServiceTemplateBuilder httpMessageSenderFactory(WebServiceMessageSenderFactory messageSenderFactory) { Assert.notNull(messageSenderFactory, "'messageSenderFactory' must not be null"); @@ -132,7 +131,6 @@ public WebServiceTemplateBuilder httpMessageSenderFactory(WebServiceMessageSende * @param detectHttpMessageSender if an HTTP-based {@link WebServiceMessageSender} * should be detected * @return a new builder instance - * @see HttpWebServiceMessageSenderBuilder */ public WebServiceTemplateBuilder detectHttpMessageSender(boolean detectHttpMessageSender) { return new WebServiceTemplateBuilder(this.httpMessageSenderFactory, detectHttpMessageSender, this.interceptors, diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateCustomizer.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateCustomizer.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateCustomizer.java rename to spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/WebServiceTemplateCustomizer.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/package-info.java b/spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/package-info.java rename to spring-boot-project/spring-boot-webservices/src/main/java/org/springframework/boot/webservices/client/package-info.java diff --git a/spring-boot-project/spring-boot-webservices/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-webservices/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..8aab0bce5fe0 --- /dev/null +++ b/spring-boot-project/spring-boot-webservices/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,9 @@ +{ + "properties": [ + { + "name": "spring.webservices.wsdl-locations", + "type": "java.util.List", + "description": "Comma-separated list of locations of WSDLs and accompanying XSDs to be exposed as beans." + } + ] +} diff --git a/spring-boot-project/spring-boot-webservices/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-webservices/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..2ab305e059a6 --- /dev/null +++ b/spring-boot-project/spring-boot-webservices/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +org.springframework.boot.webservices.autoconfigure.WebServicesAutoConfiguration +org.springframework.boot.webservices.autoconfigure.client.WebServiceTemplateAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/OnWsdlLocationsConditionTests.java b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/OnWsdlLocationsConditionTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/OnWsdlLocationsConditionTests.java rename to spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/OnWsdlLocationsConditionTests.java index f5f750746ac3..bf43067e596a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/OnWsdlLocationsConditionTests.java +++ b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/OnWsdlLocationsConditionTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.webservices; +package org.springframework.boot.webservices.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/WebServicesAutoConfigurationTests.java b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/WebServicesAutoConfigurationTests.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/WebServicesAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/WebServicesAutoConfigurationTests.java index 1c195f56e16b..75a5fd48b252 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/WebServicesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/WebServicesAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.webservices; +package org.springframework.boot.webservices.autoconfigure; import java.util.Collection; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/WebServicesPropertiesTests.java b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/WebServicesPropertiesTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/WebServicesPropertiesTests.java rename to spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/WebServicesPropertiesTests.java index d88040807f91..16a13ca57af6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/WebServicesPropertiesTests.java +++ b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/WebServicesPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.webservices; +package org.springframework.boot.webservices.autoconfigure; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/client/WebServiceTemplateAutoConfigurationTests.java b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/client/WebServiceTemplateAutoConfigurationTests.java similarity index 90% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/client/WebServiceTemplateAutoConfigurationTests.java rename to spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/client/WebServiceTemplateAutoConfigurationTests.java index 391e3df6a949..8155ecbd2746 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/webservices/client/WebServiceTemplateAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/autoconfigure/client/WebServiceTemplateAutoConfigurationTests.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.webservices.client; +package org.springframework.boot.webservices.autoconfigure.client; import java.util.function.Consumer; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.http.client.HttpClientAutoConfiguration; +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; @@ -48,8 +47,8 @@ */ class WebServiceTemplateAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(WebServiceTemplateAutoConfiguration.class, HttpClientAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(WebServiceTemplateAutoConfiguration.class)); @Test void autoConfiguredBuilderShouldNotHaveMarshallerAndUnmarshaller() { @@ -97,9 +96,8 @@ void builderShouldBeFreshForEachUse() { } @Test - void whenHasFactoryProperty() { - this.contextRunner.withConfiguration(AutoConfigurations.of(HttpMessageConvertersAutoConfiguration.class)) - .withPropertyValues("spring.http.client.factory=simple") + void whenHasFactory() { + this.contextRunner.withBean(ClientHttpRequestFactoryBuilder.class, ClientHttpRequestFactoryBuilder::simple) .run(assertWebServiceTemplateBuilder((builder) -> { WebServiceTemplate webServiceTemplate = builder.build(); assertThat(webServiceTemplate.getMessageSenders()).hasSize(1); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/WebServiceMessageSenderFactoryTests.java b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/client/WebServiceMessageSenderFactoryTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/WebServiceMessageSenderFactoryTests.java rename to spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/client/WebServiceMessageSenderFactoryTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilderTests.java b/spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilderTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilderTests.java rename to spring-boot-project/spring-boot-webservices/src/test/java/org/springframework/boot/webservices/client/WebServiceTemplateBuilderTests.java diff --git a/spring-boot-project/spring-boot-websocket/build.gradle b/spring-boot-project/spring-boot-websocket/build.gradle new file mode 100644 index 000000000000..e84f82ba41c7 --- /dev/null +++ b/spring-boot-project/spring-boot-websocket/build.gradle @@ -0,0 +1,42 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot WebSocket" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.springframework:spring-messaging") + api("org.springframework:spring-websocket") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-jackson")) + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(project(":spring-boot-project:spring-boot-webmvc")) + testImplementation("org.apache.tomcat.embed:tomcat-embed-websocket") + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfiguration.java b/spring-boot-project/spring-boot-websocket/src/main/java/org/springframework/boot/websocket/autoconfigure/servlet/WebSocketMessagingAutoConfiguration.java similarity index 95% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfiguration.java rename to spring-boot-project/spring-boot-websocket/src/main/java/org/springframework/boot/websocket/autoconfigure/servlet/WebSocketMessagingAutoConfiguration.java index 8851a8a12e98..fdade17c2633 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-websocket/src/main/java/org/springframework/boot/websocket/autoconfigure/servlet/WebSocketMessagingAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.websocket.servlet; +package org.springframework.boot.websocket.autoconfigure.servlet; import java.util.List; import java.util.Map; @@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -50,9 +49,9 @@ * @author Andy Wilkinson * @author Lasse Wulff * @author Moritz Halbritter - * @since 1.3.0 + * @since 4.0.0 */ -@AutoConfiguration(after = JacksonAutoConfiguration.class) +@AutoConfiguration(afterName = "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration") @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass(WebSocketMessageBrokerConfigurer.class) public class WebSocketMessagingAutoConfiguration { diff --git a/spring-boot-project/spring-boot-websocket/src/main/java/org/springframework/boot/websocket/autoconfigure/servlet/package-info.java b/spring-boot-project/spring-boot-websocket/src/main/java/org/springframework/boot/websocket/autoconfigure/servlet/package-info.java new file mode 100644 index 000000000000..db0507aa8466 --- /dev/null +++ b/spring-boot-project/spring-boot-websocket/src/main/java/org/springframework/boot/websocket/autoconfigure/servlet/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for WebSocket support in servlet web servers. + */ +package org.springframework.boot.websocket.autoconfigure.servlet; diff --git a/spring-boot-project/spring-boot-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..85617d3fddb3 --- /dev/null +++ b/spring-boot-project/spring-boot-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.websocket.autoconfigure.servlet.WebSocketMessagingAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java b/spring-boot-project/spring-boot-websocket/src/test/java/org/springframework/boot/websocket/autoconfigure/servlet/WebSocketMessagingAutoConfigurationTests.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java rename to spring-boot-project/spring-boot-websocket/src/test/java/org/springframework/boot/websocket/autoconfigure/servlet/WebSocketMessagingAutoConfigurationTests.java index 75d6283806ff..718727b1f2eb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-websocket/src/test/java/org/springframework/boot/websocket/autoconfigure/servlet/WebSocketMessagingAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.websocket.servlet; +package org.springframework.boot.websocket.autoconfigure.servlet; import java.lang.reflect.Type; import java.util.ArrayList; @@ -37,15 +37,16 @@ import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration.WebSocketMessageConverterConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.tomcat.autoconfigure.WebSocketTomcatWebServerFactoryCustomizer; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.websocket.autoconfigure.servlet.WebSocketMessagingAutoConfiguration.WebSocketMessageConverterConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -145,7 +146,7 @@ void customizedConverterTypesMatchDefaultConverterTypes() { void predefinedThreadExecutorIsSelectedForInboundChannel() { AsyncTaskExecutor expectedExecutor = new SimpleAsyncTaskExecutor(); ChannelRegistration registration = new ChannelRegistration(); - WebSocketMessagingAutoConfiguration.WebSocketMessageConverterConfiguration configuration = new WebSocketMessagingAutoConfiguration.WebSocketMessageConverterConfiguration( + WebSocketMessageConverterConfiguration configuration = new WebSocketMessagingAutoConfiguration.WebSocketMessageConverterConfiguration( new ObjectMapper(), Map.of(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME, expectedExecutor)); configuration.configureClientInboundChannel(registration); @@ -261,7 +262,7 @@ public void handleTransportError(StompSession session, Throwable exception) { @EnableWebSocket @EnableConfigurationProperties @EnableWebSocketMessageBroker - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class, + @ImportAutoConfiguration({ JacksonAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, WebSocketMessagingAutoConfiguration.class, DispatcherServletAutoConfiguration.class }) static class WebSocketMessagingConfiguration implements WebSocketMessageBrokerConfigurer { @@ -287,8 +288,8 @@ TomcatServletWebServerFactory tomcat() { } @Bean - TomcatWebSocketServletWebServerCustomizer tomcatCustomizer() { - return new TomcatWebSocketServletWebServerCustomizer(); + WebSocketTomcatWebServerFactoryCustomizer tomcatCustomizer() { + return new WebSocketTomcatWebServerFactoryCustomizer(); } } diff --git a/spring-boot-project/spring-boot-zipkin/build.gradle b/spring-boot-project/spring-boot-zipkin/build.gradle new file mode 100644 index 000000000000..b60e7be0a7ef --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/build.gradle @@ -0,0 +1,47 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.docker-test" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Zipkin" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("io.zipkin.reporter2:zipkin-reporter-brave") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional(project(":spring-boot-project:spring-boot-docker-compose")) + optional(project(":spring-boot-project:spring-boot-testcontainers")) + optional("io.zipkin.reporter2:zipkin-reporter-brave") + + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-docker-compose"))) + dockerTestImplementation("org.testcontainers:junit-jupiter") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-testcontainers"))) + testImplementation("com.squareup.okhttp3:mockwebserver") +} diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/zipkin/ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-zipkin/src/dockerTest/java/org/springframework/boot/zipkin/docker/compose/ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests.java similarity index 88% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/zipkin/ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-zipkin/src/dockerTest/java/org/springframework/boot/zipkin/docker/compose/ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests.java index ba40173ef52d..0826b76fa1bb 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/zipkin/ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-zipkin/src/dockerTest/java/org/springframework/boot/zipkin/docker/compose/ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.zipkin; +package org.springframework.boot.zipkin.docker.compose; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.zipkin.autoconfigure.ZipkinConnectionDetails; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-zipkin/src/dockerTest/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryIntegrationTests.java similarity index 89% rename from spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryIntegrationTests.java rename to spring-boot-project/spring-boot-zipkin/src/dockerTest/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryIntegrationTests.java index b366235673a2..76a2802cded7 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-zipkin/src/dockerTest/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.zipkin; +package org.springframework.boot.zipkin.testcontainers; import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; @@ -22,12 +22,12 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.boot.testsupport.container.ZipkinContainer; +import org.springframework.boot.zipkin.autoconfigure.ZipkinAutoConfiguration; +import org.springframework.boot.zipkin.autoconfigure.ZipkinConnectionDetails; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/zipkin/zipkin-compose.yaml b/spring-boot-project/spring-boot-zipkin/src/dockerTest/resources/org/springframework/boot/zipkin/docker/compose/zipkin-compose.yaml similarity index 100% rename from spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/zipkin/zipkin-compose.yaml rename to spring-boot-project/spring-boot-zipkin/src/dockerTest/resources/org/springframework/boot/zipkin/docker/compose/zipkin-compose.yaml diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/HttpSender.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/HttpSender.java similarity index 97% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/HttpSender.java rename to spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/HttpSender.java index 1030abdc4ebb..32addf3a13d8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/HttpSender.java +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/HttpSender.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/PropertiesZipkinConnectionDetails.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/PropertiesZipkinConnectionDetails.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/PropertiesZipkinConnectionDetails.java rename to spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/PropertiesZipkinConnectionDetails.java index 5c59d2fb1d3d..92a83cf0eff9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/PropertiesZipkinConnectionDetails.java +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/PropertiesZipkinConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; /** * Adapts {@link ZipkinProperties} to {@link ZipkinConnectionDetails}. diff --git a/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinAutoConfiguration.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinAutoConfiguration.java new file mode 100644 index 000000000000..a0fecce670b9 --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinAutoConfiguration.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.zipkin.autoconfigure; + +import java.net.http.HttpClient; +import java.net.http.HttpClient.Builder; + +import zipkin2.reporter.BytesMessageSender; +import zipkin2.reporter.Encoding; +import zipkin2.reporter.HttpEndpointSupplier; +import zipkin2.reporter.HttpEndpointSuppliers; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Zipkin. + * + * @author Moritz Halbritter + * @author Moritz Halbritter + * @author Stefan Bratanov + * @author Wick Dynex + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass(Encoding.class) +@EnableConfigurationProperties(ZipkinProperties.class) +public class ZipkinAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(ZipkinConnectionDetails.class) + PropertiesZipkinConnectionDetails zipkinConnectionDetails(ZipkinProperties properties) { + return new PropertiesZipkinConnectionDetails(properties); + } + + @Bean + @ConditionalOnMissingBean + Encoding encoding(ZipkinProperties properties) { + return switch (properties.getEncoding()) { + case JSON -> Encoding.JSON; + case PROTO3 -> Encoding.PROTO3; + }; + } + + @Bean + @ConditionalOnMissingBean(BytesMessageSender.class) + @ConditionalOnClass(HttpClient.class) + ZipkinHttpClientSender httpClientSender(ZipkinProperties properties, Encoding encoding, + ObjectProvider customizers, + ObjectProvider connectionDetailsProvider, + ObjectProvider endpointSupplierFactoryProvider) { + ZipkinConnectionDetails connectionDetails = connectionDetailsProvider + .getIfAvailable(() -> new PropertiesZipkinConnectionDetails(properties)); + HttpEndpointSupplier.Factory endpointSupplierFactory = endpointSupplierFactoryProvider + .getIfAvailable(HttpEndpointSuppliers::constantFactory); + Builder httpClientBuilder = HttpClient.newBuilder().connectTimeout(properties.getConnectTimeout()); + customizers.orderedStream().forEach((customizer) -> customizer.customize(httpClientBuilder)); + return new ZipkinHttpClientSender(encoding, endpointSupplierFactory, connectionDetails.getSpanEndpoint(), + httpClientBuilder.build(), properties.getReadTimeout()); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConnectionDetails.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinConnectionDetails.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConnectionDetails.java rename to spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinConnectionDetails.java index e0ce60c2f6cc..51165d012b60 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConnectionDetails.java +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; import zipkin2.reporter.HttpEndpointSupplier.Factory; @@ -27,7 +27,7 @@ * {@link Factory HttpEndpointSupplier.Factory} which defaults to no-op (constant). * * @author Moritz Halbritter - * @since 3.1.0 + * @since 4.0.0 */ public interface ZipkinConnectionDetails extends ConnectionDetails { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientBuilderCustomizer.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientBuilderCustomizer.java similarity index 92% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientBuilderCustomizer.java rename to spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientBuilderCustomizer.java index d39268ece5ec..19bc7abab892 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; import java.net.http.HttpClient.Builder; @@ -23,7 +23,7 @@ * {@link Builder HttpClient.Builder} used to send spans to Zipkin. * * @author Moritz Halbritter - * @since 3.3.0 + * @since 4.0.0 */ @FunctionalInterface public interface ZipkinHttpClientBuilderCustomizer { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientSender.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientSender.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientSender.java rename to spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientSender.java index 5a6a3793393a..7a62e859895c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientSender.java +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientSender.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; import java.io.IOException; import java.net.URI; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinProperties.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java rename to spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinProperties.java index 7bb99b9b74fa..d9e3b0bee4f6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/ZipkinProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; import java.time.Duration; @@ -24,7 +24,7 @@ * Configuration properties for {@link ZipkinAutoConfiguration}. * * @author Moritz Halbritter - * @since 3.0.0 + * @since 4.0.0 */ @ConfigurationProperties("management.zipkin.tracing") public class ZipkinProperties { diff --git a/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/package-info.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/package-info.java new file mode 100644 index 000000000000..0f7d47393fef --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/autoconfigure/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for Zipkin. + */ +package org.springframework.boot.zipkin.autoconfigure; diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/zipkin/ZipkinDockerComposeConnectionDetailsFactory.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/docker/compose/ZipkinDockerComposeConnectionDetailsFactory.java similarity index 87% rename from spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/zipkin/ZipkinDockerComposeConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/docker/compose/ZipkinDockerComposeConnectionDetailsFactory.java index b3ddea29e950..40f206dc3ca4 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/zipkin/ZipkinDockerComposeConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/docker/compose/ZipkinDockerComposeConnectionDetailsFactory.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.springframework.boot.docker.compose.service.connection.zipkin; +package org.springframework.boot.zipkin.docker.compose; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; +import org.springframework.boot.zipkin.autoconfigure.ZipkinConnectionDetails; /** * {@link DockerComposeConnectionDetailsFactory} to create {@link ZipkinConnectionDetails} @@ -35,8 +35,7 @@ class ZipkinDockerComposeConnectionDetailsFactory private static final int ZIPKIN_PORT = 9411; ZipkinDockerComposeConnectionDetailsFactory() { - super("openzipkin/zipkin", - "org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration"); + super("openzipkin/zipkin", "org.springframework.boot.zipkin.autoconfigure.ZipkinAutoConfiguration"); } @Override diff --git a/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/docker/compose/package-info.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/docker/compose/package-info.java new file mode 100644 index 000000000000..846796b7355c --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/docker/compose/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for Docker Compose Zipkin service connections. + */ +package org.springframework.boot.zipkin.docker.compose; diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactory.java similarity index 88% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactory.java rename to spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactory.java index c4ae27e2f55f..c4eadafc650a 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactory.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.zipkin; +package org.springframework.boot.zipkin.testcontainers; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.boot.zipkin.autoconfigure.ZipkinConnectionDetails; /** * {@link ContainerConnectionDetailsFactory} to create {@link ZipkinConnectionDetails} @@ -38,8 +38,7 @@ class ZipkinContainerConnectionDetailsFactory private static final int ZIPKIN_PORT = 9411; ZipkinContainerConnectionDetailsFactory() { - super("openzipkin/zipkin", - "org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration"); + super("openzipkin/zipkin", "org.springframework.boot.zipkin.autoconfigure.ZipkinAutoConfiguration"); } @Override diff --git a/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/testcontainers/package-info.java b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/testcontainers/package-info.java new file mode 100644 index 000000000000..f1ce8fda22ac --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/src/main/java/org/springframework/boot/zipkin/testcontainers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support for testcontainers Zipkin service connections. + */ +package org.springframework.boot.zipkin.testcontainers; diff --git a/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000000..bb197d579a8a --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,12 @@ +{ + "groups": [], + "properties": [ + { + "name": "management.zipkin.tracing.encoding", + "defaultValue": [ + "JSON" + ] + } + ], + "hints": [] +} diff --git a/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..1a4f790626a5 --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Connection Details Factories +org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ +org.springframework.boot.zipkin.docker.compose.ZipkinDockerComposeConnectionDetailsFactory,\ +org.springframework.boot.zipkin.testcontainers.ZipkinContainerConnectionDetailsFactory diff --git a/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000000..e540382114dc --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.zipkin.autoconfigure.ZipkinAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/TestHttpEndpointSupplier.java b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/TestHttpEndpointSupplier.java similarity index 94% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/TestHttpEndpointSupplier.java rename to spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/TestHttpEndpointSupplier.java index a26cc92164b4..422010c09c9f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/TestHttpEndpointSupplier.java +++ b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/TestHttpEndpointSupplier.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; import java.util.concurrent.atomic.AtomicInteger; diff --git a/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinAutoConfigurationTests.java b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinAutoConfigurationTests.java new file mode 100644 index 000000000000..bc0f07bbba3f --- /dev/null +++ b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinAutoConfigurationTests.java @@ -0,0 +1,188 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.zipkin.autoconfigure; + +import java.net.http.HttpClient; + +import org.junit.jupiter.api.Test; +import zipkin2.reporter.BytesMessageSender; +import zipkin2.reporter.Encoding; +import zipkin2.reporter.HttpEndpointSupplier; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link ZipkinAutoConfiguration}. + * + * @author Moritz Halbritter + * @author Wick Dynex + */ +class ZipkinAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ZipkinAutoConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(Encoding.class); + assertThat(context).hasSingleBean(PropertiesZipkinConnectionDetails.class); + assertThat(context).hasSingleBean(BytesMessageSender.class); + assertThat(context).hasSingleBean(ZipkinHttpClientSender.class); + }); + } + + @Test + void shouldNotSupplyBeansIfZipkinReporterIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("zipkin2.reporter")) + .run((context) -> assertThat(context).doesNotHaveBean(Encoding.class)); + } + + @Test + void shouldNotProvideHttpClientSenderIfHttpClientIsNotAvailable() { + this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class)) + .run((context) -> assertThat(context).doesNotHaveBean(ZipkinHttpClientSender.class)); + } + + @Test + void shouldBackOffOnCustomEncodingBeans() { + this.contextRunner.withUserConfiguration(CustomEncodingConfiguration.class).run((context) -> { + assertThat(context).hasBean("customEncoding"); + assertThat(context).hasSingleBean(Encoding.class); + }); + } + + @Test + void shouldBackOffOnCustomSenderBeans() { + this.contextRunner.withUserConfiguration(CustomSenderConfiguration.class).run((context) -> { + assertThat(context).hasBean("customSender"); + assertThat(context).hasSingleBean(BytesMessageSender.class); + }); + } + + @Test + void shouldUseCustomHttpEndpointSupplierFactory() { + this.contextRunner.withUserConfiguration(CustomHttpEndpointSupplierFactoryConfiguration.class) + .run((context) -> { + ZipkinHttpClientSender httpClientSender = context.getBean(ZipkinHttpClientSender.class); + assertThat(httpClientSender).extracting("endpointSupplier") + .isInstanceOf(CustomHttpEndpointSupplier.class); + }); + } + + @Test + void definesPropertiesBasedConnectionDetailsByDefault() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesZipkinConnectionDetails.class)); + } + + @Test + void shouldUseCustomConnectionDetailsWhenDefined() { + this.contextRunner + .withBean(ZipkinConnectionDetails.class, () -> new FixedZipkinConnectionDetails("http://localhost")) + .run((context) -> assertThat(context).hasSingleBean(ZipkinConnectionDetails.class) + .doesNotHaveBean(PropertiesZipkinConnectionDetails.class)); + } + + @Test + void shouldWorkWithoutSenders() { + this.contextRunner + .withClassLoader(new FilteredClassLoader("org.springframework.web.client", + "org.springframework.web.reactive.function.client")) + .run((context) -> assertThat(context).hasNotFailed()); + } + + private static final class FixedZipkinConnectionDetails implements ZipkinConnectionDetails { + + private final String spanEndpoint; + + private FixedZipkinConnectionDetails(String spanEndpoint) { + this.spanEndpoint = spanEndpoint; + } + + @Override + public String getSpanEndpoint() { + return this.spanEndpoint; + } + + } + + @Configuration(proxyBeanMethods = false) + private static final class CustomEncodingConfiguration { + + @Bean + Encoding customEncoding() { + return Encoding.PROTO3; + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomSenderConfiguration { + + @Bean + BytesMessageSender customSender() { + return mock(BytesMessageSender.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class CustomHttpEndpointSupplierFactoryConfiguration { + + @Bean + HttpEndpointSupplier.Factory httpEndpointSupplier() { + return new CustomHttpEndpointSupplierFactory(); + } + + } + + static class CustomHttpEndpointSupplierFactory implements HttpEndpointSupplier.Factory { + + @Override + public HttpEndpointSupplier create(String endpoint) { + return new CustomHttpEndpointSupplier(endpoint); + } + + } + + static class CustomHttpEndpointSupplier implements HttpEndpointSupplier { + + private final String endpoint; + + CustomHttpEndpointSupplier(String endpoint) { + this.endpoint = endpoint; + } + + @Override + public String get() { + return this.endpoint; + } + + @Override + public void close() { + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientSenderTests.java b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientSenderTests.java similarity index 98% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientSenderTests.java rename to spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientSenderTests.java index f36e95efb5f9..889e42b588f6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpClientSenderTests.java +++ b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpClientSenderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; import java.io.IOException; import java.net.http.HttpClient; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpSenderTests.java b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpSenderTests.java similarity index 96% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpSenderTests.java rename to spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpSenderTests.java index dfa7a6b66329..623063c53f33 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinHttpSenderTests.java +++ b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/autoconfigure/ZipkinHttpSenderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; +package org.springframework.boot.zipkin.autoconfigure; import java.io.IOException; import java.nio.charset.StandardCharsets; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryTests.java similarity index 88% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryTests.java rename to spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryTests.java index b0969d87da00..61be89fc09e7 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryTests.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.zipkin; +package org.springframework.boot.zipkin.testcontainers; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; +import org.springframework.boot.zipkin.autoconfigure.ZipkinAutoConfiguration; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java similarity index 94% rename from spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java rename to spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java index 1d0a390fba6b..7afc3c03ba0e 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java +++ b/spring-boot-project/spring-boot-zipkin/src/test/java/org/springframework/boot/zipkin/testcontainers/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.testcontainers.service.connection.zipkin; +package org.springframework.boot.zipkin.testcontainers; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot/build.gradle b/spring-boot-project/spring-boot/build.gradle index d2833eed4af9..09f986b48830 100644 --- a/spring-boot-project/spring-boot/build.gradle +++ b/spring-boot-project/spring-boot/build.gradle @@ -26,12 +26,6 @@ plugins { description = "Spring Boot" -def tomcatConfigProperties = layout.buildDirectory.dir("tomcat-config-properties") - -configurations { - tomcatDistribution -} - dependencies { annotationProcessor("org.apache.logging.log4j:log4j-core") @@ -39,137 +33,42 @@ dependencies { api("org.springframework:spring-context") optional("ch.qos.logback:logback-classic") - optional("com.clickhouse:clickhouse-jdbc") optional("com.fasterxml.jackson.core:jackson-databind") - optional("com.h2database:h2") optional("com.google.code.gson:gson") - optional("com.mchange:c3p0") - optional("com.oracle.database.jdbc:ucp11") - optional("com.oracle.database.jdbc:ojdbc11") - optional("com.samskivert:jmustache") - optional("com.zaxxer:HikariCP") - optional("io.netty:netty-tcnative-boringssl-static") - optional("io.projectreactor:reactor-tools") - optional("io.projectreactor.netty:reactor-netty-http") - optional("io.r2dbc:r2dbc-pool") - optional("io.rsocket:rsocket-core") - optional("io.rsocket:rsocket-transport-netty") - optional("io.undertow:undertow-servlet") - optional("jakarta.jms:jakarta.jms-api") - optional("jakarta.persistence:jakarta.persistence-api") + optional("io.projectreactor:reactor-core") optional("jakarta.servlet:jakarta.servlet-api") - optional("jakarta.transaction:jakarta.transaction-api") - optional("junit:junit") - optional("org.apache.commons:commons-dbcp2") - optional("org.apache.httpcomponents.client5:httpclient5") - optional("org.apache.httpcomponents.core5:httpcore5-reactive") + optional("jakarta.validation:jakarta.validation-api") + optional("org.apache.groovy:groovy") optional("org.apache.logging.log4j:log4j-api") optional("org.apache.logging.log4j:log4j-core") optional("org.apache.logging.log4j:log4j-jul") - optional("org.apache.tomcat.embed:tomcat-embed-core") - optional("org.apache.tomcat.embed:tomcat-embed-jasper") - optional("org.apache.tomcat:tomcat-jdbc") - optional("org.assertj:assertj-core") - optional("org.apache.groovy:groovy") - optional("org.apache.groovy:groovy-xml") optional("org.crac:crac") - optional("org.eclipse.jetty:jetty-alpn-conscrypt-server") - optional("org.eclipse.jetty:jetty-client") - optional("org.eclipse.jetty:jetty-reactive-httpclient") - optional("org.eclipse.jetty:jetty-util") - optional("org.eclipse.jetty.ee10:jetty-ee10-servlets") - optional("org.eclipse.jetty.ee10:jetty-ee10-webapp") - optional("org.eclipse.jetty.http2:jetty-http2-server") - optional("org.flywaydb:flyway-core") - optional("org.hamcrest:hamcrest-library") - optional("org.hibernate.orm:hibernate-core") - optional("org.hibernate.validator:hibernate-validator") - optional("org.jooq:jooq") - optional("org.liquibase:liquibase-core") { - exclude(group: "javax.xml.bind", module: "jaxb-api") - } - optional("org.messaginghub:pooled-jms") { - exclude group: "org.apache.geronimo.specs", module: "geronimo-jms_2.0_spec" - } - optional("org.postgresql:postgresql") + optional("org.jetbrains.kotlin:kotlin-reflect") + optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.slf4j:jul-to-slf4j") - optional("org.slf4j:slf4j-api") - optional("org.springframework:spring-messaging") - optional("org.springframework:spring-orm") - optional("org.springframework:spring-jms") - optional("org.springframework:spring-oxm") - optional("org.springframework:spring-r2dbc") optional("org.springframework:spring-test") optional("org.springframework:spring-web") - optional("org.springframework:spring-webflux") - optional("org.springframework:spring-webmvc") - optional("org.springframework.security:spring-security-web") - optional("org.springframework.ws:spring-ws-core") { - exclude group: "com.sun.mail", module: "jakarta.mail" - exclude group: "jakarta.platform", module: "jakarta.jakartaee-api" - exclude group: "org.eclipse.jetty", module: "jetty-server" - exclude group: "org.eclipse.jetty", module: "jetty-servlet" - exclude group: "jakarta.mail", module: "jakarta.mail-api" - } - optional("org.vibur:vibur-dbcp") optional("org.yaml:snakeyaml") - optional("org.jetbrains.kotlin:kotlin-reflect") - optional("org.jetbrains.kotlin:kotlin-stdlib") - optional("software.amazon.jdbc:aws-advanced-jdbc-wrapper") - testFixturesCompileOnly("jakarta.servlet:jakarta.servlet-api") - testFixturesCompileOnly("org.mockito:mockito-core") - testFixturesCompileOnly("org.springframework:spring-web") + testFixturesCompileOnly(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - testImplementation("org.springframework:spring-core-test") - testImplementation("com.ibm.db2:jcc") - testImplementation("com.jayway.jsonpath:json-path") - testImplementation("com.microsoft.sqlserver:mssql-jdbc") - testImplementation("com.mysql:mysql-connector-j") - testImplementation("com.sun.xml.messaging.saaj:saaj-impl") testImplementation("io.projectreactor:reactor-test") - testImplementation("io.r2dbc:r2dbc-h2") + testImplementation("io.projectreactor.netty:reactor-netty-http") + testImplementation("jakarta.annotation:jakarta.annotation-api") testImplementation("jakarta.inject:jakarta.inject-api") - testImplementation("jakarta.xml.ws:jakarta.xml.ws-api") - testImplementation("net.sourceforge.jtds:jtds") - testImplementation("org.apache.derby:derby") - testImplementation("org.apache.derby:derbytools") - testImplementation("org.awaitility:awaitility") + testImplementation("org.apache.groovy:groovy-xml") + testImplementation("org.apache.httpcomponents.client5:httpclient5") + testImplementation("org.apache.tomcat:tomcat-jdbc") + testImplementation("org.apache.tomcat.embed:tomcat-embed-core") + testImplementation("org.apache.tomcat.embed:tomcat-embed-jasper") testImplementation("org.codehaus.janino:janino") testImplementation("org.eclipse.jetty:jetty-client") testImplementation("org.eclipse.jetty.http2:jetty-http2-client") testImplementation("org.eclipse.jetty.http2:jetty-http2-client-transport") - testImplementation("org.firebirdsql.jdbc:jaybird") { - exclude group: "javax.resource", module: "connector-api" - } - testImplementation("org.hsqldb:hsqldb") - testImplementation("org.junit.jupiter:junit-jupiter") - testImplementation("org.mariadb.jdbc:mariadb-java-client") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.springframework:spring-context-support") - testImplementation("org.springframework:spring-core-test") - testImplementation("org.springframework.data:spring-data-redis") + testImplementation("org.hibernate.validator:hibernate-validator") + testImplementation("org.jboss.logging:jboss-logging") testImplementation("org.springframework.data:spring-data-r2dbc") - testImplementation("org.xerial:sqlite-jdbc") - - testRuntimeOnly("org.testcontainers:jdbc") { - exclude group: "javax.annotation", module: "javax.annotation-api" - } - - tomcatDistribution("org.apache.tomcat:tomcat:${tomcatVersion}@zip") -} - -tasks.register("extractTomcatConfigProperties", Sync) { - destinationDir = file(tomcatConfigProperties) - from { - zipTree(configurations.tomcatDistribution.incoming.files.singleFile).matching { - include '**/conf/catalina.properties' - }.singleFile - } } def syncJavaTemplates = tasks.register("syncJavaTemplates", Sync) { @@ -200,11 +99,4 @@ sourceSets { srcDirs syncJavaTemplates } } - test { - output.dir(tomcatConfigProperties, builtBy: "extractTomcatConfigProperties") - } -} - -test { - jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java index 754cd9d0adc7..8e6f1a5ee351 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java @@ -138,10 +138,7 @@ private MapPropertySource getVersionSource(Class sourceClass, Environment env } private Map getVersionsMap(Class sourceClass, Environment environment, String defaultValue) { - String appVersion = getApplicationVersion(sourceClass); - if (appVersion == null) { - appVersion = getApplicationVersion(environment); - } + String appVersion = getApplicationVersion(environment); String bootVersion = getBootVersion(); Map versions = new HashMap<>(); versions.put("application.version", getVersionString(appVersion, false, defaultValue)); @@ -151,17 +148,6 @@ private Map getVersionsMap(Class sourceClass, Environment env return versions; } - /** - * Returns the application version. - * @param sourceClass the source class - * @return the application version or {@code null} if unknown - * @deprecated since 3.4.0 for removal in 4.0.0 - */ - @Deprecated(since = "3.4.0", forRemoval = true) - protected String getApplicationVersion(Class sourceClass) { - return null; - } - private String getApplicationVersion(Environment environment) { return environment.getProperty("spring.application.version"); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index 4fc7d16fd2e2..51ece877060c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -61,14 +61,11 @@ import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; import org.springframework.boot.convert.ApplicationConversionService; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigUtils; import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; import org.springframework.context.annotation.ConfigurationClassPostProcessor; @@ -384,7 +381,6 @@ private void prepareContext(DefaultBootstrapContext bootstrapContext, Configurab listeners.contextPrepared(context); bootstrapContext.close(context); if (this.properties.isLogStartupInfo()) { - logStartupInfo(context.getParent() == null); logStartupInfo(context); logStartupProfileInfo(context); } @@ -626,17 +622,6 @@ protected void logStartupInfo(ConfigurableApplicationContext context) { } } - /** - * Called to log startup information, subclasses may override to add additional - * logging. - * @param isRoot true if this application is the root of a context hierarchy - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #logStartupInfo(ConfigurableApplicationContext)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - protected void logStartupInfo(boolean isRoot) { - } - /** * Called to log active profile information. * @param context the application context @@ -1222,11 +1207,9 @@ public void setEnvironmentPrefix(String environmentPrefix) { /** * Sets the factory that will be called to create the application context. If not set, - * defaults to a factory that will create - * {@link AnnotationConfigServletWebServerApplicationContext} for servlet web - * applications, {@link AnnotationConfigReactiveWebServerApplicationContext} for - * reactive web applications, and {@link AnnotationConfigApplicationContext} for - * non-web applications. + * defaults to a factory that will create a context that is appropriate for the + * application's type (a reactive web application, a servlet web application, or a + * non-web application). * @param applicationContextFactory the factory for the context * @since 2.4.0 */ diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/admin/SpringApplicationAdminMXBeanRegistrar.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/admin/SpringApplicationAdminMXBeanRegistrar.java index 4b444239332b..4ddb68238d93 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/admin/SpringApplicationAdminMXBeanRegistrar.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/admin/SpringApplicationAdminMXBeanRegistrar.java @@ -29,7 +29,6 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEvent; @@ -38,6 +37,7 @@ import org.springframework.context.event.GenericApplicationListener; import org.springframework.core.Ordered; import org.springframework.core.ResolvableType; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.StandardEnvironment; import org.springframework.util.Assert; @@ -63,8 +63,6 @@ public class SpringApplicationAdminMXBeanRegistrar implements ApplicationContext private boolean ready; - private boolean embeddedWebApplication; - public SpringApplicationAdminMXBeanRegistrar(String name) throws MalformedObjectNameException { this.objectName = new ObjectName(name); } @@ -87,8 +85,7 @@ public boolean supportsEventType(ResolvableType eventType) { if (type == null) { return false; } - return ApplicationReadyEvent.class.isAssignableFrom(type) - || WebServerInitializedEvent.class.isAssignableFrom(type); + return ApplicationReadyEvent.class.isAssignableFrom(type); } @Override @@ -101,9 +98,6 @@ public void onApplicationEvent(ApplicationEvent event) { if (event instanceof ApplicationReadyEvent readyEvent) { onApplicationReadyEvent(readyEvent); } - if (event instanceof WebServerInitializedEvent initializedEvent) { - onWebServerInitializedEvent(initializedEvent); - } } @Override @@ -117,12 +111,6 @@ void onApplicationReadyEvent(ApplicationReadyEvent event) { } } - void onWebServerInitializedEvent(WebServerInitializedEvent event) { - if (this.applicationContext.equals(event.getApplicationContext())) { - this.embeddedWebApplication = true; - } - } - @Override public void afterPropertiesSet() throws Exception { MBeanServer server = ManagementFactory.getPlatformMBeanServer(); @@ -146,7 +134,8 @@ public boolean isReady() { @Override public boolean isEmbeddedWebApplication() { - return SpringApplicationAdminMXBeanRegistrar.this.embeddedWebApplication; + return SpringApplicationAdminMXBeanRegistrar.this.environment instanceof ConfigurableEnvironment configurableEnvironment + && configurableEnvironment.getPropertySources().get("server.ports") != null; } @Override diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java index fd7f2ed1abf0..6fdebddfd5bc 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java @@ -73,9 +73,8 @@ public abstract class Configurations { */ protected Configurations(Collection> classes) { Assert.notNull(classes, "'classes' must not be null"); - Collection> sorted = sort(classes); this.sorter = null; - this.classes = Collections.unmodifiableSet(new LinkedHashSet<>(sorted)); + this.classes = Collections.unmodifiableSet(new LinkedHashSet<>(classes)); this.beanNameGenerator = null; } @@ -99,18 +98,6 @@ protected final Set> getClasses() { return this.classes; } - /** - * Sort configuration classes into the order that they should be applied. - * @param classes the classes to sort - * @return a sorted set of classes - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link #Configurations(UnaryOperator, Collection, Function)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - protected Collection> sort(Collection> classes) { - return classes; - } - /** * Merge configurations from another source of the same type. * @param other the other {@link Configurations} (must be of the same type as this diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/io/ApplicationResourceLoader.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/io/ApplicationResourceLoader.java index bc4b93f1508a..d553464e617e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/io/ApplicationResourceLoader.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/io/ApplicationResourceLoader.java @@ -50,29 +50,6 @@ */ public class ApplicationResourceLoader extends DefaultResourceLoader { - /** - * Create a new {@code ApplicationResourceLoader}. - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #get()} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public ApplicationResourceLoader() { - this(null); - } - - /** - * Create a new {@code ApplicationResourceLoader}. - * @param classLoader the {@link ClassLoader} to load class path resources with, or - * {@code null} for using the thread context class loader at the time of actual - * resource access - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of {@link #get(ClassLoader)} - */ - @Deprecated(since = "3.4.0", forRemoval = true) - public ApplicationResourceLoader(ClassLoader classLoader) { - super(classLoader); - SpringFactoriesLoader loader = SpringFactoriesLoader.forDefaultResourceLocation(classLoader); - getProtocolResolvers().addAll(loader.load(ProtocolResolver.class)); - } - @Override protected Resource getResourceByPath(String path) { return new ApplicationResource(path); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystemProperties.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystemProperties.java index 19ef6ef3e1c4..6c96c2ae620e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystemProperties.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystemProperties.java @@ -122,14 +122,11 @@ private PropertyResolver getPropertyResolver() { } protected void apply(LogFile logFile, PropertyResolver resolver) { - Charset defaultCharset = getDefaultCharset(); - Charset consoleCharset = (defaultCharset != null) ? defaultCharset : getDefaultConsoleCharset(); - Charset fileCharset = (defaultCharset != null) ? defaultCharset : getDefaultFileCharset(); setSystemProperty(LoggingSystemProperty.APPLICATION_NAME, resolver); setSystemProperty(LoggingSystemProperty.APPLICATION_GROUP, resolver); setSystemProperty(LoggingSystemProperty.PID, new ApplicationPid().toString()); - setSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET, resolver, consoleCharset.name()); - setSystemProperty(LoggingSystemProperty.FILE_CHARSET, resolver, fileCharset.name()); + setSystemProperty(LoggingSystemProperty.CONSOLE_CHARSET, resolver, getDefaultConsoleCharset().name()); + setSystemProperty(LoggingSystemProperty.FILE_CHARSET, resolver, getDefaultFileCharset().name()); setSystemProperty(LoggingSystemProperty.CONSOLE_THRESHOLD, resolver, this::thresholdMapper); setSystemProperty(LoggingSystemProperty.FILE_THRESHOLD, resolver, this::thresholdMapper); setSystemProperty(LoggingSystemProperty.EXCEPTION_CONVERSION_WORD, resolver); @@ -145,17 +142,6 @@ protected void apply(LogFile logFile, PropertyResolver resolver) { } } - /** - * Returns the default charset. - * @return the default charset - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of - * {@link #getDefaultConsoleCharset()} and {@link #getDefaultFileCharset()}. - */ - @Deprecated(since = "3.5.0", forRemoval = true) - protected Charset getDefaultCharset() { - return null; - } - /** * Returns the default console charset. * @return the default console charset diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/ApplicationNameConverter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/ApplicationNameConverter.java deleted file mode 100644 index 83919caffdae..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/ApplicationNameConverter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.logging.logback; - -import ch.qos.logback.classic.pattern.ClassicConverter; -import ch.qos.logback.classic.pattern.PropertyConverter; -import ch.qos.logback.classic.spi.ILoggingEvent; - -import org.springframework.boot.logging.LoggingSystemProperty; - -/** - * Logback {@link ClassicConverter} to convert the - * {@link LoggingSystemProperty#APPLICATION_NAME APPLICATION_NAME} into a value suitable - * for logging. Similar to Logback's {@link PropertyConverter} but a non-existent property - * is logged as an empty string rather than {@code null}. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @since 3.2.4 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link EnclosedInSquareBracketsConverter} - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public class ApplicationNameConverter extends ClassicConverter { - - private static final String ENVIRONMENT_VARIABLE_NAME = LoggingSystemProperty.APPLICATION_NAME - .getEnvironmentVariableName(); - - @Override - public String convert(ILoggingEvent event) { - String applicationName = event.getLoggerContextVO().getPropertyMap().get(ENVIRONMENT_VARIABLE_NAME); - applicationName = (applicationName != null) ? applicationName : System.getProperty(ENVIRONMENT_VARIABLE_NAME); - return (applicationName != null) ? applicationName : ""; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java index b81004bd9347..076f4e0846c4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java @@ -98,7 +98,6 @@ void apply(LogbackConfigurator config) { } private void defaults(LogbackConfigurator config) { - deprecatedDefaults(config); config.conversionRule("clr", ColorConverter.class, ColorConverter::new); config.conversionRule("correlationId", CorrelationIdConverter.class, CorrelationIdConverter::new); config.conversionRule("esb", EnclosedInSquareBracketsConverter.class, EnclosedInSquareBracketsConverter::new); @@ -123,11 +122,6 @@ private void defaults(LogbackConfigurator config) { config.logger("org.springframework.boot.actuate.endpoint.jmx", Level.WARN); } - @SuppressWarnings("removal") - private void deprecatedDefaults(LogbackConfigurator config) { - config.conversionRule("applicationName", ApplicationNameConverter.class, ApplicationNameConverter::new); - } - void putProperty(LogbackConfigurator config, String name, String val) { config.getContext().putProperty(name, resolve(config, val)); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackRuntimeHints.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackRuntimeHints.java index 82e8b2da8457..be0e3293432b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackRuntimeHints.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackRuntimeHints.java @@ -44,7 +44,6 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) { registerHintsForLogbackLoggingSystemTypeChecks(reflection, classLoader); registerHintsForBuiltInLogbackConverters(reflection); registerHintsForSpringBootConverters(reflection); - registerHintsForDeprecateSpringBootConverters(reflection); } private void registerHintsForLogbackLoggingSystemTypeChecks(ReflectionHints reflection, ClassLoader classLoader) { @@ -64,11 +63,6 @@ private void registerHintsForSpringBootConverters(ReflectionHints reflection) { WhitespaceThrowableProxyConverter.class, CorrelationIdConverter.class); } - @SuppressWarnings("removal") - private void registerHintsForDeprecateSpringBootConverters(ReflectionHints reflection) { - registerForPublicConstructorInvocation(reflection, ApplicationNameConverter.class); - } - private void registerForPublicConstructorInvocation(ReflectionHints reflection, Class... classes) { reflection.registerTypes(TypeReference.listOf(classes), (hint) -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS)); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatter.java index d8c7849508bf..0bde5f83c248 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLogFormatter.java @@ -18,8 +18,6 @@ import java.nio.charset.Charset; -import ch.qos.logback.classic.pattern.ThrowableProxyConverter; - import org.springframework.boot.logging.StackTracePrinter; import org.springframework.core.env.Environment; @@ -36,7 +34,7 @@ * When using Logback, implementing classes can also use the following parameter types in * the constructor: *
      - *
    • {@link ThrowableProxyConverter}
    • + *
    • {@code ch.qos.logback.classic.pattern.ThrowableProxyConverter}
    • *
    * * @param the log event type diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonMembersCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonMembersCustomizer.java index 69c3bee1ee23..897a8d7b72be 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonMembersCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/structured/StructuredLoggingJsonMembersCustomizer.java @@ -16,8 +16,6 @@ package org.springframework.boot.logging.structured; -import ch.qos.logback.classic.pattern.ThrowableProxyConverter; - import org.springframework.boot.json.JsonWriter; import org.springframework.boot.json.JsonWriter.Members; import org.springframework.core.env.Environment; @@ -38,7 +36,7 @@ * When using Logback, implementing classes can also use the following parameter types in * the constructor: *
      - *
    • {@link ThrowableProxyConverter}
    • + *
    • {@code ch.qos.logback.classic.pattern.ThrowableProxyConverter}
    • *
    * * @param the type being written diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/package-info.java deleted file mode 100644 index 87ebfe88a51b..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/hibernate/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Hibernate Support classes. - */ -package org.springframework.boot.orm.jpa.hibernate; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/package-info.java deleted file mode 100644 index 46bf47a83373..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/orm/jpa/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * JPA Support classes. - */ -package org.springframework.boot.orm.jpa; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java deleted file mode 100644 index 28c91b56aad8..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.rsocket.netty; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import io.rsocket.SocketAcceptor; -import io.rsocket.transport.ServerTransport; -import io.rsocket.transport.netty.server.CloseableChannel; -import io.rsocket.transport.netty.server.TcpServerTransport; -import io.rsocket.transport.netty.server.WebsocketServerTransport; -import reactor.core.publisher.Mono; -import reactor.netty.http.server.HttpServer; -import reactor.netty.tcp.SslProvider.GenericSslContextSpec; -import reactor.netty.tcp.TcpServer; - -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.rsocket.server.ConfigurableRSocketServerFactory; -import org.springframework.boot.rsocket.server.RSocketServer; -import org.springframework.boot.rsocket.server.RSocketServerCustomizer; -import org.springframework.boot.rsocket.server.RSocketServerFactory; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.embedded.netty.SslServerCustomizer; -import org.springframework.boot.web.server.Ssl; -import org.springframework.boot.web.server.Ssl.ClientAuth; -import org.springframework.boot.web.server.Ssl.ServerNameSslBundle; -import org.springframework.boot.web.server.WebServerSslBundle; -import org.springframework.http.client.ReactorResourceFactory; -import org.springframework.util.Assert; -import org.springframework.util.unit.DataSize; - -/** - * {@link RSocketServerFactory} that can be used to create {@link RSocketServer}s backed - * by Netty. - * - * @author Brian Clozel - * @author Chris Bono - * @author Scott Frederick - * @since 2.2.0 - */ -public class NettyRSocketServerFactory implements RSocketServerFactory, ConfigurableRSocketServerFactory { - - private int port = 9898; - - private DataSize fragmentSize; - - private InetAddress address; - - private RSocketServer.Transport transport = RSocketServer.Transport.TCP; - - private ReactorResourceFactory resourceFactory; - - private Duration lifecycleTimeout; - - private List rSocketServerCustomizers = new ArrayList<>(); - - private Ssl ssl; - - private SslBundles sslBundles; - - @Override - public void setPort(int port) { - this.port = port; - } - - @Override - public void setFragmentSize(DataSize fragmentSize) { - this.fragmentSize = fragmentSize; - } - - @Override - public void setAddress(InetAddress address) { - this.address = address; - } - - @Override - public void setTransport(RSocketServer.Transport transport) { - this.transport = transport; - } - - @Override - public void setSsl(Ssl ssl) { - this.ssl = ssl; - } - - @Override - public void setSslBundles(SslBundles sslBundles) { - this.sslBundles = sslBundles; - } - - /** - * Set the {@link ReactorResourceFactory} to get the shared resources from. - * @param resourceFactory the server resources - */ - public void setResourceFactory(ReactorResourceFactory resourceFactory) { - this.resourceFactory = resourceFactory; - } - - /** - * Set {@link RSocketServerCustomizer}s that should be called to configure the - * {@link io.rsocket.core.RSocketServer} while building the server. Calling this - * method will replace any existing customizers. - * @param rSocketServerCustomizers customizers to apply before the server starts - * @since 2.2.7 - */ - public void setRSocketServerCustomizers(Collection rSocketServerCustomizers) { - Assert.notNull(rSocketServerCustomizers, "'rSocketServerCustomizers' must not be null"); - this.rSocketServerCustomizers = new ArrayList<>(rSocketServerCustomizers); - } - - /** - * Add {@link RSocketServerCustomizer}s that should be called to configure the - * {@link io.rsocket.core.RSocketServer}. - * @param rSocketServerCustomizers customizers to apply before the server starts - * @since 2.2.7 - */ - public void addRSocketServerCustomizers(RSocketServerCustomizer... rSocketServerCustomizers) { - Assert.notNull(rSocketServerCustomizers, "'rSocketServerCustomizers' must not be null"); - this.rSocketServerCustomizers.addAll(Arrays.asList(rSocketServerCustomizers)); - } - - /** - * Set the maximum amount of time that should be waited when starting or stopping the - * server. - * @param lifecycleTimeout the lifecycle timeout - */ - public void setLifecycleTimeout(Duration lifecycleTimeout) { - this.lifecycleTimeout = lifecycleTimeout; - } - - @Override - public NettyRSocketServer create(SocketAcceptor socketAcceptor) { - ServerTransport transport = createTransport(); - io.rsocket.core.RSocketServer server = io.rsocket.core.RSocketServer.create(socketAcceptor); - configureServer(server); - Mono starter = server.bind(transport); - return new NettyRSocketServer(starter, this.lifecycleTimeout); - } - - private void configureServer(io.rsocket.core.RSocketServer server) { - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(this.fragmentSize).asInt(DataSize::toBytes).to(server::fragment); - this.rSocketServerCustomizers.forEach((customizer) -> customizer.customize(server)); - } - - private ServerTransport createTransport() { - if (this.transport == RSocketServer.Transport.WEBSOCKET) { - return createWebSocketTransport(); - } - return createTcpTransport(); - } - - private ServerTransport createWebSocketTransport() { - HttpServer httpServer = HttpServer.create(); - if (this.resourceFactory != null) { - httpServer = httpServer.runOn(this.resourceFactory.getLoopResources()); - } - if (Ssl.isEnabled(this.ssl)) { - httpServer = customizeSslConfiguration(httpServer); - } - return WebsocketServerTransport.create(httpServer.bindAddress(this::getListenAddress)); - } - - private HttpServer customizeSslConfiguration(HttpServer httpServer) { - return new SslServerCustomizer(null, this.ssl.getClientAuth(), getSslBundle(), getServerNameSslBundles()) - .apply(httpServer); - } - - private ServerTransport createTcpTransport() { - TcpServer tcpServer = TcpServer.create(); - if (this.resourceFactory != null) { - tcpServer = tcpServer.runOn(this.resourceFactory.getLoopResources()); - } - if (Ssl.isEnabled(this.ssl)) { - tcpServer = new TcpSslServerCustomizer(this.ssl.getClientAuth(), getSslBundle(), getServerNameSslBundles()) - .apply(tcpServer); - } - return TcpServerTransport.create(tcpServer.bindAddress(this::getListenAddress)); - } - - private SslBundle getSslBundle() { - return WebServerSslBundle.get(this.ssl, this.sslBundles); - } - - protected final Map getServerNameSslBundles() { - return this.ssl.getServerNameBundles() - .stream() - .collect(Collectors.toMap(Ssl.ServerNameSslBundle::serverName, this::getBundle)); - } - - private SslBundle getBundle(ServerNameSslBundle serverNameSslBundle) { - return this.sslBundles.getBundle(serverNameSslBundle.bundle()); - } - - private InetSocketAddress getListenAddress() { - if (this.address != null) { - return new InetSocketAddress(this.address.getHostAddress(), this.port); - } - return new InetSocketAddress(this.port); - } - - private static final class TcpSslServerCustomizer - extends org.springframework.boot.web.embedded.netty.SslServerCustomizer { - - private final SslBundle sslBundle; - - private TcpSslServerCustomizer(ClientAuth clientAuth, SslBundle sslBundle, - Map serverNameSslBundles) { - super(null, clientAuth, sslBundle, serverNameSslBundles); - this.sslBundle = sslBundle; - } - - private TcpServer apply(TcpServer server) { - GenericSslContextSpec sslContextSpec = createSslContextSpec(this.sslBundle); - return server.secure((spec) -> spec.sslContext(sslContextSpec)); - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/package-info.java deleted file mode 100644 index c52efdbd62a6..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/security/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Classes and utilities for Spring Security. - */ -package org.springframework.boot.security; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/task/ThreadPoolTaskSchedulerBuilder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/task/ThreadPoolTaskSchedulerBuilder.java index 8b7852ba7985..91cd78d186eb 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/task/ThreadPoolTaskSchedulerBuilder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/task/ThreadPoolTaskSchedulerBuilder.java @@ -57,25 +57,6 @@ public ThreadPoolTaskSchedulerBuilder() { this(null, null, null, null, null, null); } - /** - * Constructs a new {@code ThreadPoolTaskSchedulerBuilder} instance with the specified - * configuration. - * @param poolSize the maximum allowed number of threads - * @param awaitTermination whether the executor should wait for scheduled tasks to - * complete on shutdown - * @param awaitTerminationPeriod the maximum time the executor is supposed to block on - * shutdown - * @param threadNamePrefix the prefix to use for the names of newly created threads - * @param taskSchedulerCustomizers the customizers to apply to the - * {@link ThreadPoolTaskScheduler} - * @deprecated since 3.5.0 for removal in 4.0.0 in favor of the default constructor - */ - @Deprecated(since = "3.5.0", forRemoval = true) - public ThreadPoolTaskSchedulerBuilder(Integer poolSize, Boolean awaitTermination, Duration awaitTerminationPeriod, - String threadNamePrefix, Set taskSchedulerCustomizers) { - this(poolSize, awaitTermination, awaitTerminationPeriod, threadNamePrefix, null, taskSchedulerCustomizers); - } - private ThreadPoolTaskSchedulerBuilder(Integer poolSize, Boolean awaitTermination, Duration awaitTerminationPeriod, String threadNamePrefix, TaskDecorator taskDecorator, Set taskSchedulerCustomizers) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactories.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactories.java deleted file mode 100644 index 5d9ce9882374..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactories.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import java.util.function.Supplier; - -import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; -import org.springframework.boot.http.client.JdkClientHttpRequestFactoryBuilder; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.http.client.JdkClientHttpRequestFactory; -import org.springframework.http.client.JettyClientHttpRequestFactory; -import org.springframework.http.client.ReactorClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Utility class that can be used to create {@link ClientHttpRequestFactory} instances - * configured using given {@link ClientHttpRequestFactorySettings}. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @author Scott Frederick - * @since 3.0.0 - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link ClientHttpRequestFactoryBuilder} - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public final class ClientHttpRequestFactories { - - private ClientHttpRequestFactories() { - } - - /** - * Return a {@link ClientHttpRequestFactory} implementation with the given - * {@code settings} applied. The first of the following implementations whose - * dependencies {@link ClassUtils#isPresent are available} is returned: - *
      - *
    1. {@link HttpComponentsClientHttpRequestFactory}
    2. - *
    3. {@link JettyClientHttpRequestFactory}
    4. - *
    5. {@link ReactorClientHttpRequestFactory}
    6. - *
    7. {@link SimpleClientHttpRequestFactory}
    8. - *
    - * @param settings the settings to apply - * @return a new {@link ClientHttpRequestFactory} - */ - @SuppressWarnings("removal") - public static ClientHttpRequestFactory get(ClientHttpRequestFactorySettings settings) { - Assert.notNull(settings, "'settings' must not be null"); - return detectBuilder().build(settings.adapt()); - } - - /** - * Return a new {@link ClientHttpRequestFactory} of the given - * {@code requestFactoryType}, applying {@link ClientHttpRequestFactorySettings} using - * reflection if necessary. The following implementations are supported without the - * use of reflection: - *
      - *
    • {@link HttpComponentsClientHttpRequestFactory}
    • - *
    • {@link JdkClientHttpRequestFactory}
    • - *
    • {@link JettyClientHttpRequestFactory}
    • - *
    • {@link ReactorClientHttpRequestFactory}
    • - *
    • {@link SimpleClientHttpRequestFactory}
    • - *
    - * A {@code requestFactoryType} of {@link ClientHttpRequestFactory} is equivalent to - * calling {@link #get(ClientHttpRequestFactorySettings)}. - * @param the {@link ClientHttpRequestFactory} type - * @param requestFactoryType the {@link ClientHttpRequestFactory} type - * @param settings the settings to apply - * @return a new {@link ClientHttpRequestFactory} instance - */ - @SuppressWarnings("removal") - public static T get(Class requestFactoryType, - ClientHttpRequestFactorySettings settings) { - Assert.notNull(settings, "'settings' must not be null"); - return getBuilder(requestFactoryType).build(settings.adapt()); - } - - /** - * Return a new {@link ClientHttpRequestFactory} from the given supplier, applying - * {@link ClientHttpRequestFactorySettings} using reflection. - * @param the {@link ClientHttpRequestFactory} type - * @param requestFactorySupplier the {@link ClientHttpRequestFactory} supplier - * @param settings the settings to apply - * @return a new {@link ClientHttpRequestFactory} instance - */ - @SuppressWarnings("removal") - public static T get(Supplier requestFactorySupplier, - ClientHttpRequestFactorySettings settings) { - return ClientHttpRequestFactoryBuilder.of(requestFactorySupplier).build(settings.adapt()); - } - - @SuppressWarnings("unchecked") - private static ClientHttpRequestFactoryBuilder getBuilder( - Class requestFactoryType) { - if (requestFactoryType == ClientHttpRequestFactory.class) { - return (ClientHttpRequestFactoryBuilder) detectBuilder(); - } - return ClientHttpRequestFactoryBuilder.of(requestFactoryType); - } - - private static ClientHttpRequestFactoryBuilder detectBuilder() { - ClientHttpRequestFactoryBuilder builder = ClientHttpRequestFactoryBuilder.detect(); - if (builder instanceof JdkClientHttpRequestFactoryBuilder) { - // Same logic as earlier versions which did not support JDK client factories - return ClientHttpRequestFactoryBuilder.simple(); - } - return builder; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettings.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettings.java deleted file mode 100644 index 7eb823680fa8..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettings.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import java.time.Duration; - -import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.http.client.ClientHttpRequestFactory; - -/** - * Settings that can be applied when creating a {@link ClientHttpRequestFactory}. - * - * @param connectTimeout the connect timeout - * @param readTimeout the read timeout - * @param sslBundle the SSL bundle providing SSL configuration - * @author Andy Wilkinson - * @author Phillip Webb - * @author Scott Frederick - * @since 3.0.0 - * @see ClientHttpRequestFactoryBuilder - * @deprecated since 3.4.0 for removal in 4.0.0 in favor of - * {@link org.springframework.boot.http.client.ClientHttpRequestFactorySettings} - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public record ClientHttpRequestFactorySettings(Duration connectTimeout, Duration readTimeout, SslBundle sslBundle) { - - /** - * Use defaults for the {@link ClientHttpRequestFactory} which can differ depending on - * the implementation. - */ - public static final ClientHttpRequestFactorySettings DEFAULTS = new ClientHttpRequestFactorySettings(null, null, - null); - - /** - * Return a new {@link ClientHttpRequestFactorySettings} instance with an updated - * connect timeout setting. - * @param connectTimeout the new connect timeout setting - * @return a new {@link ClientHttpRequestFactorySettings} instance - */ - public ClientHttpRequestFactorySettings withConnectTimeout(Duration connectTimeout) { - return new ClientHttpRequestFactorySettings(connectTimeout, this.readTimeout, this.sslBundle); - } - - /** - * Return a new {@link ClientHttpRequestFactorySettings} instance with an updated read - * timeout setting. - * @param readTimeout the new read timeout setting - * @return a new {@link ClientHttpRequestFactorySettings} instance - */ - - public ClientHttpRequestFactorySettings withReadTimeout(Duration readTimeout) { - return new ClientHttpRequestFactorySettings(this.connectTimeout, readTimeout, this.sslBundle); - } - - /** - * Return a new {@link ClientHttpRequestFactorySettings} instance with an updated SSL - * bundle setting. - * @param sslBundle the new SSL bundle setting - * @return a new {@link ClientHttpRequestFactorySettings} instance - * @since 3.1.0 - */ - public ClientHttpRequestFactorySettings withSslBundle(SslBundle sslBundle) { - return new ClientHttpRequestFactorySettings(this.connectTimeout, this.readTimeout, sslBundle); - } - - org.springframework.boot.http.client.ClientHttpRequestFactorySettings adapt() { - return new org.springframework.boot.http.client.ClientHttpRequestFactorySettings(null, connectTimeout(), - readTimeout(), sslBundle()); - } - - static ClientHttpRequestFactorySettings of( - org.springframework.boot.http.client.ClientHttpRequestFactorySettings settings) { - return new ClientHttpRequestFactorySettings(settings.connectTimeout(), settings.readTimeout(), - settings.sslBundle()); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/package-info.java deleted file mode 100644 index 211d76a3756f..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Web client utilities. - */ -package org.springframework.boot.web.client; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/codec/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/codec/package-info.java deleted file mode 100644 index ce303cf5dd2b..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/codec/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support for web-based codecs. - */ -package org.springframework.boot.web.codec; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/package-info.java deleted file mode 100644 index 36eafebcb01c..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Web integrations with Spring's {@link org.springframework.context.ApplicationContext - * ApplicationContext}. - */ -package org.springframework.boot.web.context; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/AnnotationConfigReactiveWebApplicationContext.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/AnnotationConfigReactiveWebApplicationContext.java index cab454b60f45..67fa8d88c69a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/AnnotationConfigReactiveWebApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ConfigurableReactiveWebApplicationContext.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebApplicationContext.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ConfigurableReactiveWebApplicationContext.java index efd5c84dbd60..c1c9c90a2002 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ConfigurableReactiveWebApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import org.springframework.context.ConfigurableApplicationContext; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebEnvironment.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ConfigurableReactiveWebEnvironment.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebEnvironment.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ConfigurableReactiveWebEnvironment.java index e5a89e224e40..4d4dd678f64c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebEnvironment.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ConfigurableReactiveWebEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import org.springframework.core.env.ConfigurableEnvironment; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResource.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResource.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResource.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResource.java index e82dfbacab69..0a7f56a2757b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResource.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResource.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import java.io.FileNotFoundException; import java.io.IOException; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResourceFilePathResolver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResourceFilePathResolver.java similarity index 95% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResourceFilePathResolver.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResourceFilePathResolver.java index 539e4c17195b..1da0ee7facaf 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResourceFilePathResolver.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResourceFilePathResolver.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import org.springframework.boot.io.ApplicationResourceLoader; import org.springframework.boot.io.ApplicationResourceLoader.FilePathResolver; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/GenericReactiveWebApplicationContext.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContext.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/GenericReactiveWebApplicationContext.java index ff1cf0a0753f..21573a803f4d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/GenericReactiveWebApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.support.GenericApplicationContext; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ReactiveWebApplicationContext.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebApplicationContext.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ReactiveWebApplicationContext.java index efa2c199d80d..4e6f907a4aae 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/ReactiveWebApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import org.springframework.context.ApplicationContext; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/StandardReactiveWebEnvironment.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/StandardReactiveWebEnvironment.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/StandardReactiveWebEnvironment.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/StandardReactiveWebEnvironment.java index 19491e91a43c..8a66bb2cf648 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/StandardReactiveWebEnvironment.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/StandardReactiveWebEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import org.springframework.core.env.Environment; import org.springframework.core.env.MutablePropertySources; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/package-info.java new file mode 100644 index 000000000000..8eec2af2e7ed --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/reactive/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Reactive based web integrations with Spring's + * {@link org.springframework.context.ApplicationContext ApplicationContext}. + */ +package org.springframework.boot.web.context.reactive; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/AnnotationConfigServletWebApplicationContext.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebApplicationContext.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/AnnotationConfigServletWebApplicationContext.java index 8eedaf9bcdba..46bf4260bf33 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/AnnotationConfigServletWebApplicationContext.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.context.servlet; import java.util.Arrays; import java.util.LinkedHashSet; @@ -40,7 +40,7 @@ import org.springframework.web.context.support.GenericWebApplicationContext; /** - * {@link GenericWebApplicationContext}that accepts annotated classes as input - in + * {@link GenericWebApplicationContext} that accepts annotated classes as input - in * particular {@link Configuration @Configuration}-annotated classes, but also plain * {@link Component @Component} classes and JSR-330 compliant classes using * {@code javax.inject} annotations. Allows for registering classes one by one (specifying diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ApplicationServletEnvironment.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/ApplicationServletEnvironment.java similarity index 90% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ApplicationServletEnvironment.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/ApplicationServletEnvironment.java index 7deceb20d8fd..5ed3fdbf4050 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ApplicationServletEnvironment.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/ApplicationServletEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.context.servlet; import org.springframework.boot.SpringApplication; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; @@ -27,8 +27,9 @@ * {@link SpringApplication}. * * @author Phillip Webb + * @since 4.0.0 */ -class ApplicationServletEnvironment extends StandardServletEnvironment { +public class ApplicationServletEnvironment extends StandardServletEnvironment { @Override protected String doGetActiveProfilesProperty() { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletContextResourceFilePathResolver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/ServletContextResourceFilePathResolver.java similarity index 96% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletContextResourceFilePathResolver.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/ServletContextResourceFilePathResolver.java index d4cf4c110a16..92e3222f859f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletContextResourceFilePathResolver.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/ServletContextResourceFilePathResolver.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.context.servlet; import org.springframework.boot.io.ApplicationResourceLoader; import org.springframework.boot.io.ApplicationResourceLoader.FilePathResolver; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/WebApplicationContextInitializer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/WebApplicationContextInitializer.java new file mode 100644 index 000000000000..d678c59f40d8 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/WebApplicationContextInitializer.java @@ -0,0 +1,94 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.context.servlet; + +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.web.servlet.ServletContextInitializer; +import org.springframework.boot.web.servlet.ServletContextInitializerBeans; +import org.springframework.web.context.ConfigurableWebApplicationContext; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.ServletContextScope; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Common initialization logic for Servlet web applications. + * + * @author Andy Wilkinson + * @since 4.0.0 + */ +public class WebApplicationContextInitializer { + + private static final Log logger = LogFactory.getLog(WebApplicationContextInitializer.class); + + private final ConfigurableWebApplicationContext context; + + public WebApplicationContextInitializer(ConfigurableWebApplicationContext context) { + this.context = context; + } + + public void initialize(ServletContext servletContext) throws ServletException { + prepareWebApplicationContext(servletContext); + registerApplicationScope(servletContext, this.context.getBeanFactory()); + WebApplicationContextUtils.registerEnvironmentBeans(this.context.getBeanFactory(), servletContext); + for (ServletContextInitializer initializerBean : new ServletContextInitializerBeans( + this.context.getBeanFactory())) { + initializerBean.onStartup(servletContext); + } + } + + private void prepareWebApplicationContext(ServletContext servletContext) { + Object rootContext = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); + if (rootContext != null) { + if (rootContext == this) { + throw new IllegalStateException( + "Cannot initialize context because there is already a root application context present - " + + "check whether you have multiple ServletContextInitializers!"); + } + return; + } + try { + servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); + if (logger.isDebugEnabled()) { + logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]"); + } + this.context.setServletContext(servletContext); + if (logger.isInfoEnabled()) { + long elapsedTime = System.currentTimeMillis() - this.context.getStartupDate(); + logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms"); + } + } + catch (RuntimeException | Error ex) { + logger.error("Context initialization failed", ex); + servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); + throw ex; + } + } + + private void registerApplicationScope(ServletContext servletContext, ConfigurableListableBeanFactory beanFactory) { + ServletContextScope appScope = new ServletContextScope(servletContext); + beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); + // Register as ServletContext attribute, for ContextCleanupListener to detect it. + servletContext.setAttribute(ServletContextScope.class.getName(), appScope); + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/package-info.java new file mode 100644 index 000000000000..1b39a7716379 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/servlet/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Servlet based web integrations with Spring's + * {@link org.springframework.web.context.WebApplicationContext WebApplicationContext}. + */ +package org.springframework.boot.web.context.servlet; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/GracefulShutdown.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/GracefulShutdown.java deleted file mode 100644 index 0d535c6243f3..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/GracefulShutdown.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.jetty; - -import java.lang.reflect.Method; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.function.Supplier; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Server; - -import org.springframework.boot.web.server.GracefulShutdownCallback; -import org.springframework.boot.web.server.GracefulShutdownResult; -import org.springframework.util.ReflectionUtils; - -/** - * Handles Jetty graceful shutdown. - * - * @author Andy Wilkinson - * @author Onur Kagan Ozcan - */ -final class GracefulShutdown { - - private static final Log logger = LogFactory.getLog(GracefulShutdown.class); - - private final Server server; - - private final Supplier activeRequests; - - private volatile boolean aborted = false; - - GracefulShutdown(Server server, Supplier activeRequests) { - this.server = server; - this.activeRequests = activeRequests; - } - - void shutDownGracefully(GracefulShutdownCallback callback) { - logger.info("Commencing graceful shutdown. Waiting for active requests to complete"); - new Thread(() -> awaitShutdown(callback), "jetty-shutdown").start(); - boolean jetty10 = isJetty10(); - for (Connector connector : this.server.getConnectors()) { - shutdown(connector, !jetty10); - } - - } - - @SuppressWarnings("unchecked") - private void shutdown(Connector connector, boolean getResult) { - Future result; - try { - result = connector.shutdown(); - } - catch (NoSuchMethodError ex) { - Method shutdown = ReflectionUtils.findMethod(connector.getClass(), "shutdown"); - result = (Future) ReflectionUtils.invokeMethod(shutdown, connector); - } - if (getResult) { - try { - result.get(); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - catch (ExecutionException ex) { - // Continue - } - } - } - - private boolean isJetty10() { - try { - return CompletableFuture.class.equals(Connector.class.getMethod("shutdown").getReturnType()); - } - catch (Exception ex) { - return false; - } - } - - private void awaitShutdown(GracefulShutdownCallback callback) { - while (!this.aborted && this.activeRequests.get() > 0) { - sleep(100); - } - if (this.aborted) { - logger.info("Graceful shutdown aborted with one or more requests still active"); - callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE); - } - else { - logger.info("Graceful shutdown complete"); - callback.shutdownComplete(GracefulShutdownResult.IDLE); - } - } - - private void sleep(long millis) { - try { - Thread.sleep(millis); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - - void abort() { - this.aborted = true; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java deleted file mode 100644 index 6f0862a2ea6e..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.jetty; - -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.ServletHolder; -import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; -import org.eclipse.jetty.server.AbstractConnector; -import org.eclipse.jetty.server.ConnectionFactory; -import org.eclipse.jetty.server.ConnectionLimit; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.handler.StatisticsHandler; -import org.eclipse.jetty.util.thread.ThreadPool; - -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.server.Shutdown; -import org.springframework.boot.web.server.Ssl; -import org.springframework.boot.web.server.WebServer; -import org.springframework.http.client.reactive.JettyResourceFactory; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * {@link ReactiveWebServerFactory} that can be used to create {@link JettyWebServer}s. - * - * @author Brian Clozel - * @author Moritz Halbritter - * @since 2.0.0 - */ -public class JettyReactiveWebServerFactory extends AbstractReactiveWebServerFactory - implements ConfigurableJettyWebServerFactory { - - private static final Log logger = LogFactory.getLog(JettyReactiveWebServerFactory.class); - - /** - * The number of acceptor threads to use. - */ - private int acceptors = -1; - - /** - * The number of selector threads to use. - */ - private int selectors = -1; - - private boolean useForwardHeaders; - - private Set jettyServerCustomizers = new LinkedHashSet<>(); - - private JettyResourceFactory resourceFactory; - - private ThreadPool threadPool; - - private int maxConnections = -1; - - /** - * Create a new {@link JettyServletWebServerFactory} instance. - */ - public JettyReactiveWebServerFactory() { - } - - /** - * Create a new {@link JettyServletWebServerFactory} that listens for requests using - * the specified port. - * @param port the port to listen on - */ - public JettyReactiveWebServerFactory(int port) { - super(port); - } - - @Override - public void setUseForwardHeaders(boolean useForwardHeaders) { - this.useForwardHeaders = useForwardHeaders; - } - - @Override - public void setAcceptors(int acceptors) { - this.acceptors = acceptors; - } - - @Override - public WebServer getWebServer(HttpHandler httpHandler) { - ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler); - Server server = createJettyServer(servlet); - return new JettyWebServer(server, getPort() >= 0); - } - - @Override - public void addServerCustomizers(JettyServerCustomizer... customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.jettyServerCustomizers.addAll(Arrays.asList(customizers)); - } - - @Override - public void setMaxConnections(int maxConnections) { - this.maxConnections = maxConnections; - } - - /** - * Sets {@link JettyServerCustomizer}s that will be applied to the {@link Server} - * before it is started. Calling this method will replace any existing customizers. - * @param customizers the Jetty customizers to apply - */ - public void setServerCustomizers(Collection customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.jettyServerCustomizers = new LinkedHashSet<>(customizers); - } - - /** - * Returns a mutable collection of Jetty {@link JettyServerCustomizer}s that will be - * applied to the {@link Server} before it is created. - * @return the Jetty customizers - */ - public Collection getServerCustomizers() { - return this.jettyServerCustomizers; - } - - /** - * Returns a Jetty {@link ThreadPool} that should be used by the {@link Server}. - * @return a Jetty {@link ThreadPool} or {@code null} - */ - public ThreadPool getThreadPool() { - return this.threadPool; - } - - @Override - public void setThreadPool(ThreadPool threadPool) { - this.threadPool = threadPool; - } - - @Override - public void setSelectors(int selectors) { - this.selectors = selectors; - } - - /** - * Set the {@link JettyResourceFactory} to get the shared resources from. - * @param resourceFactory the server resources - * @since 2.1.0 - */ - public void setResourceFactory(JettyResourceFactory resourceFactory) { - this.resourceFactory = resourceFactory; - } - - protected JettyResourceFactory getResourceFactory() { - return this.resourceFactory; - } - - protected Server createJettyServer(ServletHttpHandlerAdapter servlet) { - int port = Math.max(getPort(), 0); - InetSocketAddress address = new InetSocketAddress(getAddress(), port); - Server server = new Server(getThreadPool()); - server.addConnector(createConnector(address, server)); - server.setStopTimeout(0); - ServletHolder servletHolder = new ServletHolder(servlet); - servletHolder.setAsyncSupported(true); - ServletContextHandler contextHandler = new ServletContextHandler("/", false, false); - contextHandler.addServlet(servletHolder, "/"); - server.setHandler(addHandlerWrappers(contextHandler)); - JettyReactiveWebServerFactory.logger.info("Server initialized with port: " + port); - if (this.maxConnections > -1) { - server.addBean(new ConnectionLimit(this.maxConnections, server)); - } - if (Ssl.isEnabled(getSsl())) { - customizeSsl(server, address); - } - for (JettyServerCustomizer customizer : getServerCustomizers()) { - customizer.customize(server); - } - if (this.useForwardHeaders) { - new ForwardHeadersCustomizer().customize(server); - } - if (getShutdown() == Shutdown.GRACEFUL) { - StatisticsHandler statisticsHandler = new StatisticsHandler(); - statisticsHandler.setHandler(server.getHandler()); - server.setHandler(statisticsHandler); - } - server.setAttribute(org.springframework.boot.web.server.WebServerFactory.class.getName(), getClass()); - return server; - } - - private AbstractConnector createConnector(InetSocketAddress address, Server server) { - HttpConfiguration httpConfiguration = new HttpConfiguration(); - httpConfiguration.setSendServerVersion(false); - List connectionFactories = new ArrayList<>(); - connectionFactories.add(new HttpConnectionFactory(httpConfiguration)); - if (getHttp2() != null && getHttp2().isEnabled()) { - connectionFactories.add(new HTTP2CServerConnectionFactory(httpConfiguration)); - } - JettyResourceFactory resourceFactory = getResourceFactory(); - ServerConnector connector; - if (resourceFactory != null) { - connector = new ServerConnector(server, resourceFactory.getExecutor(), resourceFactory.getScheduler(), - resourceFactory.getByteBufferPool(), this.acceptors, this.selectors, - connectionFactories.toArray(new ConnectionFactory[0])); - } - else { - connector = new ServerConnector(server, this.acceptors, this.selectors, - connectionFactories.toArray(new ConnectionFactory[0])); - } - connector.setHost(address.getHostString()); - connector.setPort(address.getPort()); - return connector; - } - - private Handler addHandlerWrappers(Handler handler) { - if (getCompression() != null && getCompression().getEnabled()) { - handler = applyWrapper(handler, JettyHandlerWrappers.createGzipHandlerWrapper(getCompression())); - } - if (StringUtils.hasText(getServerHeader())) { - handler = applyWrapper(handler, JettyHandlerWrappers.createServerHeaderHandlerWrapper(getServerHeader())); - } - return handler; - } - - private Handler applyWrapper(Handler handler, Handler.Wrapper wrapper) { - wrapper.setHandler(handler); - return wrapper; - } - - private void customizeSsl(Server server, InetSocketAddress address) { - Assert.state(getSsl().getServerNameBundles().isEmpty(), "Server name SSL bundles are not supported with Jetty"); - new SslServerCustomizer(getHttp2(), address, getSsl().getClientAuth(), getSslBundle()).customize(server); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java deleted file mode 100644 index 30dcff93bcd1..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.jetty; - -import java.io.File; -import java.net.InetSocketAddress; -import java.net.URL; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.EventListener; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; - -import jakarta.servlet.http.Cookie; -import org.eclipse.jetty.ee10.servlet.ErrorHandler; -import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler; -import org.eclipse.jetty.ee10.servlet.ListenerHolder; -import org.eclipse.jetty.ee10.servlet.ServletHandler; -import org.eclipse.jetty.ee10.servlet.ServletHolder; -import org.eclipse.jetty.ee10.servlet.ServletMapping; -import org.eclipse.jetty.ee10.servlet.SessionHandler; -import org.eclipse.jetty.ee10.servlet.Source; -import org.eclipse.jetty.ee10.webapp.AbstractConfiguration; -import org.eclipse.jetty.ee10.webapp.Configuration; -import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.eclipse.jetty.ee10.webapp.WebInfConfiguration; -import org.eclipse.jetty.http.CookieCompliance; -import org.eclipse.jetty.http.HttpCookie; -import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.http.HttpFields.Mutable; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.MimeTypes; -import org.eclipse.jetty.http.MimeTypes.Wrapper; -import org.eclipse.jetty.http.SetCookieParser; -import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; -import org.eclipse.jetty.server.AbstractConnector; -import org.eclipse.jetty.server.ConnectionFactory; -import org.eclipse.jetty.server.ConnectionLimit; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.HttpCookieUtils; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.handler.StatisticsHandler; -import org.eclipse.jetty.session.DefaultSessionCache; -import org.eclipse.jetty.session.FileSessionDataStore; -import org.eclipse.jetty.session.SessionConfig; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.resource.ResourceFactory; -import org.eclipse.jetty.util.resource.URLResourceFactory; -import org.eclipse.jetty.util.thread.ThreadPool; - -import org.springframework.boot.web.server.Cookie.SameSite; -import org.springframework.boot.web.server.ErrorPage; -import org.springframework.boot.web.server.MimeMappings; -import org.springframework.boot.web.server.Shutdown; -import org.springframework.boot.web.server.Ssl; -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; -import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.ResourceLoader; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - -/** - * {@link ServletWebServerFactory} that can be used to create a {@link JettyWebServer}. - * Can be initialized using Spring's {@link ServletContextInitializer}s or Jetty - * {@link Configuration}s. - *

    - * Unless explicitly configured otherwise this factory will create servers that listen for - * HTTP requests on port 8080. - * - * @author Phillip Webb - * @author Dave Syer - * @author Andrey Hihlovskiy - * @author Andy Wilkinson - * @author Eddú Meléndez - * @author Venil Noronha - * @author Henri Kerola - * @author Moritz Halbritter - * @author Onur Kagan Ozcan - * @since 2.0.0 - * @see #setPort(int) - * @see #setConfigurations(Collection) - * @see JettyWebServer - */ -public class JettyServletWebServerFactory extends AbstractServletWebServerFactory - implements ConfigurableJettyWebServerFactory, ResourceLoaderAware { - - private List configurations = new ArrayList<>(); - - private boolean useForwardHeaders; - - /** - * The number of acceptor threads to use. - */ - private int acceptors = -1; - - /** - * The number of selector threads to use. - */ - private int selectors = -1; - - private Set jettyServerCustomizers = new LinkedHashSet<>(); - - private ResourceLoader resourceLoader; - - private ThreadPool threadPool; - - private int maxConnections = -1; - - /** - * Create a new {@link JettyServletWebServerFactory} instance. - */ - public JettyServletWebServerFactory() { - } - - /** - * Create a new {@link JettyServletWebServerFactory} that listens for requests using - * the specified port. - * @param port the port to listen on - */ - public JettyServletWebServerFactory(int port) { - super(port); - } - - /** - * Create a new {@link JettyServletWebServerFactory} with the specified context path - * and port. - * @param contextPath the root context path - * @param port the port to listen on - */ - public JettyServletWebServerFactory(String contextPath, int port) { - super(contextPath, port); - } - - @Override - public WebServer getWebServer(ServletContextInitializer... initializers) { - JettyEmbeddedWebAppContext context = new JettyEmbeddedWebAppContext(); - context.getContext().getServletContext().setExtendedListenerTypes(true); - int port = Math.max(getPort(), 0); - InetSocketAddress address = new InetSocketAddress(getAddress(), port); - Server server = createServer(address); - context.setServer(server); - configureWebAppContext(context, initializers); - server.setHandler(addHandlerWrappers(context)); - this.logger.info("Server initialized with port: " + port); - if (this.maxConnections > -1) { - server.addBean(new ConnectionLimit(this.maxConnections, server.getConnectors())); - } - if (Ssl.isEnabled(getSsl())) { - customizeSsl(server, address); - } - for (JettyServerCustomizer customizer : getServerCustomizers()) { - customizer.customize(server); - } - if (this.useForwardHeaders) { - new ForwardHeadersCustomizer().customize(server); - } - if (getShutdown() == Shutdown.GRACEFUL) { - StatisticsHandler statisticsHandler = new StatisticsHandler(); - statisticsHandler.setHandler(server.getHandler()); - server.setHandler(statisticsHandler); - } - return getJettyWebServer(server); - } - - private Server createServer(InetSocketAddress address) { - Server server = new Server(getThreadPool()); - server.setConnectors(new Connector[] { createConnector(address, server) }); - server.setStopTimeout(0); - MimeTypes.Mutable mimeTypes = server.getMimeTypes(); - for (MimeMappings.Mapping mapping : getMimeMappings()) { - mimeTypes.addMimeMapping(mapping.getExtension(), mapping.getMimeType()); - } - return server; - } - - private AbstractConnector createConnector(InetSocketAddress address, Server server) { - HttpConfiguration httpConfiguration = new HttpConfiguration(); - httpConfiguration.setSendServerVersion(false); - List connectionFactories = new ArrayList<>(); - connectionFactories.add(new HttpConnectionFactory(httpConfiguration)); - if (getHttp2() != null && getHttp2().isEnabled()) { - connectionFactories.add(new HTTP2CServerConnectionFactory(httpConfiguration)); - } - ServerConnector connector = new ServerConnector(server, this.acceptors, this.selectors, - connectionFactories.toArray(new ConnectionFactory[0])); - connector.setHost(address.getHostString()); - connector.setPort(address.getPort()); - return connector; - } - - private Handler addHandlerWrappers(Handler handler) { - if (getCompression() != null && getCompression().getEnabled()) { - handler = applyWrapper(handler, JettyHandlerWrappers.createGzipHandlerWrapper(getCompression())); - } - if (StringUtils.hasText(getServerHeader())) { - handler = applyWrapper(handler, JettyHandlerWrappers.createServerHeaderHandlerWrapper(getServerHeader())); - } - if (!CollectionUtils.isEmpty(getCookieSameSiteSuppliers())) { - handler = applyWrapper(handler, - new SuppliedSameSiteCookieHandlerWrapper(getSessionCookieName(), getCookieSameSiteSuppliers())); - } - return handler; - } - - private String getSessionCookieName() { - String name = getSession().getCookie().getName(); - return (name != null) ? name : SessionConfig.__DefaultSessionCookie; - } - - private Handler applyWrapper(Handler handler, Handler.Wrapper wrapper) { - wrapper.setHandler(handler); - return wrapper; - } - - private void customizeSsl(Server server, InetSocketAddress address) { - Assert.state(getSsl().getServerNameBundles().isEmpty(), "Server name SSL bundles are not supported with Jetty"); - new SslServerCustomizer(getHttp2(), address, getSsl().getClientAuth(), getSslBundle()).customize(server); - } - - /** - * Configure the given Jetty {@link WebAppContext} for use. - * @param context the context to configure - * @param initializers the set of initializers to apply - */ - protected final void configureWebAppContext(WebAppContext context, ServletContextInitializer... initializers) { - Assert.notNull(context, "'context' must not be null"); - context.clearAliasChecks(); - if (this.resourceLoader != null) { - context.setClassLoader(this.resourceLoader.getClassLoader()); - } - String contextPath = getContextPath(); - context.setContextPath(StringUtils.hasLength(contextPath) ? contextPath : "/"); - context.setDisplayName(getDisplayName()); - configureDocumentRoot(context); - if (isRegisterDefaultServlet()) { - addDefaultServlet(context); - } - if (shouldRegisterJspServlet()) { - addJspServlet(context); - context.addBean(new JasperInitializer(context), true); - } - addLocaleMappings(context); - ServletContextInitializer[] initializersToUse = mergeInitializers(initializers); - Configuration[] configurations = getWebAppContextConfigurations(context, initializersToUse); - context.setConfigurations(configurations); - context.setThrowUnavailableOnStartupException(true); - configureSession(context); - context.setTempDirectory(getTempDirectory(context)); - postProcessWebAppContext(context); - } - - private void configureSession(WebAppContext context) { - SessionHandler handler = context.getSessionHandler(); - SameSite sessionSameSite = getSession().getCookie().getSameSite(); - if (sessionSameSite != null && sessionSameSite != SameSite.OMITTED) { - handler.setSameSite(HttpCookie.SameSite.valueOf(sessionSameSite.name())); - } - Duration sessionTimeout = getSession().getTimeout(); - handler.setMaxInactiveInterval(isNegative(sessionTimeout) ? -1 : (int) sessionTimeout.getSeconds()); - if (getSession().isPersistent()) { - DefaultSessionCache cache = new DefaultSessionCache(handler); - FileSessionDataStore store = new FileSessionDataStore(); - store.setStoreDir(getValidSessionStoreDir()); - cache.setSessionDataStore(store); - handler.setSessionCache(cache); - } - } - - private boolean isNegative(Duration sessionTimeout) { - return sessionTimeout == null || sessionTimeout.isNegative(); - } - - private void addLocaleMappings(WebAppContext context) { - getLocaleCharsetMappings() - .forEach((locale, charset) -> context.addLocaleEncoding(locale.toString(), charset.toString())); - } - - private File getTempDirectory(WebAppContext context) { - String temp = System.getProperty("java.io.tmpdir"); - return (temp != null) ? new File(temp, getTempDirectoryPrefix(context) + UUID.randomUUID()) : null; - } - - @SuppressWarnings("removal") - private String getTempDirectoryPrefix(WebAppContext context) { - try { - return ((JettyEmbeddedWebAppContext) context).getCanonicalNameForTmpDir(); - } - catch (Throwable ex) { - return WebInfConfiguration.getCanonicalNameForWebAppTmpDir(context); - } - } - - private void configureDocumentRoot(WebAppContext handler) { - File root = getValidDocumentRoot(); - File docBase = (root != null) ? root : createTempDir("jetty-docbase"); - try { - ResourceFactory resourceFactory = handler.getResourceFactory(); - List resources = new ArrayList<>(); - Resource rootResource = (docBase.isDirectory() - ? resourceFactory.newResource(docBase.getCanonicalFile().toURI()) - : resourceFactory.newJarFileResource(docBase.toURI())); - resources.add((root != null) ? new LoaderHidingResource(rootResource, rootResource) : rootResource); - URLResourceFactory urlResourceFactory = new URLResourceFactory(); - for (URL resourceJarUrl : getUrlsOfJarsWithMetaInfResources()) { - Resource resource = createResource(resourceJarUrl, resourceFactory, urlResourceFactory); - if (resource != null) { - resources.add(resource); - } - } - handler.setBaseResource(ResourceFactory.combine(resources)); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - } - - private Resource createResource(URL url, ResourceFactory resourceFactory, URLResourceFactory urlResourceFactory) - throws Exception { - if ("file".equals(url.getProtocol())) { - File file = new File(url.toURI()); - if (file.isFile()) { - return resourceFactory.newResource("jar:" + url + "!/META-INF/resources/"); - } - if (file.isDirectory()) { - return resourceFactory.newResource(url).resolve("META-INF/resources/"); - } - } - return urlResourceFactory.newResource(url + "META-INF/resources/"); - } - - /** - * Add Jetty's {@code DefaultServlet} to the given {@link WebAppContext}. - * @param context the jetty {@link WebAppContext} - */ - protected final void addDefaultServlet(WebAppContext context) { - Assert.notNull(context, "'context' must not be null"); - ServletHolder holder = new ServletHolder(); - holder.setName("default"); - holder.setClassName("org.eclipse.jetty.ee10.servlet.DefaultServlet"); - holder.setInitParameter("dirAllowed", "false"); - holder.setInitOrder(1); - context.getServletHandler().addServletWithMapping(holder, "/"); - ServletMapping servletMapping = context.getServletHandler().getServletMapping("/"); - servletMapping.setFromDefaultDescriptor(true); - } - - /** - * Add Jetty's {@code JspServlet} to the given {@link WebAppContext}. - * @param context the jetty {@link WebAppContext} - */ - protected final void addJspServlet(WebAppContext context) { - Assert.notNull(context, "'context' must not be null"); - ServletHolder holder = new ServletHolder(); - holder.setName("jsp"); - holder.setClassName(getJsp().getClassName()); - holder.setInitParameter("fork", "false"); - holder.setInitParameters(getJsp().getInitParameters()); - holder.setInitOrder(3); - context.getServletHandler().addServlet(holder); - ServletMapping mapping = new ServletMapping(); - mapping.setServletName("jsp"); - mapping.setPathSpecs(new String[] { "*.jsp", "*.jspx" }); - context.getServletHandler().addServletMapping(mapping); - } - - /** - * Return the Jetty {@link Configuration}s that should be applied to the server. - * @param webAppContext the Jetty {@link WebAppContext} - * @param initializers the {@link ServletContextInitializer}s to apply - * @return configurations to apply - */ - protected Configuration[] getWebAppContextConfigurations(WebAppContext webAppContext, - ServletContextInitializer... initializers) { - List configurations = new ArrayList<>(); - configurations.add(getServletContextInitializerConfiguration(webAppContext, initializers)); - configurations.add(getErrorPageConfiguration()); - configurations.add(getMimeTypeConfiguration()); - configurations.add(new WebListenersConfiguration(getWebListenerClassNames())); - configurations.addAll(getConfigurations()); - return configurations.toArray(new Configuration[0]); - } - - /** - * Create a configuration object that adds error handlers. - * @return a configuration object for adding error pages - */ - private Configuration getErrorPageConfiguration() { - return new AbstractConfiguration(new AbstractConfiguration.Builder()) { - - @Override - public void configure(WebAppContext context) throws Exception { - JettyEmbeddedErrorHandler errorHandler = new JettyEmbeddedErrorHandler(); - context.setErrorHandler(errorHandler); - addJettyErrorPages(errorHandler, getErrorPages()); - } - - }; - } - - /** - * Create a configuration object that adds mime type mappings. - * @return a configuration object for adding mime type mappings - */ - private Configuration getMimeTypeConfiguration() { - return new AbstractConfiguration(new AbstractConfiguration.Builder()) { - - @Override - public void configure(WebAppContext context) throws Exception { - MimeTypes.Wrapper mimeTypes = (Wrapper) context.getMimeTypes(); - mimeTypes.setWrapped(new MimeTypes(null)); - for (MimeMappings.Mapping mapping : getMimeMappings()) { - mimeTypes.addMimeMapping(mapping.getExtension(), mapping.getMimeType()); - } - } - - }; - } - - /** - * Return a Jetty {@link Configuration} that will invoke the specified - * {@link ServletContextInitializer}s. By default this method will return a - * {@link ServletContextInitializerConfiguration}. - * @param webAppContext the Jetty {@link WebAppContext} - * @param initializers the {@link ServletContextInitializer}s to apply - * @return the {@link Configuration} instance - */ - protected Configuration getServletContextInitializerConfiguration(WebAppContext webAppContext, - ServletContextInitializer... initializers) { - return new ServletContextInitializerConfiguration(initializers); - } - - /** - * Post process the Jetty {@link WebAppContext} before it's used with the Jetty - * Server. Subclasses can override this method to apply additional processing to the - * {@link WebAppContext}. - * @param webAppContext the Jetty {@link WebAppContext} - */ - protected void postProcessWebAppContext(WebAppContext webAppContext) { - } - - /** - * Factory method called to create the {@link JettyWebServer}. Subclasses can override - * this method to return a different {@link JettyWebServer} or apply additional - * processing to the Jetty server. - * @param server the Jetty server. - * @return a new {@link JettyWebServer} instance - */ - protected JettyWebServer getJettyWebServer(Server server) { - return new JettyWebServer(server, getPort() >= 0); - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - - @Override - public void setUseForwardHeaders(boolean useForwardHeaders) { - this.useForwardHeaders = useForwardHeaders; - } - - @Override - public void setAcceptors(int acceptors) { - this.acceptors = acceptors; - } - - @Override - public void setSelectors(int selectors) { - this.selectors = selectors; - } - - @Override - public void setMaxConnections(int maxConnections) { - this.maxConnections = maxConnections; - } - - /** - * Sets {@link JettyServerCustomizer}s that will be applied to the {@link Server} - * before it is started. Calling this method will replace any existing customizers. - * @param customizers the Jetty customizers to apply - */ - public void setServerCustomizers(Collection customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.jettyServerCustomizers = new LinkedHashSet<>(customizers); - } - - /** - * Returns a mutable collection of Jetty {@link JettyServerCustomizer}s that will be - * applied to the {@link Server} before it is created. - * @return the {@link JettyServerCustomizer}s - */ - public Collection getServerCustomizers() { - return this.jettyServerCustomizers; - } - - @Override - public void addServerCustomizers(JettyServerCustomizer... customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.jettyServerCustomizers.addAll(Arrays.asList(customizers)); - } - - /** - * Sets Jetty {@link Configuration}s that will be applied to the {@link WebAppContext} - * before the server is created. Calling this method will replace any existing - * configurations. - * @param configurations the Jetty configurations to apply - */ - public void setConfigurations(Collection configurations) { - Assert.notNull(configurations, "'configurations' must not be null"); - this.configurations = new ArrayList<>(configurations); - } - - /** - * Returns a mutable collection of Jetty {@link Configuration}s that will be applied - * to the {@link WebAppContext} before the server is created. - * @return the Jetty {@link Configuration}s - */ - public Collection getConfigurations() { - return this.configurations; - } - - /** - * Add {@link Configuration}s that will be applied to the {@link WebAppContext} before - * the server is started. - * @param configurations the configurations to add - */ - public void addConfigurations(Configuration... configurations) { - Assert.notNull(configurations, "'configurations' must not be null"); - this.configurations.addAll(Arrays.asList(configurations)); - } - - /** - * Returns a Jetty {@link ThreadPool} that should be used by the {@link Server}. - * @return a Jetty {@link ThreadPool} or {@code null} - */ - public ThreadPool getThreadPool() { - return this.threadPool; - } - - @Override - public void setThreadPool(ThreadPool threadPool) { - this.threadPool = threadPool; - } - - private void addJettyErrorPages(ErrorHandler errorHandler, Collection errorPages) { - if (errorHandler instanceof ErrorPageErrorHandler handler) { - for (ErrorPage errorPage : errorPages) { - if (errorPage.isGlobal()) { - handler.addErrorPage(ErrorPageErrorHandler.GLOBAL_ERROR_PAGE, errorPage.getPath()); - } - else { - if (errorPage.getExceptionName() != null) { - handler.addErrorPage(errorPage.getExceptionName(), errorPage.getPath()); - } - else { - handler.addErrorPage(errorPage.getStatusCode(), errorPage.getPath()); - } - } - } - } - } - - /** - * {@link AbstractConfiguration} to apply {@code @WebListener} classes. - */ - private static class WebListenersConfiguration extends AbstractConfiguration { - - private final Set classNames; - - WebListenersConfiguration(Set webListenerClassNames) { - super(new AbstractConfiguration.Builder()); - this.classNames = webListenerClassNames; - } - - @Override - public void configure(WebAppContext context) throws Exception { - ServletHandler servletHandler = context.getServletHandler(); - for (String className : this.classNames) { - configure(context, servletHandler, className); - } - } - - private void configure(WebAppContext context, ServletHandler servletHandler, String className) - throws ClassNotFoundException { - ListenerHolder holder = servletHandler.newListenerHolder(new Source(Source.Origin.ANNOTATION, className)); - holder.setHeldClass(loadClass(context, className)); - servletHandler.addListener(holder); - } - - @SuppressWarnings("unchecked") - private Class loadClass(WebAppContext context, String className) - throws ClassNotFoundException { - ClassLoader classLoader = context.getClassLoader(); - classLoader = (classLoader != null) ? classLoader : getClass().getClassLoader(); - return (Class) classLoader.loadClass(className); - } - - } - - /** - * {@link Handler.Wrapper} to apply {@link CookieSameSiteSupplier supplied} - * {@link SameSite} cookie values. - */ - private static class SuppliedSameSiteCookieHandlerWrapper extends Handler.Wrapper { - - private static final SetCookieParser setCookieParser = SetCookieParser.newInstance(); - - private final String sessionCookieName; - - private final List suppliers; - - SuppliedSameSiteCookieHandlerWrapper(String sessionCookieName, List suppliers) { - this.sessionCookieName = sessionCookieName; - this.suppliers = suppliers; - } - - @Override - public boolean handle(Request request, Response response, Callback callback) throws Exception { - SuppliedSameSiteCookieResponse wrappedResponse = new SuppliedSameSiteCookieResponse(request, response); - return super.handle(request, wrappedResponse, callback); - } - - private class SuppliedSameSiteCookieResponse extends Response.Wrapper { - - private final HttpFields.Mutable wrappedHeaders; - - SuppliedSameSiteCookieResponse(Request request, Response wrapped) { - super(request, wrapped); - this.wrappedHeaders = new SuppliedSameSiteCookieHeaders( - request.getConnectionMetaData().getHttpConfiguration().getResponseCookieCompliance(), - wrapped.getHeaders()); - } - - @Override - public Mutable getHeaders() { - return this.wrappedHeaders; - } - - } - - private class SuppliedSameSiteCookieHeaders extends HttpFields.Mutable.Wrapper { - - private final CookieCompliance compliance; - - SuppliedSameSiteCookieHeaders(CookieCompliance compliance, HttpFields.Mutable fields) { - super(fields); - this.compliance = compliance; - } - - @Override - public HttpField onAddField(HttpField field) { - return (field.getHeader() != HttpHeader.SET_COOKIE) ? field : onAddSetCookieField(field); - } - - private HttpField onAddSetCookieField(HttpField field) { - HttpCookie cookie = setCookieParser.parse(field.getValue()); - if (cookie == null || isSessionCookie(cookie)) { - return field; - } - SameSite sameSite = getSameSite(cookie); - if (sameSite == null) { - return field; - } - HttpCookie updatedCookie = buildCookieWithUpdatedSameSite(cookie, sameSite); - return new HttpCookieUtils.SetCookieHttpField(updatedCookie, this.compliance); - } - - private boolean isSessionCookie(HttpCookie cookie) { - return SuppliedSameSiteCookieHandlerWrapper.this.sessionCookieName.equals(cookie.getName()); - } - - private HttpCookie buildCookieWithUpdatedSameSite(HttpCookie cookie, SameSite sameSite) { - return HttpCookie.build(cookie) - .sameSite(org.eclipse.jetty.http.HttpCookie.SameSite.from(sameSite.name())) - .build(); - } - - private SameSite getSameSite(HttpCookie cookie) { - return getSameSite(asServletCookie(cookie)); - } - - private SameSite getSameSite(Cookie cookie) { - return SuppliedSameSiteCookieHandlerWrapper.this.suppliers.stream() - .map((supplier) -> supplier.getSameSite(cookie)) - .filter(Objects::nonNull) - .findFirst() - .orElse(null); - } - - private Cookie asServletCookie(HttpCookie cookie) { - Cookie servletCookie = new Cookie(cookie.getName(), cookie.getValue()); - cookie.getAttributes().forEach(servletCookie::setAttribute); - return servletCookie; - } - - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java deleted file mode 100644 index ed2ef2b8a617..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.jetty; - -import java.net.InetSocketAddress; - -import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; -import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.http2.HTTP2Cipher; -import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; -import org.eclipse.jetty.server.ConnectionFactory; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.util.ssl.SslContextFactory; - -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslBundleKey; -import org.springframework.boot.ssl.SslOptions; -import org.springframework.boot.ssl.SslStoreBundle; -import org.springframework.boot.web.server.Http2; -import org.springframework.boot.web.server.Ssl.ClientAuth; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link JettyServerCustomizer} that configures SSL on the given Jetty server instance. - * - * @author Brian Clozel - * @author Olivier Lamy - * @author Chris Bono - * @author Cyril Dangerville - * @author Scott Frederick - */ -class SslServerCustomizer implements JettyServerCustomizer { - - private final Http2 http2; - - private final InetSocketAddress address; - - private final ClientAuth clientAuth; - - private final SslBundle sslBundle; - - SslServerCustomizer(Http2 http2, InetSocketAddress address, ClientAuth clientAuth, SslBundle sslBundle) { - this.address = address; - this.clientAuth = clientAuth; - this.sslBundle = sslBundle; - this.http2 = http2; - } - - @Override - public void customize(Server server) { - SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setEndpointIdentificationAlgorithm(null); - configureSsl(sslContextFactory, this.clientAuth); - ServerConnector connector = createConnector(server, sslContextFactory); - server.setConnectors(new Connector[] { connector }); - } - - private ServerConnector createConnector(Server server, SslContextFactory.Server sslContextFactory) { - HttpConfiguration config = new HttpConfiguration(); - config.setSendServerVersion(false); - config.setSecureScheme("https"); - config.setSecurePort(this.address.getPort()); - config.addCustomizer(new SecureRequestCustomizer()); - ServerConnector connector = createServerConnector(server, sslContextFactory, config); - connector.setPort(this.address.getPort()); - connector.setHost(this.address.getHostString()); - return connector; - } - - private ServerConnector createServerConnector(Server server, SslContextFactory.Server sslContextFactory, - HttpConfiguration config) { - if (this.http2 == null || !this.http2.isEnabled()) { - return createHttp11ServerConnector(config, sslContextFactory, server); - } - Assert.state(isJettyAlpnPresent(), - () -> "An 'org.eclipse.jetty:jetty-alpn-*-server' dependency is required for HTTP/2 support."); - Assert.state(isJettyHttp2Present(), - () -> "The 'org.eclipse.jetty.http2:jetty-http2-server' dependency is required for HTTP/2 support."); - return createHttp2ServerConnector(config, sslContextFactory, server); - } - - private ServerConnector createHttp11ServerConnector(HttpConfiguration config, - SslContextFactory.Server sslContextFactory, Server server) { - SslConnectionFactory sslConnectionFactory = createSslConnectionFactory(sslContextFactory, - HttpVersion.HTTP_1_1.asString()); - HttpConnectionFactory connectionFactory = new HttpConnectionFactory(config); - return new SslValidatingServerConnector(this.sslBundle.getKey(), sslContextFactory, server, - sslConnectionFactory, connectionFactory); - } - - private SslConnectionFactory createSslConnectionFactory(SslContextFactory.Server sslContextFactory, - String protocol) { - return new SslConnectionFactory(sslContextFactory, protocol); - } - - private boolean isJettyAlpnPresent() { - return ClassUtils.isPresent("org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory", null); - } - - private boolean isJettyHttp2Present() { - return ClassUtils.isPresent("org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory", null); - } - - private ServerConnector createHttp2ServerConnector(HttpConfiguration config, - SslContextFactory.Server sslContextFactory, Server server) { - HttpConnectionFactory http = new HttpConnectionFactory(config); - HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(config); - ALPNServerConnectionFactory alpn = createAlpnServerConnectionFactory(); - sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); - if (isConscryptPresent()) { - sslContextFactory.setProvider("Conscrypt"); - } - SslConnectionFactory sslConnectionFactory = createSslConnectionFactory(sslContextFactory, alpn.getProtocol()); - return new SslValidatingServerConnector(this.sslBundle.getKey(), sslContextFactory, server, - sslConnectionFactory, alpn, h2, http); - } - - private ALPNServerConnectionFactory createAlpnServerConnectionFactory() { - try { - return new ALPNServerConnectionFactory(); - } - catch (IllegalStateException ex) { - throw new IllegalStateException( - "An 'org.eclipse.jetty:jetty-alpn-*-server' dependency is required for HTTP/2 support.", ex); - } - } - - private boolean isConscryptPresent() { - return ClassUtils.isPresent("org.conscrypt.Conscrypt", null) - && ClassUtils.isPresent("org.eclipse.jetty.alpn.conscrypt.server.ConscryptServerALPNProcessor", null); - } - - /** - * Configure the SSL connection. - * @param factory the Jetty {@link Server SslContextFactory.Server}. - * @param clientAuth the client authentication mode - */ - protected void configureSsl(SslContextFactory.Server factory, ClientAuth clientAuth) { - SslBundleKey key = this.sslBundle.getKey(); - SslOptions options = this.sslBundle.getOptions(); - SslStoreBundle stores = this.sslBundle.getStores(); - factory.setProtocol(this.sslBundle.getProtocol()); - configureSslClientAuth(factory, clientAuth); - if (stores.getKeyStorePassword() != null) { - factory.setKeyStorePassword(stores.getKeyStorePassword()); - } - factory.setCertAlias(key.getAlias()); - if (options.getCiphers() != null) { - factory.setIncludeCipherSuites(options.getCiphers()); - factory.setExcludeCipherSuites(); - } - if (options.getEnabledProtocols() != null) { - factory.setIncludeProtocols(options.getEnabledProtocols()); - factory.setExcludeProtocols(); - } - try { - if (key.getPassword() != null) { - factory.setKeyManagerPassword(key.getPassword()); - } - factory.setKeyStore(stores.getKeyStore()); - factory.setTrustStore(stores.getTrustStore()); - } - catch (Exception ex) { - throw new IllegalStateException("Unable to set SSL store: " + ex.getMessage(), ex); - } - } - - private void configureSslClientAuth(SslContextFactory.Server factory, ClientAuth clientAuth) { - factory.setWantClientAuth(clientAuth == ClientAuth.WANT || clientAuth == ClientAuth.NEED); - factory.setNeedClientAuth(clientAuth == ClientAuth.NEED); - } - - /** - * A {@link ServerConnector} that validates the ssl key alias on server startup. - */ - static class SslValidatingServerConnector extends ServerConnector { - - private final SslBundleKey key; - - private final SslContextFactory sslContextFactory; - - SslValidatingServerConnector(SslBundleKey key, SslContextFactory sslContextFactory, Server server, - SslConnectionFactory sslConnectionFactory, HttpConnectionFactory connectionFactory) { - super(server, sslConnectionFactory, connectionFactory); - this.key = key; - this.sslContextFactory = sslContextFactory; - } - - SslValidatingServerConnector(SslBundleKey keyAlias, SslContextFactory sslContextFactory, Server server, - ConnectionFactory... factories) { - super(server, factories); - this.key = keyAlias; - this.sslContextFactory = sslContextFactory; - } - - @Override - protected void doStart() throws Exception { - super.doStart(); - this.key.assertContainsAlias(this.sslContextFactory.getKeyStore()); - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/package-info.java deleted file mode 100644 index f56627374151..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Embedded reactive and servlet web server implementations backed by Jetty. - * - * @see org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory - * @see org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory - */ -package org.springframework.boot.web.embedded.jetty; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/GracefulShutdown.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/GracefulShutdown.java deleted file mode 100644 index 0e0cc14767f2..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/GracefulShutdown.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.netty; - -import java.time.Duration; -import java.util.function.Supplier; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.netty.DisposableServer; - -import org.springframework.boot.web.server.GracefulShutdownCallback; -import org.springframework.boot.web.server.GracefulShutdownResult; - -/** - * Handles Netty graceful shutdown. - * - * @author Andy Wilkinson - */ -final class GracefulShutdown { - - private static final Log logger = LogFactory.getLog(GracefulShutdown.class); - - private final Supplier disposableServer; - - private volatile Thread shutdownThread; - - private volatile boolean shuttingDown; - - GracefulShutdown(Supplier disposableServer) { - this.disposableServer = disposableServer; - } - - void shutDownGracefully(GracefulShutdownCallback callback) { - DisposableServer server = this.disposableServer.get(); - if (server == null) { - return; - } - logger.info("Commencing graceful shutdown. Waiting for active requests to complete"); - this.shutdownThread = new Thread(() -> doShutdown(callback, server), "netty-shutdown"); - this.shutdownThread.start(); - } - - private void doShutdown(GracefulShutdownCallback callback, DisposableServer server) { - this.shuttingDown = true; - try { - server.disposeNow(Duration.ofNanos(Long.MAX_VALUE)); - logger.info("Graceful shutdown complete"); - callback.shutdownComplete(GracefulShutdownResult.IDLE); - } - catch (Exception ex) { - logger.info("Graceful shutdown aborted with one or more requests still active"); - callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE); - } - finally { - this.shutdownThread = null; - this.shuttingDown = false; - } - } - - void abort() { - Thread shutdownThread = this.shutdownThread; - if (shutdownThread != null) { - while (!this.shuttingDown) { - sleep(50); - } - shutdownThread.interrupt(); - } - } - - private void sleep(long millis) { - try { - Thread.sleep(millis); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/SslServerCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/SslServerCustomizer.java deleted file mode 100644 index ea80e03cb189..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/SslServerCustomizer.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.netty; - -import java.util.HashMap; -import java.util.Map; - -import io.netty.handler.ssl.ClientAuth; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.netty.http.Http11SslContextSpec; -import reactor.netty.http.Http2SslContextSpec; -import reactor.netty.http.server.HttpServer; -import reactor.netty.tcp.AbstractProtocolSslContextSpec; -import reactor.netty.tcp.SslProvider; -import reactor.netty.tcp.SslProvider.GenericSslContextSpec; -import reactor.netty.tcp.SslProvider.SslContextSpec; - -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslOptions; -import org.springframework.boot.web.server.Http2; -import org.springframework.boot.web.server.Ssl; - -/** - * {@link NettyServerCustomizer} that configures SSL for the given Reactor Netty server - * instance. - * - * @author Brian Clozel - * @author Raheela Aslam - * @author Chris Bono - * @author Cyril Dangerville - * @author Scott Frederick - * @author Moritz Halbritter - * @author Phillip Webb - * @since 2.0.0 - */ -public class SslServerCustomizer implements NettyServerCustomizer { - - private static final Log logger = LogFactory.getLog(SslServerCustomizer.class); - - private final Http2 http2; - - private final ClientAuth clientAuth; - - private volatile SslProvider sslProvider; - - private final Map serverNameSslProviders; - - public SslServerCustomizer(Http2 http2, Ssl.ClientAuth clientAuth, SslBundle sslBundle, - Map serverNameSslBundles) { - this.http2 = http2; - this.clientAuth = Ssl.ClientAuth.map(clientAuth, ClientAuth.NONE, ClientAuth.OPTIONAL, ClientAuth.REQUIRE); - this.sslProvider = createSslProvider(sslBundle); - this.serverNameSslProviders = createServerNameSslProviders(serverNameSslBundles); - updateSslBundle(null, sslBundle); - } - - @Override - public HttpServer apply(HttpServer server) { - return server.secure(this::applySecurity); - } - - private void applySecurity(SslContextSpec spec) { - spec.sslContext(this.sslProvider.getSslContext()).setSniAsyncMappings((serverName, promise) -> { - SslProvider provider = (serverName != null) ? this.serverNameSslProviders.get(serverName) - : this.sslProvider; - return promise.setSuccess(provider); - }); - } - - void updateSslBundle(String serverName, SslBundle sslBundle) { - logger.debug("SSL Bundle has been updated, reloading SSL configuration"); - if (serverName == null) { - this.sslProvider = createSslProvider(sslBundle); - } - else { - this.serverNameSslProviders.put(serverName, createSslProvider(sslBundle)); - } - } - - private Map createServerNameSslProviders(Map serverNameSslBundles) { - Map serverNameSslProviders = new HashMap<>(); - serverNameSslBundles - .forEach((serverName, sslBundle) -> serverNameSslProviders.put(serverName, createSslProvider(sslBundle))); - return serverNameSslProviders; - } - - private SslProvider createSslProvider(SslBundle sslBundle) { - return SslProvider.builder().sslContext((GenericSslContextSpec) createSslContextSpec(sslBundle)).build(); - } - - /** - * Create an {@link AbstractProtocolSslContextSpec} for a given {@link SslBundle}. - * @param sslBundle the {@link SslBundle} to use - * @return an {@link AbstractProtocolSslContextSpec} instance - * @since 3.2.0 - */ - protected final AbstractProtocolSslContextSpec createSslContextSpec(SslBundle sslBundle) { - AbstractProtocolSslContextSpec sslContextSpec = (this.http2 != null && this.http2.isEnabled()) - ? Http2SslContextSpec.forServer(sslBundle.getManagers().getKeyManagerFactory()) - : Http11SslContextSpec.forServer(sslBundle.getManagers().getKeyManagerFactory()); - return sslContextSpec.configure((builder) -> { - builder.trustManager(sslBundle.getManagers().getTrustManagerFactory()); - SslOptions options = sslBundle.getOptions(); - builder.protocols(options.getEnabledProtocols()); - builder.ciphers(SslOptions.asSet(options.getCiphers())); - builder.clientAuth(this.clientAuth); - }); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/package-info.java deleted file mode 100644 index 331023ab4147..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Embedded reactive web server implementation backed by Netty. - * - * @see org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory - */ -package org.springframework.boot.web.embedded.netty; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/GracefulShutdown.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/GracefulShutdown.java deleted file mode 100644 index e1a7a17532a4..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/GracefulShutdown.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.tomcat; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CountDownLatch; - -import org.apache.catalina.Container; -import org.apache.catalina.Service; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardContext; -import org.apache.catalina.core.StandardWrapper; -import org.apache.catalina.startup.Tomcat; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.web.server.GracefulShutdownCallback; -import org.springframework.boot.web.server.GracefulShutdownResult; - -/** - * Handles Tomcat graceful shutdown. - * - * @author Andy Wilkinson - */ -final class GracefulShutdown { - - private static final Log logger = LogFactory.getLog(GracefulShutdown.class); - - private final Tomcat tomcat; - - private volatile boolean aborted = false; - - GracefulShutdown(Tomcat tomcat) { - this.tomcat = tomcat; - } - - void shutDownGracefully(GracefulShutdownCallback callback) { - logger.info("Commencing graceful shutdown. Waiting for active requests to complete"); - CountDownLatch shutdownUnderway = new CountDownLatch(1); - new Thread(() -> doShutdown(callback, shutdownUnderway), "tomcat-shutdown").start(); - try { - shutdownUnderway.await(); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - - private void doShutdown(GracefulShutdownCallback callback, CountDownLatch shutdownUnderway) { - try { - List connectors = getConnectors(); - connectors.forEach(this::close); - shutdownUnderway.countDown(); - awaitInactiveOrAborted(); - if (this.aborted) { - logger.info("Graceful shutdown aborted with one or more requests still active"); - callback.shutdownComplete(GracefulShutdownResult.REQUESTS_ACTIVE); - } - else { - logger.info("Graceful shutdown complete"); - callback.shutdownComplete(GracefulShutdownResult.IDLE); - } - } - finally { - shutdownUnderway.countDown(); - } - } - - private List getConnectors() { - List connectors = new ArrayList<>(); - for (Service service : this.tomcat.getServer().findServices()) { - Collections.addAll(connectors, service.findConnectors()); - } - return connectors; - } - - private void close(Connector connector) { - connector.pause(); - connector.getProtocolHandler().closeServerSocketGraceful(); - } - - private void awaitInactiveOrAborted() { - try { - for (Container host : this.tomcat.getEngine().findChildren()) { - for (Container context : host.findChildren()) { - while (!this.aborted && isActive(context)) { - Thread.sleep(50); - } - } - } - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - - private boolean isActive(Container context) { - try { - if (((StandardContext) context).getInProgressAsyncCount() > 0) { - return true; - } - for (Container wrapper : context.findChildren()) { - if (((StandardWrapper) wrapper).getCountAllocated() > 0) { - return true; - } - } - return false; - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - void abort() { - this.aborted = true; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java deleted file mode 100644 index 70c63d992358..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.tomcat; - -import java.io.File; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.catalina.Context; -import org.apache.catalina.Engine; -import org.apache.catalina.Executor; -import org.apache.catalina.Host; -import org.apache.catalina.LifecycleListener; -import org.apache.catalina.Valve; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.AprLifecycleListener; -import org.apache.catalina.loader.WebappLoader; -import org.apache.catalina.startup.Tomcat; -import org.apache.catalina.startup.Tomcat.FixContextListener; -import org.apache.catalina.webresources.StandardRoot; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.coyote.AbstractProtocol; -import org.apache.coyote.ProtocolHandler; -import org.apache.coyote.http2.Http2Protocol; -import org.apache.tomcat.util.modeler.Registry; -import org.apache.tomcat.util.scan.StandardJarScanFilter; - -import org.springframework.boot.util.LambdaSafe; -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.server.Ssl; -import org.springframework.boot.web.server.WebServer; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.http.server.reactive.TomcatHttpHandlerAdapter; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - * {@link ReactiveWebServerFactory} that can be used to create a {@link TomcatWebServer}. - * - * @author Brian Clozel - * @author HaiTao Zhang - * @author Moritz Halbritter - * @author Scott Frederick - * @since 2.0.0 - */ -public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFactory - implements ConfigurableTomcatWebServerFactory { - - private static final Log logger = LogFactory.getLog(TomcatReactiveWebServerFactory.class); - - private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; - - /** - * The class name of default protocol used. - */ - public static final String DEFAULT_PROTOCOL = "org.apache.coyote.http11.Http11NioProtocol"; - - private File baseDirectory; - - private final List engineValves = new ArrayList<>(); - - private List contextLifecycleListeners = new ArrayList<>(); - - private Set tomcatContextCustomizers = new LinkedHashSet<>(); - - private Set tomcatConnectorCustomizers = new LinkedHashSet<>(); - - private Set> tomcatProtocolHandlerCustomizers = new LinkedHashSet<>(); - - private final List additionalTomcatConnectors = new ArrayList<>(); - - private String protocol = DEFAULT_PROTOCOL; - - private Charset uriEncoding = DEFAULT_CHARSET; - - private int backgroundProcessorDelay; - - private boolean disableMBeanRegistry = true; - - private boolean useApr; - - /** - * Create a new {@link TomcatReactiveWebServerFactory} instance. - */ - public TomcatReactiveWebServerFactory() { - } - - /** - * Create a new {@link TomcatReactiveWebServerFactory} that listens for requests using - * the specified port. - * @param port the port to listen on - */ - public TomcatReactiveWebServerFactory(int port) { - super(port); - } - - private List getDefaultServerLifecycleListeners() { - ArrayList lifecycleListeners = new ArrayList<>(); - if (this.useApr) { - lifecycleListeners.add(new AprLifecycleListener()); - } - return lifecycleListeners; - } - - @Override - public WebServer getWebServer(HttpHandler httpHandler) { - if (this.disableMBeanRegistry) { - Registry.disableRegistry(); - } - Tomcat tomcat = new Tomcat(); - File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat"); - tomcat.setBaseDir(baseDir.getAbsolutePath()); - for (LifecycleListener listener : getDefaultServerLifecycleListeners()) { - tomcat.getServer().addLifecycleListener(listener); - } - Connector connector = new Connector(this.protocol); - connector.setThrowOnFailure(true); - tomcat.getService().addConnector(connector); - customizeConnector(connector); - tomcat.setConnector(connector); - registerConnectorExecutor(tomcat, connector); - tomcat.getHost().setAutoDeploy(false); - configureEngine(tomcat.getEngine()); - for (Connector additionalConnector : this.additionalTomcatConnectors) { - tomcat.getService().addConnector(additionalConnector); - registerConnectorExecutor(tomcat, additionalConnector); - } - TomcatHttpHandlerAdapter servlet = new TomcatHttpHandlerAdapter(httpHandler); - prepareContext(tomcat.getHost(), servlet); - return getTomcatWebServer(tomcat); - } - - private void registerConnectorExecutor(Tomcat tomcat, Connector connector) { - if (connector.getProtocolHandler().getExecutor() instanceof Executor executor) { - tomcat.getService().addExecutor(executor); - } - } - - private void configureEngine(Engine engine) { - engine.setBackgroundProcessorDelay(this.backgroundProcessorDelay); - for (Valve valve : this.engineValves) { - engine.getPipeline().addValve(valve); - } - } - - protected void prepareContext(Host host, TomcatHttpHandlerAdapter servlet) { - File docBase = createTempDir("tomcat-docbase"); - TomcatEmbeddedContext context = new TomcatEmbeddedContext(); - StandardRoot resourcesRoot = new StandardRoot(); - resourcesRoot.setReadOnly(true); - context.setResources(resourcesRoot); - context.setPath(""); - context.setDocBase(docBase.getAbsolutePath()); - context.addLifecycleListener(new FixContextListener()); - ClassLoader parentClassLoader = ClassUtils.getDefaultClassLoader(); - context.setParentClassLoader(parentClassLoader); - skipAllTldScanning(context); - WebappLoader loader = new WebappLoader(); - loader.setLoaderInstance(new TomcatEmbeddedWebappClassLoader(parentClassLoader)); - loader.setDelegate(true); - context.setLoader(loader); - Tomcat.addServlet(context, "httpHandlerServlet", servlet).setAsyncSupported(true); - context.addServletMappingDecoded("/", "httpHandlerServlet"); - host.addChild(context); - configureContext(context); - } - - private void skipAllTldScanning(TomcatEmbeddedContext context) { - StandardJarScanFilter filter = new StandardJarScanFilter(); - filter.setTldSkip("*.jar"); - context.getJarScanner().setJarScanFilter(filter); - } - - /** - * Configure the Tomcat {@link Context}. - * @param context the Tomcat context - */ - protected void configureContext(Context context) { - this.contextLifecycleListeners.forEach(context::addLifecycleListener); - new DisableReferenceClearingContextCustomizer().customize(context); - this.tomcatContextCustomizers.forEach((customizer) -> customizer.customize(context)); - } - - protected void customizeConnector(Connector connector) { - int port = Math.max(getPort(), 0); - connector.setPort(port); - if (StringUtils.hasText(getServerHeader())) { - connector.setProperty("server", getServerHeader()); - } - if (connector.getProtocolHandler() instanceof AbstractProtocol abstractProtocol) { - customizeProtocol(abstractProtocol); - } - invokeProtocolHandlerCustomizers(connector.getProtocolHandler()); - if (getUriEncoding() != null) { - connector.setURIEncoding(getUriEncoding().name()); - } - if (getHttp2() != null && getHttp2().isEnabled()) { - connector.addUpgradeProtocol(new Http2Protocol()); - } - if (Ssl.isEnabled(getSsl())) { - customizeSsl(connector); - } - TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer(getCompression()); - compression.customize(connector); - for (TomcatConnectorCustomizer customizer : this.tomcatConnectorCustomizers) { - customizer.customize(connector); - } - } - - @SuppressWarnings("unchecked") - private void invokeProtocolHandlerCustomizers(ProtocolHandler protocolHandler) { - LambdaSafe - .callbacks(TomcatProtocolHandlerCustomizer.class, this.tomcatProtocolHandlerCustomizers, protocolHandler) - .invoke((customizer) -> customizer.customize(protocolHandler)); - } - - private void customizeProtocol(AbstractProtocol protocol) { - if (getAddress() != null) { - protocol.setAddress(getAddress()); - } - } - - private void customizeSsl(Connector connector) { - SslConnectorCustomizer customizer = new SslConnectorCustomizer(logger, connector, getSsl().getClientAuth()); - customizer.customize(getSslBundle(), getServerNameSslBundles()); - addBundleUpdateHandler(null, getSsl().getBundle(), customizer); - getSsl().getServerNameBundles() - .forEach((serverNameSslBundle) -> addBundleUpdateHandler(serverNameSslBundle.serverName(), - serverNameSslBundle.bundle(), customizer)); - } - - private void addBundleUpdateHandler(String serverName, String sslBundleName, SslConnectorCustomizer customizer) { - if (StringUtils.hasText(sslBundleName)) { - getSslBundles().addBundleUpdateHandler(sslBundleName, - (sslBundle) -> customizer.update(serverName, sslBundle)); - } - } - - @Override - public void setBaseDirectory(File baseDirectory) { - this.baseDirectory = baseDirectory; - } - - @Override - public void setBackgroundProcessorDelay(int delay) { - this.backgroundProcessorDelay = delay; - } - - /** - * Set {@link TomcatContextCustomizer}s that should be applied to the Tomcat - * {@link Context}. Calling this method will replace any existing customizers. - * @param tomcatContextCustomizers the customizers to set - */ - public void setTomcatContextCustomizers(Collection tomcatContextCustomizers) { - Assert.notNull(tomcatContextCustomizers, "'tomcatContextCustomizers' must not be null"); - this.tomcatContextCustomizers = new LinkedHashSet<>(tomcatContextCustomizers); - } - - /** - * Returns a mutable collection of the {@link TomcatContextCustomizer}s that will be - * applied to the Tomcat {@link Context}. - * @return the listeners that will be applied - */ - public Collection getTomcatContextCustomizers() { - return this.tomcatContextCustomizers; - } - - /** - * Add {@link TomcatContextCustomizer}s that should be added to the Tomcat - * {@link Context}. - * @param tomcatContextCustomizers the customizers to add - */ - @Override - public void addContextCustomizers(TomcatContextCustomizer... tomcatContextCustomizers) { - Assert.notNull(tomcatContextCustomizers, "'tomcatContextCustomizers' must not be null"); - this.tomcatContextCustomizers.addAll(Arrays.asList(tomcatContextCustomizers)); - } - - /** - * Set {@link TomcatConnectorCustomizer}s that should be applied to the Tomcat - * {@link Connector}. Calling this method will replace any existing customizers. - * @param tomcatConnectorCustomizers the customizers to set - */ - public void setTomcatConnectorCustomizers( - Collection tomcatConnectorCustomizers) { - Assert.notNull(tomcatConnectorCustomizers, "'tomcatConnectorCustomizers' must not be null"); - this.tomcatConnectorCustomizers = new LinkedHashSet<>(tomcatConnectorCustomizers); - } - - /** - * Add {@link TomcatConnectorCustomizer}s that should be added to the Tomcat - * {@link Connector}. - * @param tomcatConnectorCustomizers the customizers to add - */ - @Override - public void addConnectorCustomizers(TomcatConnectorCustomizer... tomcatConnectorCustomizers) { - Assert.notNull(tomcatConnectorCustomizers, "'tomcatConnectorCustomizers' must not be null"); - this.tomcatConnectorCustomizers.addAll(Arrays.asList(tomcatConnectorCustomizers)); - } - - /** - * Returns a mutable collection of the {@link TomcatConnectorCustomizer}s that will be - * applied to the Tomcat {@link Connector}. - * @return the customizers that will be applied - */ - public Collection getTomcatConnectorCustomizers() { - return this.tomcatConnectorCustomizers; - } - - /** - * Set {@link TomcatProtocolHandlerCustomizer}s that should be applied to the Tomcat - * {@link Connector}. Calling this method will replace any existing customizers. - * @param tomcatProtocolHandlerCustomizers the customizers to set - * @since 2.2.0 - */ - public void setTomcatProtocolHandlerCustomizers( - Collection> tomcatProtocolHandlerCustomizers) { - Assert.notNull(tomcatProtocolHandlerCustomizers, "'tomcatProtocolHandlerCustomizers' must not be null"); - this.tomcatProtocolHandlerCustomizers = new LinkedHashSet<>(tomcatProtocolHandlerCustomizers); - } - - /** - * Add {@link TomcatProtocolHandlerCustomizer}s that should be added to the Tomcat - * {@link Connector}. - * @param tomcatProtocolHandlerCustomizers the customizers to add - * @since 2.2.0 - */ - @Override - public void addProtocolHandlerCustomizers(TomcatProtocolHandlerCustomizer... tomcatProtocolHandlerCustomizers) { - Assert.notNull(tomcatProtocolHandlerCustomizers, "'tomcatProtocolHandlerCustomizers' must not be null"); - this.tomcatProtocolHandlerCustomizers.addAll(Arrays.asList(tomcatProtocolHandlerCustomizers)); - } - - /** - * Returns a mutable collection of the {@link TomcatProtocolHandlerCustomizer}s that - * will be applied to the Tomcat {@link Connector}. - * @return the customizers that will be applied - * @since 2.2.0 - */ - public Collection> getTomcatProtocolHandlerCustomizers() { - return this.tomcatProtocolHandlerCustomizers; - } - - /** - * Add {@link Connector}s in addition to the default connector, e.g. for SSL or AJP. - *

    - * {@link #getTomcatConnectorCustomizers Connector customizers} are not applied to - * connectors added this way. - * @param connectors the connectors to add - * @since 2.2.0 - */ - public void addAdditionalTomcatConnectors(Connector... connectors) { - Assert.notNull(connectors, "'connectors' must not be null"); - this.additionalTomcatConnectors.addAll(Arrays.asList(connectors)); - } - - /** - * Returns a mutable collection of the {@link Connector}s that will be added to the - * Tomcat. - * @return the additionalTomcatConnectors - * @since 2.2.0 - */ - public List getAdditionalTomcatConnectors() { - return this.additionalTomcatConnectors; - } - - @Override - public void addEngineValves(Valve... engineValves) { - Assert.notNull(engineValves, "'engineValves' must not be null"); - this.engineValves.addAll(Arrays.asList(engineValves)); - } - - /** - * Returns a mutable collection of the {@link Valve}s that will be applied to the - * Tomcat {@link Engine}. - * @return the engine valves that will be applied - */ - public List getEngineValves() { - return this.engineValves; - } - - /** - * Set the character encoding to use for URL decoding. If not specified 'UTF-8' will - * be used. - * @param uriEncoding the uri encoding to set - */ - @Override - public void setUriEncoding(Charset uriEncoding) { - this.uriEncoding = uriEncoding; - } - - /** - * Returns the character encoding to use for URL decoding. - * @return the URI encoding - */ - public Charset getUriEncoding() { - return this.uriEncoding; - } - - /** - * Set {@link LifecycleListener}s that should be applied to the Tomcat - * {@link Context}. Calling this method will replace any existing listeners. - * @param contextLifecycleListeners the listeners to set - */ - public void setContextLifecycleListeners(Collection contextLifecycleListeners) { - Assert.notNull(contextLifecycleListeners, "'contextLifecycleListeners' must not be null"); - this.contextLifecycleListeners = new ArrayList<>(contextLifecycleListeners); - } - - /** - * Returns a mutable collection of the {@link LifecycleListener}s that will be applied - * to the Tomcat {@link Context}. - * @return the context lifecycle listeners that will be applied - */ - public Collection getContextLifecycleListeners() { - return this.contextLifecycleListeners; - } - - /** - * Add {@link LifecycleListener}s that should be added to the Tomcat {@link Context}. - * @param contextLifecycleListeners the listeners to add - */ - public void addContextLifecycleListeners(LifecycleListener... contextLifecycleListeners) { - Assert.notNull(contextLifecycleListeners, "'contextLifecycleListeners' must not be null"); - this.contextLifecycleListeners.addAll(Arrays.asList(contextLifecycleListeners)); - } - - /** - * Factory method called to create the {@link TomcatWebServer}. Subclasses can - * override this method to return a different {@link TomcatWebServer} or apply - * additional processing to the Tomcat server. - * @param tomcat the Tomcat server. - * @return a new {@link TomcatWebServer} instance - */ - protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { - return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown()); - } - - /** - * The Tomcat protocol to use when create the {@link Connector}. - * @param protocol the protocol - * @see Connector#Connector(String) - */ - public void setProtocol(String protocol) { - Assert.hasLength(protocol, "'protocol' must not be empty"); - this.protocol = protocol; - } - - /** - * Set whether the factory should disable Tomcat's MBean registry prior to creating - * the server. - * @param disableMBeanRegistry whether to disable the MBean registry - * @since 2.2.0 - */ - public void setDisableMBeanRegistry(boolean disableMBeanRegistry) { - this.disableMBeanRegistry = disableMBeanRegistry; - } - - /** - * Whether to use APR. - * @param useApr whether to use APR - * @since 3.4.4 - */ - public void setUseApr(boolean useApr) { - this.useApr = useApr; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java deleted file mode 100644 index 32d05bfd5b60..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java +++ /dev/null @@ -1,1032 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.tomcat; - -import java.io.File; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.stream.Collectors; - -import jakarta.servlet.ServletContainerInitializer; -import jakarta.servlet.http.Cookie; -import jakarta.servlet.http.HttpServletRequest; -import org.apache.catalina.Context; -import org.apache.catalina.Engine; -import org.apache.catalina.Executor; -import org.apache.catalina.Host; -import org.apache.catalina.Lifecycle; -import org.apache.catalina.LifecycleEvent; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleListener; -import org.apache.catalina.Manager; -import org.apache.catalina.Valve; -import org.apache.catalina.WebResource; -import org.apache.catalina.WebResourceRoot; -import org.apache.catalina.WebResourceRoot.ResourceSetType; -import org.apache.catalina.WebResourceSet; -import org.apache.catalina.Wrapper; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.AprLifecycleListener; -import org.apache.catalina.loader.WebappLoader; -import org.apache.catalina.session.StandardManager; -import org.apache.catalina.startup.Tomcat; -import org.apache.catalina.startup.Tomcat.FixContextListener; -import org.apache.catalina.util.LifecycleBase; -import org.apache.catalina.util.SessionConfig; -import org.apache.catalina.webresources.AbstractResourceSet; -import org.apache.catalina.webresources.EmptyResource; -import org.apache.catalina.webresources.StandardRoot; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.coyote.AbstractProtocol; -import org.apache.coyote.ProtocolHandler; -import org.apache.coyote.http2.Http2Protocol; -import org.apache.tomcat.util.http.Rfc6265CookieProcessor; -import org.apache.tomcat.util.modeler.Registry; -import org.apache.tomcat.util.scan.StandardJarScanFilter; - -import org.springframework.boot.util.LambdaSafe; -import org.springframework.boot.web.server.Cookie.SameSite; -import org.springframework.boot.web.server.ErrorPage; -import org.springframework.boot.web.server.MimeMappings; -import org.springframework.boot.web.server.Ssl; -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; -import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.NativeDetector; -import org.springframework.core.io.ResourceLoader; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - * {@link AbstractServletWebServerFactory} that can be used to create - * {@link TomcatWebServer}s. Can be initialized using Spring's - * {@link ServletContextInitializer}s or Tomcat {@link LifecycleListener}s. - *

    - * Unless explicitly configured otherwise this factory will create containers that listen - * for HTTP requests on port 8080. - * - * @author Phillip Webb - * @author Dave Syer - * @author Brock Mills - * @author Stephane Nicoll - * @author Andy Wilkinson - * @author Eddú Meléndez - * @author Christoffer Sawicki - * @author Dawid Antecki - * @author Moritz Halbritter - * @author Scott Frederick - * @since 2.0.0 - * @see #setPort(int) - * @see #setContextLifecycleListeners(Collection) - * @see TomcatWebServer - */ -public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory - implements ConfigurableTomcatWebServerFactory, ResourceLoaderAware { - - private static final Log logger = LogFactory.getLog(TomcatServletWebServerFactory.class); - - private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; - - private static final Set> NO_CLASSES = Collections.emptySet(); - - /** - * The class name of default protocol used. - */ - public static final String DEFAULT_PROTOCOL = "org.apache.coyote.http11.Http11NioProtocol"; - - private File baseDirectory; - - private List engineValves = new ArrayList<>(); - - private List contextValves = new ArrayList<>(); - - private List contextLifecycleListeners = new ArrayList<>(); - - private Set tomcatContextCustomizers = new LinkedHashSet<>(); - - private Set tomcatConnectorCustomizers = new LinkedHashSet<>(); - - private Set> tomcatProtocolHandlerCustomizers = new LinkedHashSet<>(); - - private final List additionalTomcatConnectors = new ArrayList<>(); - - private ResourceLoader resourceLoader; - - private String protocol = DEFAULT_PROTOCOL; - - private Set tldSkipPatterns = new LinkedHashSet<>(TldPatterns.DEFAULT_SKIP); - - private final Set tldScanPatterns = new LinkedHashSet<>(TldPatterns.DEFAULT_SCAN); - - private Charset uriEncoding = DEFAULT_CHARSET; - - private int backgroundProcessorDelay; - - private boolean disableMBeanRegistry = true; - - private boolean useApr; - - /** - * Create a new {@link TomcatServletWebServerFactory} instance. - */ - public TomcatServletWebServerFactory() { - } - - /** - * Create a new {@link TomcatServletWebServerFactory} that listens for requests using - * the specified port. - * @param port the port to listen on - */ - public TomcatServletWebServerFactory(int port) { - super(port); - } - - /** - * Create a new {@link TomcatServletWebServerFactory} with the specified context path - * and port. - * @param contextPath the root context path - * @param port the port to listen on - */ - public TomcatServletWebServerFactory(String contextPath, int port) { - super(contextPath, port); - } - - private List getDefaultServerLifecycleListeners() { - ArrayList lifecycleListeners = new ArrayList<>(); - if (!NativeDetector.inNativeImage() && this.useApr) { - lifecycleListeners.add(new AprLifecycleListener()); - } - return lifecycleListeners; - } - - @Override - public WebServer getWebServer(ServletContextInitializer... initializers) { - if (this.disableMBeanRegistry) { - Registry.disableRegistry(); - } - Tomcat tomcat = new Tomcat(); - File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat"); - tomcat.setBaseDir(baseDir.getAbsolutePath()); - for (LifecycleListener listener : getDefaultServerLifecycleListeners()) { - tomcat.getServer().addLifecycleListener(listener); - } - Connector connector = new Connector(this.protocol); - connector.setThrowOnFailure(true); - tomcat.getService().addConnector(connector); - customizeConnector(connector); - tomcat.setConnector(connector); - registerConnectorExecutor(tomcat, connector); - tomcat.getHost().setAutoDeploy(false); - configureEngine(tomcat.getEngine()); - for (Connector additionalConnector : this.additionalTomcatConnectors) { - tomcat.getService().addConnector(additionalConnector); - registerConnectorExecutor(tomcat, additionalConnector); - } - prepareContext(tomcat.getHost(), initializers); - return getTomcatWebServer(tomcat); - } - - private void registerConnectorExecutor(Tomcat tomcat, Connector connector) { - if (connector.getProtocolHandler().getExecutor() instanceof Executor executor) { - tomcat.getService().addExecutor(executor); - } - } - - private void configureEngine(Engine engine) { - engine.setBackgroundProcessorDelay(this.backgroundProcessorDelay); - for (Valve valve : this.engineValves) { - engine.getPipeline().addValve(valve); - } - } - - protected void prepareContext(Host host, ServletContextInitializer[] initializers) { - File documentRoot = getValidDocumentRoot(); - TomcatEmbeddedContext context = new TomcatEmbeddedContext(); - WebResourceRoot resourceRoot = (documentRoot != null) ? new LoaderHidingResourceRoot(context) - : new StandardRoot(context); - ignoringNoSuchMethodError(() -> resourceRoot.setReadOnly(true)); - context.setResources(resourceRoot); - context.setName(getContextPath()); - context.setDisplayName(getDisplayName()); - context.setPath(getContextPath()); - File docBase = (documentRoot != null) ? documentRoot : createTempDir("tomcat-docbase"); - context.setDocBase(docBase.getAbsolutePath()); - context.addLifecycleListener(new FixContextListener()); - ClassLoader parentClassLoader = (this.resourceLoader != null) ? this.resourceLoader.getClassLoader() - : ClassUtils.getDefaultClassLoader(); - context.setParentClassLoader(parentClassLoader); - resetDefaultLocaleMapping(context); - addLocaleMappings(context); - context.setCreateUploadTargets(true); - configureTldPatterns(context); - WebappLoader loader = new WebappLoader(); - loader.setLoaderInstance(new TomcatEmbeddedWebappClassLoader(parentClassLoader)); - loader.setDelegate(true); - context.setLoader(loader); - if (isRegisterDefaultServlet()) { - addDefaultServlet(context); - } - if (shouldRegisterJspServlet()) { - addJspServlet(context); - addJasperInitializer(context); - } - context.addLifecycleListener(new StaticResourceConfigurer(context)); - ServletContextInitializer[] initializersToUse = mergeInitializers(initializers); - host.addChild(context); - configureContext(context, initializersToUse); - postProcessContext(context); - } - - private void ignoringNoSuchMethodError(Runnable method) { - try { - method.run(); - } - catch (NoSuchMethodError ex) { - } - } - - /** - * Override Tomcat's default locale mappings to align with other servers. See - * {@code org.apache.catalina.util.CharsetMapperDefault.properties}. - * @param context the context to reset - */ - private void resetDefaultLocaleMapping(TomcatEmbeddedContext context) { - context.addLocaleEncodingMappingParameter(Locale.ENGLISH.toString(), DEFAULT_CHARSET.displayName()); - context.addLocaleEncodingMappingParameter(Locale.FRENCH.toString(), DEFAULT_CHARSET.displayName()); - context.addLocaleEncodingMappingParameter(Locale.JAPANESE.toString(), DEFAULT_CHARSET.displayName()); - } - - private void addLocaleMappings(TomcatEmbeddedContext context) { - getLocaleCharsetMappings().forEach( - (locale, charset) -> context.addLocaleEncodingMappingParameter(locale.toString(), charset.toString())); - } - - private void configureTldPatterns(TomcatEmbeddedContext context) { - StandardJarScanFilter filter = new StandardJarScanFilter(); - filter.setTldSkip(StringUtils.collectionToCommaDelimitedString(this.tldSkipPatterns)); - filter.setTldScan(StringUtils.collectionToCommaDelimitedString(this.tldScanPatterns)); - context.getJarScanner().setJarScanFilter(filter); - } - - private void addDefaultServlet(Context context) { - Wrapper defaultServlet = context.createWrapper(); - defaultServlet.setName("default"); - defaultServlet.setServletClass("org.apache.catalina.servlets.DefaultServlet"); - defaultServlet.addInitParameter("debug", "0"); - defaultServlet.addInitParameter("listings", "false"); - defaultServlet.setLoadOnStartup(1); - // Otherwise the default location of a Spring DispatcherServlet cannot be set - defaultServlet.setOverridable(true); - context.addChild(defaultServlet); - context.addServletMappingDecoded("/", "default"); - } - - private void addJspServlet(Context context) { - Wrapper jspServlet = context.createWrapper(); - jspServlet.setName("jsp"); - jspServlet.setServletClass(getJsp().getClassName()); - jspServlet.addInitParameter("fork", "false"); - getJsp().getInitParameters().forEach(jspServlet::addInitParameter); - jspServlet.setLoadOnStartup(3); - context.addChild(jspServlet); - context.addServletMappingDecoded("*.jsp", "jsp"); - context.addServletMappingDecoded("*.jspx", "jsp"); - } - - private void addJasperInitializer(TomcatEmbeddedContext context) { - try { - ServletContainerInitializer initializer = (ServletContainerInitializer) ClassUtils - .forName("org.apache.jasper.servlet.JasperInitializer", null) - .getDeclaredConstructor() - .newInstance(); - context.addServletContainerInitializer(initializer, null); - } - catch (Exception ex) { - // Probably not Tomcat 8 - } - } - - // Needs to be protected so it can be used by subclasses - protected void customizeConnector(Connector connector) { - int port = Math.max(getPort(), 0); - connector.setPort(port); - if (StringUtils.hasText(getServerHeader())) { - connector.setProperty("server", getServerHeader()); - } - if (connector.getProtocolHandler() instanceof AbstractProtocol abstractProtocol) { - customizeProtocol(abstractProtocol); - } - invokeProtocolHandlerCustomizers(connector.getProtocolHandler()); - if (getUriEncoding() != null) { - connector.setURIEncoding(getUriEncoding().name()); - } - if (getHttp2() != null && getHttp2().isEnabled()) { - connector.addUpgradeProtocol(new Http2Protocol()); - } - if (Ssl.isEnabled(getSsl())) { - customizeSsl(connector); - } - TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer(getCompression()); - compression.customize(connector); - for (TomcatConnectorCustomizer customizer : this.tomcatConnectorCustomizers) { - customizer.customize(connector); - } - } - - private void customizeProtocol(AbstractProtocol protocol) { - if (getAddress() != null) { - protocol.setAddress(getAddress()); - } - } - - @SuppressWarnings("unchecked") - private void invokeProtocolHandlerCustomizers(ProtocolHandler protocolHandler) { - LambdaSafe - .callbacks(TomcatProtocolHandlerCustomizer.class, this.tomcatProtocolHandlerCustomizers, protocolHandler) - .invoke((customizer) -> customizer.customize(protocolHandler)); - } - - private void customizeSsl(Connector connector) { - SslConnectorCustomizer customizer = new SslConnectorCustomizer(logger, connector, getSsl().getClientAuth()); - customizer.customize(getSslBundle(), getServerNameSslBundles()); - addBundleUpdateHandler(null, getSsl().getBundle(), customizer); - getSsl().getServerNameBundles() - .forEach((serverNameSslBundle) -> addBundleUpdateHandler(serverNameSslBundle.serverName(), - serverNameSslBundle.bundle(), customizer)); - } - - private void addBundleUpdateHandler(String serverName, String sslBundleName, SslConnectorCustomizer customizer) { - if (StringUtils.hasText(sslBundleName)) { - getSslBundles().addBundleUpdateHandler(sslBundleName, - (sslBundle) -> customizer.update(serverName, sslBundle)); - } - } - - /** - * Configure the Tomcat {@link Context}. - * @param context the Tomcat context - * @param initializers initializers to apply - */ - protected void configureContext(Context context, ServletContextInitializer[] initializers) { - TomcatStarter starter = new TomcatStarter(initializers); - if (context instanceof TomcatEmbeddedContext embeddedContext) { - embeddedContext.setStarter(starter); - embeddedContext.setFailCtxIfServletStartFails(true); - } - context.addServletContainerInitializer(starter, NO_CLASSES); - for (LifecycleListener lifecycleListener : this.contextLifecycleListeners) { - context.addLifecycleListener(lifecycleListener); - } - for (Valve valve : this.contextValves) { - context.getPipeline().addValve(valve); - } - for (ErrorPage errorPage : getErrorPages()) { - org.apache.tomcat.util.descriptor.web.ErrorPage tomcatErrorPage = new org.apache.tomcat.util.descriptor.web.ErrorPage(); - tomcatErrorPage.setLocation(errorPage.getPath()); - tomcatErrorPage.setErrorCode(errorPage.getStatusCode()); - tomcatErrorPage.setExceptionType(errorPage.getExceptionName()); - context.addErrorPage(tomcatErrorPage); - } - setMimeMappings(context); - configureSession(context); - configureCookieProcessor(context); - new DisableReferenceClearingContextCustomizer().customize(context); - for (String webListenerClassName : getWebListenerClassNames()) { - context.addApplicationListener(webListenerClassName); - } - for (TomcatContextCustomizer customizer : this.tomcatContextCustomizers) { - customizer.customize(context); - } - } - - private void configureSession(Context context) { - long sessionTimeout = getSessionTimeoutInMinutes(); - context.setSessionTimeout((int) sessionTimeout); - Boolean httpOnly = getSession().getCookie().getHttpOnly(); - if (httpOnly != null) { - context.setUseHttpOnly(httpOnly); - } - if (getSession().isPersistent()) { - Manager manager = context.getManager(); - if (manager == null) { - manager = new StandardManager(); - context.setManager(manager); - } - configurePersistSession(manager); - } - else { - context.addLifecycleListener(new DisablePersistSessionListener()); - } - } - - private void setMimeMappings(Context context) { - if (context instanceof TomcatEmbeddedContext embeddedContext) { - embeddedContext.setMimeMappings(getMimeMappings()); - return; - } - for (MimeMappings.Mapping mapping : getMimeMappings()) { - context.addMimeMapping(mapping.getExtension(), mapping.getMimeType()); - } - } - - private void configureCookieProcessor(Context context) { - SameSite sessionSameSite = getSession().getCookie().getSameSite(); - List suppliers = new ArrayList<>(); - if (sessionSameSite != null) { - suppliers.add(CookieSameSiteSupplier.of(sessionSameSite) - .whenHasName(() -> SessionConfig.getSessionCookieName(context))); - } - if (!CollectionUtils.isEmpty(getCookieSameSiteSuppliers())) { - suppliers.addAll(getCookieSameSiteSuppliers()); - } - if (!suppliers.isEmpty()) { - context.setCookieProcessor(new SuppliedSameSiteCookieProcessor(suppliers)); - } - } - - private void configurePersistSession(Manager manager) { - Assert.state(manager instanceof StandardManager, - () -> "Unable to persist HTTP session state using manager type " + manager.getClass().getName()); - File dir = getValidSessionStoreDir(); - File file = new File(dir, "SESSIONS.ser"); - ((StandardManager) manager).setPathname(file.getAbsolutePath()); - } - - private long getSessionTimeoutInMinutes() { - Duration sessionTimeout = getSession().getTimeout(); - if (isZeroOrLess(sessionTimeout)) { - return 0; - } - return Math.max(sessionTimeout.toMinutes(), 1); - } - - private boolean isZeroOrLess(Duration sessionTimeout) { - return sessionTimeout == null || sessionTimeout.isNegative() || sessionTimeout.isZero(); - } - - /** - * Post process the Tomcat {@link Context} before it's used with the Tomcat Server. - * Subclasses can override this method to apply additional processing to the - * {@link Context}. - * @param context the Tomcat {@link Context} - */ - protected void postProcessContext(Context context) { - } - - /** - * Factory method called to create the {@link TomcatWebServer}. Subclasses can - * override this method to return a different {@link TomcatWebServer} or apply - * additional processing to the Tomcat server. - * @param tomcat the Tomcat server. - * @return a new {@link TomcatWebServer} instance - */ - protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { - return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown()); - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - - @Override - public void setBaseDirectory(File baseDirectory) { - this.baseDirectory = baseDirectory; - } - - /** - * Returns a mutable set of the patterns that match jars to ignore for TLD scanning. - * @return the set of jars to ignore for TLD scanning - */ - public Set getTldSkipPatterns() { - return this.tldSkipPatterns; - } - - /** - * Set the patterns that match jars to ignore for TLD scanning. See Tomcat's - * catalina.properties for typical values. Defaults to a list drawn from that source. - * @param patterns the jar patterns to skip when scanning for TLDs etc - */ - public void setTldSkipPatterns(Collection patterns) { - Assert.notNull(patterns, "'patterns' must not be null"); - this.tldSkipPatterns = new LinkedHashSet<>(patterns); - } - - /** - * Add patterns that match jars to ignore for TLD scanning. See Tomcat's - * catalina.properties for typical values. - * @param patterns the additional jar patterns to skip when scanning for TLDs etc - */ - public void addTldSkipPatterns(String... patterns) { - Assert.notNull(patterns, "'patterns' must not be null"); - this.tldSkipPatterns.addAll(Arrays.asList(patterns)); - } - - /** - * The Tomcat protocol to use when create the {@link Connector}. - * @param protocol the protocol - * @see Connector#Connector(String) - */ - public void setProtocol(String protocol) { - Assert.hasLength(protocol, "'protocol' must not be empty"); - this.protocol = protocol; - } - - /** - * Set {@link Valve}s that should be applied to the Tomcat {@link Engine}. Calling - * this method will replace any existing valves. - * @param engineValves the valves to set - */ - public void setEngineValves(Collection engineValves) { - Assert.notNull(engineValves, "'engineValves' must not be null"); - this.engineValves = new ArrayList<>(engineValves); - } - - /** - * Returns a mutable collection of the {@link Valve}s that will be applied to the - * Tomcat {@link Engine}. - * @return the engine valves that will be applied - */ - public Collection getEngineValves() { - return this.engineValves; - } - - @Override - public void addEngineValves(Valve... engineValves) { - Assert.notNull(engineValves, "'engineValves' must not be null"); - this.engineValves.addAll(Arrays.asList(engineValves)); - } - - /** - * Set {@link Valve}s that should be applied to the Tomcat {@link Context}. Calling - * this method will replace any existing valves. - * @param contextValves the valves to set - */ - public void setContextValves(Collection contextValves) { - Assert.notNull(contextValves, "'contextValves' must not be null"); - this.contextValves = new ArrayList<>(contextValves); - } - - /** - * Returns a mutable collection of the {@link Valve}s that will be applied to the - * Tomcat {@link Context}. - * @return the context valves that will be applied - * @see #getEngineValves() - */ - public Collection getContextValves() { - return this.contextValves; - } - - /** - * Add {@link Valve}s that should be applied to the Tomcat {@link Context}. - * @param contextValves the valves to add - */ - public void addContextValves(Valve... contextValves) { - Assert.notNull(contextValves, "'contextValves' must not be null"); - this.contextValves.addAll(Arrays.asList(contextValves)); - } - - /** - * Set {@link LifecycleListener}s that should be applied to the Tomcat - * {@link Context}. Calling this method will replace any existing listeners. - * @param contextLifecycleListeners the listeners to set - */ - public void setContextLifecycleListeners(Collection contextLifecycleListeners) { - Assert.notNull(contextLifecycleListeners, "'contextLifecycleListeners' must not be null"); - this.contextLifecycleListeners = new ArrayList<>(contextLifecycleListeners); - } - - /** - * Returns a mutable collection of the {@link LifecycleListener}s that will be applied - * to the Tomcat {@link Context}. - * @return the context lifecycle listeners that will be applied - */ - public Collection getContextLifecycleListeners() { - return this.contextLifecycleListeners; - } - - /** - * Add {@link LifecycleListener}s that should be added to the Tomcat {@link Context}. - * @param contextLifecycleListeners the listeners to add - */ - public void addContextLifecycleListeners(LifecycleListener... contextLifecycleListeners) { - Assert.notNull(contextLifecycleListeners, "'contextLifecycleListeners' must not be null"); - this.contextLifecycleListeners.addAll(Arrays.asList(contextLifecycleListeners)); - } - - /** - * Set {@link TomcatContextCustomizer}s that should be applied to the Tomcat - * {@link Context}. Calling this method will replace any existing customizers. - * @param tomcatContextCustomizers the customizers to set - */ - public void setTomcatContextCustomizers(Collection tomcatContextCustomizers) { - Assert.notNull(tomcatContextCustomizers, "'tomcatContextCustomizers' must not be null"); - this.tomcatContextCustomizers = new LinkedHashSet<>(tomcatContextCustomizers); - } - - /** - * Returns a mutable collection of the {@link TomcatContextCustomizer}s that will be - * applied to the Tomcat {@link Context}. - * @return the listeners that will be applied - */ - public Collection getTomcatContextCustomizers() { - return this.tomcatContextCustomizers; - } - - @Override - public void addContextCustomizers(TomcatContextCustomizer... tomcatContextCustomizers) { - Assert.notNull(tomcatContextCustomizers, "'tomcatContextCustomizers' must not be null"); - this.tomcatContextCustomizers.addAll(Arrays.asList(tomcatContextCustomizers)); - } - - /** - * Set {@link TomcatConnectorCustomizer}s that should be applied to the Tomcat - * {@link Connector}. Calling this method will replace any existing customizers. - * @param tomcatConnectorCustomizers the customizers to set - */ - public void setTomcatConnectorCustomizers( - Collection tomcatConnectorCustomizers) { - Assert.notNull(tomcatConnectorCustomizers, "'tomcatConnectorCustomizers' must not be null"); - this.tomcatConnectorCustomizers = new LinkedHashSet<>(tomcatConnectorCustomizers); - } - - @Override - public void addConnectorCustomizers(TomcatConnectorCustomizer... tomcatConnectorCustomizers) { - Assert.notNull(tomcatConnectorCustomizers, "'tomcatConnectorCustomizers' must not be null"); - this.tomcatConnectorCustomizers.addAll(Arrays.asList(tomcatConnectorCustomizers)); - } - - /** - * Returns a mutable collection of the {@link TomcatConnectorCustomizer}s that will be - * applied to the Tomcat {@link Connector}. - * @return the customizers that will be applied - */ - public Collection getTomcatConnectorCustomizers() { - return this.tomcatConnectorCustomizers; - } - - /** - * Set {@link TomcatProtocolHandlerCustomizer}s that should be applied to the Tomcat - * {@link Connector}. Calling this method will replace any existing customizers. - * @param tomcatProtocolHandlerCustomizer the customizers to set - * @since 2.2.0 - */ - public void setTomcatProtocolHandlerCustomizers( - Collection> tomcatProtocolHandlerCustomizer) { - Assert.notNull(tomcatProtocolHandlerCustomizer, "'tomcatProtocolHandlerCustomizer' must not be null"); - this.tomcatProtocolHandlerCustomizers = new LinkedHashSet<>(tomcatProtocolHandlerCustomizer); - } - - /** - * Add {@link TomcatProtocolHandlerCustomizer}s that should be added to the Tomcat - * {@link Connector}. - * @param tomcatProtocolHandlerCustomizers the customizers to add - * @since 2.2.0 - */ - @Override - public void addProtocolHandlerCustomizers(TomcatProtocolHandlerCustomizer... tomcatProtocolHandlerCustomizers) { - Assert.notNull(tomcatProtocolHandlerCustomizers, "'tomcatProtocolHandlerCustomizers' must not be null"); - this.tomcatProtocolHandlerCustomizers.addAll(Arrays.asList(tomcatProtocolHandlerCustomizers)); - } - - /** - * Returns a mutable collection of the {@link TomcatProtocolHandlerCustomizer}s that - * will be applied to the Tomcat {@link Connector}. - * @return the customizers that will be applied - * @since 2.2.0 - */ - public Collection> getTomcatProtocolHandlerCustomizers() { - return this.tomcatProtocolHandlerCustomizers; - } - - /** - * Add {@link Connector}s in addition to the default connector, e.g. for SSL or AJP. - *

    - * {@link #getTomcatConnectorCustomizers Connector customizers} are not applied to - * connectors added this way. - * @param connectors the connectors to add - */ - public void addAdditionalTomcatConnectors(Connector... connectors) { - Assert.notNull(connectors, "'connectors' must not be null"); - this.additionalTomcatConnectors.addAll(Arrays.asList(connectors)); - } - - /** - * Returns a mutable collection of the {@link Connector}s that will be added to the - * Tomcat. - * @return the additionalTomcatConnectors - */ - public List getAdditionalTomcatConnectors() { - return this.additionalTomcatConnectors; - } - - @Override - public void setUriEncoding(Charset uriEncoding) { - this.uriEncoding = uriEncoding; - } - - /** - * Returns the character encoding to use for URL decoding. - * @return the URI encoding - */ - public Charset getUriEncoding() { - return this.uriEncoding; - } - - @Override - public void setBackgroundProcessorDelay(int delay) { - this.backgroundProcessorDelay = delay; - } - - /** - * Set whether the factory should disable Tomcat's MBean registry prior to creating - * the server. - * @param disableMBeanRegistry whether to disable the MBean registry - * @since 2.2.0 - */ - public void setDisableMBeanRegistry(boolean disableMBeanRegistry) { - this.disableMBeanRegistry = disableMBeanRegistry; - } - - /** - * Whether to use APR. - * @param useApr whether to use APR - * @since 3.4.4 - */ - public void setUseApr(boolean useApr) { - this.useApr = useApr; - } - - /** - * {@link LifecycleListener} to disable persistence in the {@link StandardManager}. A - * {@link LifecycleListener} is used so not to interfere with Tomcat's default manager - * creation logic. - */ - private static final class DisablePersistSessionListener implements LifecycleListener { - - @Override - public void lifecycleEvent(LifecycleEvent event) { - if (event.getType().equals(Lifecycle.START_EVENT)) { - Context context = (Context) event.getLifecycle(); - Manager manager = context.getManager(); - if (manager instanceof StandardManager standardManager) { - standardManager.setPathname(null); - } - } - } - - } - - private final class StaticResourceConfigurer implements LifecycleListener { - - private static final String WEB_APP_MOUNT = "/"; - - private static final String INTERNAL_PATH = "/META-INF/resources"; - - private final Context context; - - private StaticResourceConfigurer(Context context) { - this.context = context; - } - - @Override - public void lifecycleEvent(LifecycleEvent event) { - if (event.getType().equals(Lifecycle.BEFORE_INIT_EVENT)) { - addResourceJars(getUrlsOfJarsWithMetaInfResources()); - } - } - - private void addResourceJars(List resourceJarUrls) { - for (URL url : resourceJarUrls) { - String path = url.getPath(); - if (path.endsWith(".jar") || path.endsWith(".jar!/")) { - String jar = url.toString(); - if (!jar.startsWith("jar:")) { - // A jar file in the file system. Convert to Jar URL. - jar = "jar:" + jar + "!/"; - } - addResourceSet(jar); - } - else { - addResourceSet(url.toString()); - } - } - for (WebResourceSet resources : this.context.getResources().getJarResources()) { - resources.setReadOnly(true); - } - } - - private void addResourceSet(String resource) { - try { - if (isInsideClassicNestedJar(resource)) { - addClassicNestedResourceSet(resource); - return; - } - WebResourceRoot root = this.context.getResources(); - URL url = new URL(resource); - if (isInsideNestedJar(resource)) { - root.addJarResources(new NestedJarResourceSet(url, root, WEB_APP_MOUNT, INTERNAL_PATH)); - } - else { - root.createWebResourceSet(ResourceSetType.RESOURCE_JAR, WEB_APP_MOUNT, url, INTERNAL_PATH); - } - } - catch (Exception ex) { - // Ignore (probably not a directory) - } - } - - private void addClassicNestedResourceSet(String resource) throws MalformedURLException { - // It's a nested jar but we now don't want the suffix because Tomcat - // is going to try and locate it as a root URL (not the resource - // inside it) - URL url = new URL(resource.substring(0, resource.length() - 2)); - this.context.getResources() - .createWebResourceSet(ResourceSetType.RESOURCE_JAR, WEB_APP_MOUNT, url, INTERNAL_PATH); - } - - private boolean isInsideClassicNestedJar(String resource) { - return !isInsideNestedJar(resource) && resource.indexOf("!/") < resource.lastIndexOf("!/"); - } - - private boolean isInsideNestedJar(String resource) { - return resource.startsWith("jar:nested:"); - } - - } - - private static final class LoaderHidingResourceRoot extends StandardRoot { - - private LoaderHidingResourceRoot(TomcatEmbeddedContext context) { - super(context); - } - - @Override - protected WebResourceSet createMainResourceSet() { - return new LoaderHidingWebResourceSet(super.createMainResourceSet()); - } - - } - - private static final class LoaderHidingWebResourceSet extends AbstractResourceSet { - - private final WebResourceSet delegate; - - private final Method initInternal; - - private LoaderHidingWebResourceSet(WebResourceSet delegate) { - this.delegate = delegate; - try { - this.initInternal = LifecycleBase.class.getDeclaredMethod("initInternal"); - this.initInternal.setAccessible(true); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - } - - @Override - public WebResource getResource(String path) { - if (path.startsWith("/org/springframework/boot")) { - return new EmptyResource(getRoot(), path); - } - return this.delegate.getResource(path); - } - - @Override - public String[] list(String path) { - return this.delegate.list(path); - } - - @Override - public Set listWebAppPaths(String path) { - return this.delegate.listWebAppPaths(path) - .stream() - .filter((webAppPath) -> !webAppPath.startsWith("/org/springframework/boot")) - .collect(Collectors.toSet()); - } - - @Override - public boolean mkdir(String path) { - return this.delegate.mkdir(path); - } - - @Override - public boolean write(String path, InputStream is, boolean overwrite) { - return this.delegate.write(path, is, overwrite); - } - - @Override - public URL getBaseUrl() { - return this.delegate.getBaseUrl(); - } - - @Override - public void setReadOnly(boolean readOnly) { - this.delegate.setReadOnly(readOnly); - } - - @Override - public boolean isReadOnly() { - return this.delegate.isReadOnly(); - } - - @Override - public void gc() { - this.delegate.gc(); - } - - @Override - public void setAllowLinking(boolean allowLinking) { - this.delegate.setAllowLinking(allowLinking); - } - - @Override - public boolean getAllowLinking() { - return this.delegate.getAllowLinking(); - } - - @Override - protected void initInternal() throws LifecycleException { - if (this.delegate instanceof LifecycleBase) { - try { - ReflectionUtils.invokeMethod(this.initInternal, this.delegate); - } - catch (Exception ex) { - throw new LifecycleException(ex); - } - } - } - - } - - /** - * {@link Rfc6265CookieProcessor} that supports {@link CookieSameSiteSupplier - * supplied} {@link SameSite} values. - */ - private static class SuppliedSameSiteCookieProcessor extends Rfc6265CookieProcessor { - - private final List suppliers; - - SuppliedSameSiteCookieProcessor(List suppliers) { - this.suppliers = suppliers; - } - - @Override - public String generateHeader(Cookie cookie, HttpServletRequest request) { - SameSite sameSite = getSameSite(cookie); - String sameSiteValue = (sameSite != null) ? sameSite.attributeValue() : null; - if (sameSiteValue == null) { - return super.generateHeader(cookie, request); - } - Rfc6265CookieProcessor delegate = new Rfc6265CookieProcessor(); - delegate.setSameSiteCookies(sameSiteValue); - return delegate.generateHeader(cookie, request); - } - - private SameSite getSameSite(Cookie cookie) { - for (CookieSameSiteSupplier supplier : this.suppliers) { - SameSite sameSite = supplier.getSameSite(cookie); - if (sameSite != null) { - return sameSite; - } - } - return null; - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/package-info.java deleted file mode 100644 index f60d94bb9399..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Embedded reactive and servlet web server implementations backed by Tomcat. - * - * @see org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory - * @see org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory - */ -package org.springframework.boot.web.embedded.tomcat; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactory.java deleted file mode 100644 index 8855f6064e6e..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactory.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.undertow; - -import java.io.File; -import java.util.Collection; -import java.util.List; - -import io.undertow.Undertow; - -import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.server.WebServer; -import org.springframework.http.server.reactive.UndertowHttpHandlerAdapter; - -/** - * {@link ReactiveWebServerFactory} that can be used to create {@link UndertowWebServer}s. - * - * @author Brian Clozel - * @author Scott Frederick - * @since 2.0.0 - */ -public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerFactory - implements ConfigurableUndertowWebServerFactory { - - private final UndertowWebServerFactoryDelegate delegate = new UndertowWebServerFactoryDelegate(); - - /** - * Create a new {@link UndertowReactiveWebServerFactory} instance. - */ - public UndertowReactiveWebServerFactory() { - } - - /** - * Create a new {@link UndertowReactiveWebServerFactory} that listens for requests - * using the specified port. - * @param port the port to listen on - */ - public UndertowReactiveWebServerFactory(int port) { - super(port); - } - - @Override - public void setBuilderCustomizers(Collection customizers) { - this.delegate.setBuilderCustomizers(customizers); - } - - @Override - public void addBuilderCustomizers(UndertowBuilderCustomizer... customizers) { - this.delegate.addBuilderCustomizers(customizers); - } - - /** - * Returns a mutable collection of the {@link UndertowBuilderCustomizer}s that will be - * applied to the Undertow {@link io.undertow.Undertow.Builder Builder}. - * @return the customizers that will be applied - */ - public Collection getBuilderCustomizers() { - return this.delegate.getBuilderCustomizers(); - } - - @Override - public void setBufferSize(Integer bufferSize) { - this.delegate.setBufferSize(bufferSize); - } - - @Override - public void setIoThreads(Integer ioThreads) { - this.delegate.setIoThreads(ioThreads); - } - - @Override - public void setWorkerThreads(Integer workerThreads) { - this.delegate.setWorkerThreads(workerThreads); - } - - @Override - public void setUseDirectBuffers(Boolean directBuffers) { - this.delegate.setUseDirectBuffers(directBuffers); - } - - @Override - public void setUseForwardHeaders(boolean useForwardHeaders) { - this.delegate.setUseForwardHeaders(useForwardHeaders); - } - - protected final boolean isUseForwardHeaders() { - return this.delegate.isUseForwardHeaders(); - } - - @Override - public void setAccessLogDirectory(File accessLogDirectory) { - this.delegate.setAccessLogDirectory(accessLogDirectory); - } - - @Override - public void setAccessLogPattern(String accessLogPattern) { - this.delegate.setAccessLogPattern(accessLogPattern); - } - - /** - * Returns the access log prefix. - * @return the access log prefix - * @since 3.5.0 - */ - public String getAccessLogPrefix() { - return this.delegate.getAccessLogPrefix(); - } - - @Override - public void setAccessLogPrefix(String accessLogPrefix) { - this.delegate.setAccessLogPrefix(accessLogPrefix); - } - - @Override - public void setAccessLogSuffix(String accessLogSuffix) { - this.delegate.setAccessLogSuffix(accessLogSuffix); - } - - public boolean isAccessLogEnabled() { - return this.delegate.isAccessLogEnabled(); - } - - @Override - public void setAccessLogEnabled(boolean accessLogEnabled) { - this.delegate.setAccessLogEnabled(accessLogEnabled); - } - - @Override - public void setAccessLogRotate(boolean accessLogRotate) { - this.delegate.setAccessLogRotate(accessLogRotate); - } - - @Override - public WebServer getWebServer(org.springframework.http.server.reactive.HttpHandler httpHandler) { - Undertow.Builder builder = this.delegate.createBuilder(this, this::getSslBundle, this::getServerNameSslBundles); - List httpHandlerFactories = this.delegate.createHttpHandlerFactories(this, - (next) -> new UndertowHttpHandlerAdapter(httpHandler)); - return new UndertowWebServer(builder, httpHandlerFactories, getPort() >= 0); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java deleted file mode 100644 index 5f6fc0ea8358..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.embedded.undertow; - -import java.io.File; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Supplier; - -import io.undertow.Handlers; -import io.undertow.Undertow; -import io.undertow.Undertow.Builder; -import io.undertow.UndertowOptions; - -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; -import org.springframework.boot.web.server.Compression; -import org.springframework.boot.web.server.Http2; -import org.springframework.boot.web.server.Shutdown; -import org.springframework.boot.web.server.Ssl; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Delegate class used by {@link UndertowServletWebServerFactory} and - * {@link UndertowReactiveWebServerFactory}. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @author Scott Frederick - */ -class UndertowWebServerFactoryDelegate { - - private Set builderCustomizers = new LinkedHashSet<>(); - - private Integer bufferSize; - - private Integer ioThreads; - - private Integer workerThreads; - - private Boolean directBuffers; - - private File accessLogDirectory; - - private String accessLogPattern; - - private String accessLogPrefix; - - private String accessLogSuffix; - - private boolean accessLogEnabled; - - private boolean accessLogRotate = true; - - private boolean useForwardHeaders; - - void setBuilderCustomizers(Collection customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.builderCustomizers = new LinkedHashSet<>(customizers); - } - - void addBuilderCustomizers(UndertowBuilderCustomizer... customizers) { - Assert.notNull(customizers, "'customizers' must not be null"); - this.builderCustomizers.addAll(Arrays.asList(customizers)); - } - - Collection getBuilderCustomizers() { - return this.builderCustomizers; - } - - void setBufferSize(Integer bufferSize) { - this.bufferSize = bufferSize; - } - - void setIoThreads(Integer ioThreads) { - this.ioThreads = ioThreads; - } - - void setWorkerThreads(Integer workerThreads) { - this.workerThreads = workerThreads; - } - - void setUseDirectBuffers(Boolean directBuffers) { - this.directBuffers = directBuffers; - } - - void setAccessLogDirectory(File accessLogDirectory) { - this.accessLogDirectory = accessLogDirectory; - } - - void setAccessLogPattern(String accessLogPattern) { - this.accessLogPattern = accessLogPattern; - } - - void setAccessLogPrefix(String accessLogPrefix) { - this.accessLogPrefix = accessLogPrefix; - } - - String getAccessLogPrefix() { - return this.accessLogPrefix; - } - - void setAccessLogSuffix(String accessLogSuffix) { - this.accessLogSuffix = accessLogSuffix; - } - - void setAccessLogEnabled(boolean accessLogEnabled) { - this.accessLogEnabled = accessLogEnabled; - } - - boolean isAccessLogEnabled() { - return this.accessLogEnabled; - } - - void setAccessLogRotate(boolean accessLogRotate) { - this.accessLogRotate = accessLogRotate; - } - - void setUseForwardHeaders(boolean useForwardHeaders) { - this.useForwardHeaders = useForwardHeaders; - } - - boolean isUseForwardHeaders() { - return this.useForwardHeaders; - } - - Builder createBuilder(AbstractConfigurableWebServerFactory factory, Supplier sslBundleSupplier, - Supplier> serverNameSslBundlesSupplier) { - InetAddress address = factory.getAddress(); - int port = factory.getPort(); - Builder builder = Undertow.builder(); - if (this.bufferSize != null) { - builder.setBufferSize(this.bufferSize); - } - if (this.ioThreads != null) { - builder.setIoThreads(this.ioThreads); - } - if (this.workerThreads != null) { - builder.setWorkerThreads(this.workerThreads); - } - if (this.directBuffers != null) { - builder.setDirectBuffers(this.directBuffers); - } - Http2 http2 = factory.getHttp2(); - if (http2 != null) { - builder.setServerOption(UndertowOptions.ENABLE_HTTP2, http2.isEnabled()); - } - Ssl ssl = factory.getSsl(); - if (Ssl.isEnabled(ssl)) { - new SslBuilderCustomizer(factory.getPort(), address, ssl.getClientAuth(), sslBundleSupplier.get(), - serverNameSslBundlesSupplier.get()) - .customize(builder); - } - else { - builder.addHttpListener(port, (address != null) ? address.getHostAddress() : "0.0.0.0"); - } - builder.setServerOption(UndertowOptions.SHUTDOWN_TIMEOUT, 0); - for (UndertowBuilderCustomizer customizer : this.builderCustomizers) { - customizer.customize(builder); - } - return builder; - } - - List createHttpHandlerFactories(AbstractConfigurableWebServerFactory webServerFactory, - HttpHandlerFactory... initialHttpHandlerFactories) { - List factories = createHttpHandlerFactories(webServerFactory.getCompression(), - this.useForwardHeaders, webServerFactory.getServerHeader(), webServerFactory.getShutdown(), - initialHttpHandlerFactories); - if (isAccessLogEnabled()) { - factories.add(new AccessLogHttpHandlerFactory(this.accessLogDirectory, this.accessLogPattern, - this.accessLogPrefix, this.accessLogSuffix, this.accessLogRotate)); - } - return factories; - } - - static List createHttpHandlerFactories(Compression compression, boolean useForwardHeaders, - String serverHeader, Shutdown shutdown, HttpHandlerFactory... initialHttpHandlerFactories) { - List factories = new ArrayList<>(Arrays.asList(initialHttpHandlerFactories)); - if (compression != null && compression.getEnabled()) { - factories.add(new CompressionHttpHandlerFactory(compression)); - } - if (useForwardHeaders) { - factories.add(Handlers::proxyPeerAddress); - } - if (StringUtils.hasText(serverHeader)) { - factories.add((next) -> Handlers.header(next, "Server", serverHeader)); - } - if (shutdown == Shutdown.GRACEFUL) { - factories.add(Handlers::gracefulShutdown); - } - return factories; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/package-info.java deleted file mode 100644 index 2d048977db20..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Embedded reactive and servlet web server implementations backed by Undertow. - * - * @see org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory - * @see org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory - */ -package org.springframework.boot.web.embedded.undertow; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPage.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPage.java similarity index 98% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPage.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPage.java index 6c461656135c..d71f213e543c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPage.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPage.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server; +package org.springframework.boot.web.error; import org.springframework.http.HttpStatus; import org.springframework.util.ObjectUtils; @@ -24,7 +24,7 @@ * {@literal <error-page>} element traditionally found in web.xml. * * @author Dave Syer - * @since 2.0.0 + * @since 4.0.0 */ public class ErrorPage { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistrar.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistrar.java similarity index 94% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistrar.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistrar.java index 1d8b0fe632f3..3366d711d5f1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistrar.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistrar.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.web.server; +package org.springframework.boot.web.error; /** * Interface to be implemented by types that register {@link ErrorPage ErrorPages}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface ErrorPageRegistrar { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistrarBeanPostProcessor.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistrarBeanPostProcessor.java similarity index 97% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistrarBeanPostProcessor.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistrarBeanPostProcessor.java index d26d2cdb242c..cc2708902862 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistrarBeanPostProcessor.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistrarBeanPostProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server; +package org.springframework.boot.web.error; import java.util.ArrayList; import java.util.Collection; @@ -35,7 +35,7 @@ * * @author Phillip Webb * @author Stephane Nicoll - * @since 2.0.0 + * @since 4.0.0 */ public class ErrorPageRegistrarBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistry.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistry.java similarity index 93% rename from spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistry.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistry.java index c885b257031c..77bcb36190ba 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/ErrorPageRegistry.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorPageRegistry.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.web.server; +package org.springframework.boot.web.error; /** * Interface for a registry that holds {@link ErrorPage ErrorPages}. * * @author Phillip Webb - * @since 2.0.0 + * @since 4.0.0 */ @FunctionalInterface public interface ErrorPageRegistry { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/WebServerStartStopLifecycle.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/WebServerStartStopLifecycle.java deleted file mode 100644 index 113d3eaa4ef8..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/WebServerStartStopLifecycle.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.context; - -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.boot.web.server.WebServer; -import org.springframework.context.SmartLifecycle; - -/** - * {@link SmartLifecycle} to start and stop the {@link WebServer} in a - * {@link ReactiveWebServerApplicationContext}. - * - * @author Andy Wilkinson - */ -class WebServerStartStopLifecycle implements SmartLifecycle { - - private final WebServerManager weServerManager; - - private volatile boolean running; - - WebServerStartStopLifecycle(WebServerManager weServerManager) { - this.weServerManager = weServerManager; - } - - @Override - public void start() { - this.weServerManager.start(); - this.running = true; - } - - @Override - public void stop() { - this.running = false; - this.weServerManager.stop(); - } - - @Override - public boolean isRunning() { - return this.running; - } - - @Override - public int getPhase() { - return WebServerApplicationContext.START_STOP_LIFECYCLE_PHASE; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/package-info.java deleted file mode 100644 index 49b68096407a..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Reactive based web integrations with Spring's - * {@link org.springframework.context.ApplicationContext ApplicationContext}. - */ -package org.springframework.boot.web.reactive.context; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java deleted file mode 100644 index 535bb6cd1210..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.error; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; - -import org.springframework.boot.web.error.Error; -import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; -import org.springframework.http.HttpStatus; -import org.springframework.util.StringUtils; -import org.springframework.validation.BindingResult; -import org.springframework.validation.method.MethodValidationResult; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.server.ResponseStatusException; -import org.springframework.web.server.ServerWebExchange; - -/** - * Default implementation of {@link ErrorAttributes}. Provides the following attributes - * when possible: - *

      - *
    • timestamp - The time that the errors were extracted
    • - *
    • status - The status code
    • - *
    • error - The error reason
    • - *
    • exception - The class name of the root exception (if configured)
    • - *
    • message - The exception message (if configured)
    • - *
    • errors - Any validation errors wrapped in {@link Error}, derived from a - * {@link BindingResult} or {@link MethodValidationResult} exception (if configured)
    • - *
    • trace - The exception stack trace (if configured)
    • - *
    • path - The URL path when the exception was raised
    • - *
    • requestId - Unique ID associated with the current request
    • - *
    - * - * @author Brian Clozel - * @author Stephane Nicoll - * @author Michele Mancioppi - * @author Scott Frederick - * @author Moritz Halbritter - * @author Yanming Zhou - * @author Yongjun Hong - * @since 2.0.0 - * @see ErrorAttributes - */ -public class DefaultErrorAttributes implements ErrorAttributes { - - private static final String ERROR_INTERNAL_ATTRIBUTE = DefaultErrorAttributes.class.getName() + ".ERROR"; - - @Override - public Map getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { - Map errorAttributes = getErrorAttributes(request, options.isIncluded(Include.STACK_TRACE)); - options.retainIncluded(errorAttributes); - return errorAttributes; - } - - private Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) { - Map errorAttributes = new LinkedHashMap<>(); - errorAttributes.put("timestamp", new Date()); - errorAttributes.put("path", request.requestPath().value()); - Throwable error = getError(request); - MergedAnnotation responseStatusAnnotation = MergedAnnotations - .from(error.getClass(), SearchStrategy.TYPE_HIERARCHY) - .get(ResponseStatus.class); - HttpStatus errorStatus = determineHttpStatus(error, responseStatusAnnotation); - errorAttributes.put("status", errorStatus.value()); - errorAttributes.put("error", errorStatus.getReasonPhrase()); - errorAttributes.put("requestId", request.exchange().getRequest().getId()); - handleException(errorAttributes, error, responseStatusAnnotation, includeStackTrace); - return errorAttributes; - } - - private HttpStatus determineHttpStatus(Throwable error, MergedAnnotation responseStatusAnnotation) { - if (error instanceof ResponseStatusException responseStatusException) { - HttpStatus httpStatus = HttpStatus.resolve(responseStatusException.getStatusCode().value()); - if (httpStatus != null) { - return httpStatus; - } - } - return responseStatusAnnotation.getValue("code", HttpStatus.class).orElse(HttpStatus.INTERNAL_SERVER_ERROR); - } - - private void addStackTrace(Map errorAttributes, Throwable error) { - StringWriter stackTrace = new StringWriter(); - error.printStackTrace(new PrintWriter(stackTrace)); - stackTrace.flush(); - errorAttributes.put("trace", stackTrace.toString()); - } - - private void handleException(Map errorAttributes, Throwable error, - MergedAnnotation responseStatusAnnotation, boolean includeStackTrace) { - Throwable exception; - if (error instanceof BindingResult bindingResult) { - exception = error; - errorAttributes.put("message", error.getMessage()); - errorAttributes.put("errors", Error.wrap(bindingResult.getAllErrors())); - } - else if (error instanceof MethodValidationResult methodValidationResult) { - exception = error; - errorAttributes.put("message", getErrorMessage(methodValidationResult)); - errorAttributes.put("errors", Error.wrap(methodValidationResult.getAllErrors())); - } - else if (error instanceof ResponseStatusException responseStatusException) { - exception = (responseStatusException.getCause() != null) ? responseStatusException.getCause() : error; - errorAttributes.put("message", responseStatusException.getReason()); - if (exception instanceof BindingResult bindingResult) { - errorAttributes.put("errors", Error.wrap(bindingResult.getAllErrors())); - } - } - else { - exception = error; - String reason = responseStatusAnnotation.getValue("reason", String.class).orElse(""); - String message = StringUtils.hasText(reason) ? reason : error.getMessage(); - errorAttributes.put("message", (message != null) ? message : ""); - } - errorAttributes.put("exception", exception.getClass().getName()); - if (includeStackTrace) { - addStackTrace(errorAttributes, exception); - } - } - - private String getErrorMessage(MethodValidationResult methodValidationResult) { - return "Validation failed for method='%s'. Error count: %s".formatted(methodValidationResult.getMethod(), - methodValidationResult.getAllErrors().size()); - } - - @Override - public Throwable getError(ServerRequest request) { - Optional error = request.attribute(ERROR_INTERNAL_ATTRIBUTE); - return (Throwable) error - .orElseThrow(() -> new IllegalStateException("Missing exception attribute in ServerWebExchange")); - } - - @Override - public void storeErrorInformation(Throwable error, ServerWebExchange exchange) { - exchange.getAttributes().putIfAbsent(ERROR_INTERNAL_ATTRIBUTE, error); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorAttributes.java deleted file mode 100644 index c66be8425556..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/ErrorAttributes.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.error; - -import java.util.Collections; -import java.util.Map; - -import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ServerWebExchange; - -/** - * Provides access to error attributes which can be logged or presented to the user. - * - * @author Brian Clozel - * @author Scott Frederick - * @since 2.0.0 - * @see DefaultErrorAttributes - */ -public interface ErrorAttributes { - - /** - * Return a {@link Map} of the error attributes. The map can be used as the model of - * an error page, or returned as a {@link ServerResponse} body. - * @param request the source request - * @param options options for error attribute contents - * @return a map of error attributes - */ - default Map getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { - return Collections.emptyMap(); - } - - /** - * Return the underlying cause of the error or {@code null} if the error cannot be - * extracted. - * @param request the source ServerRequest - * @return the {@link Exception} that caused the error or {@code null} - */ - Throwable getError(ServerRequest request); - - /** - * Store the given error information in the current {@link ServerWebExchange}. - * @param error the {@link Exception} that caused the error - * @param exchange the source exchange - */ - void storeErrorInformation(Throwable error, ServerWebExchange exchange); - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/package-info.java deleted file mode 100644 index 545f6adef4c9..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring WebFlux error handling infrastructure. - */ -package org.springframework.boot.web.reactive.error; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedHiddenHttpMethodFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedHiddenHttpMethodFilter.java deleted file mode 100644 index 99e94faebc1d..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/OrderedHiddenHttpMethodFilter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.filter; - -import org.springframework.core.Ordered; -import org.springframework.web.filter.reactive.HiddenHttpMethodFilter; - -/** - * {@link HiddenHttpMethodFilter} that also implements {@link Ordered}. - * - * @author Artsiom Yudovin - * @since 2.0.5 - */ -public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter implements OrderedWebFilter { - - /** - * The default order is high to ensure the filter is applied before Spring Security. - */ - public static final int DEFAULT_ORDER = REQUEST_WRAPPER_FILTER_MAX_ORDER - 10000; - - private int order = DEFAULT_ORDER; - - @Override - public int getOrder() { - return this.order; - } - - /** - * Set the order for this filter. - * @param order the order to set - */ - public void setOrder(int order) { - this.order = order; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/package-info.java deleted file mode 100644 index 02ed782e9856..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/filter/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring Boot specific {@link org.springframework.web.server.WebFilter} implementations. - */ -package org.springframework.boot.web.reactive.filter; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/function/client/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/function/client/package-info.java deleted file mode 100644 index 2a128ec2efac..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/function/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring WebFlux WebClient support abstractions. - */ -package org.springframework.boot.web.reactive.function.client; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/MustacheView.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/MustacheView.java deleted file mode 100644 index 8d9ad74324e0..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/MustacheView.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.result.view; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; -import java.nio.charset.Charset; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; - -import com.samskivert.mustache.Mustache.Compiler; -import com.samskivert.mustache.Template; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.core.io.Resource; -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.core.io.buffer.DataBufferUtils; -import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.http.MediaType; -import org.springframework.web.reactive.result.view.AbstractUrlBasedView; -import org.springframework.web.reactive.result.view.View; -import org.springframework.web.server.ServerWebExchange; - -/** - * Spring WebFlux {@link View} using the Mustache template engine. - * - * @author Brian Clozel - * @since 2.0.0 - */ -public class MustacheView extends AbstractUrlBasedView { - - private Compiler compiler; - - private String charset; - - /** - * Set the JMustache compiler to be used by this view. Typically this property is not - * set directly. Instead a single {@link Compiler} is expected in the Spring - * application context which is used to compile Mustache templates. - * @param compiler the Mustache compiler - */ - public void setCompiler(Compiler compiler) { - this.compiler = compiler; - } - - /** - * Set the charset used for reading Mustache template files. - * @param charset the charset to use for reading template files - */ - public void setCharset(String charset) { - this.charset = charset; - } - - @Override - public boolean checkResourceExists(Locale locale) throws Exception { - return resolveResource() != null; - } - - @Override - protected Mono renderInternal(Map model, MediaType contentType, ServerWebExchange exchange) { - Resource resource = resolveResource(); - if (resource == null) { - return Mono - .error(new IllegalStateException("Could not find Mustache template with URL [" + getUrl() + "]")); - } - DataBuffer dataBuffer = exchange.getResponse() - .bufferFactory() - .allocateBuffer(DefaultDataBufferFactory.DEFAULT_INITIAL_CAPACITY); - try (Reader reader = getReader(resource)) { - Template template = this.compiler.compile(reader); - Charset charset = getCharset(contentType).orElseGet(this::getDefaultCharset); - try (Writer writer = new OutputStreamWriter(dataBuffer.asOutputStream(), charset)) { - template.execute(model, writer); - writer.flush(); - } - } - catch (Exception ex) { - DataBufferUtils.release(dataBuffer); - return Mono.error(ex); - } - return exchange.getResponse().writeWith(Flux.just(dataBuffer)); - } - - private Resource resolveResource() { - Resource resource = getApplicationContext().getResource(getUrl()); - if (resource == null || !resource.exists()) { - return null; - } - return resource; - } - - private Reader getReader(Resource resource) throws IOException { - if (this.charset != null) { - return new InputStreamReader(resource.getInputStream(), this.charset); - } - return new InputStreamReader(resource.getInputStream()); - } - - private Optional getCharset(MediaType mediaType) { - return Optional.ofNullable((mediaType != null) ? mediaType.getCharset() : null); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/MustacheViewResolver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/MustacheViewResolver.java deleted file mode 100644 index 86651d97145f..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/MustacheViewResolver.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.result.view; - -import com.samskivert.mustache.Mustache; -import com.samskivert.mustache.Mustache.Compiler; - -import org.springframework.web.reactive.result.view.AbstractUrlBasedView; -import org.springframework.web.reactive.result.view.UrlBasedViewResolver; -import org.springframework.web.reactive.result.view.ViewResolver; - -/** - * Spring WebFlux {@link ViewResolver} for Mustache. - * - * @author Brian Clozel - * @author Marten Deinum - * @since 2.0.0 - */ -public class MustacheViewResolver extends UrlBasedViewResolver { - - private final Compiler compiler; - - private String charset; - - /** - * Create a {@code MustacheViewResolver} backed by a default instance of a - * {@link Compiler}. - */ - public MustacheViewResolver() { - this.compiler = Mustache.compiler(); - setViewClass(requiredViewClass()); - } - - /** - * Create a {@code MustacheViewResolver} backed by a custom instance of a - * {@link Compiler}. - * @param compiler the Mustache compiler used to compile templates - */ - public MustacheViewResolver(Compiler compiler) { - this.compiler = compiler; - setViewClass(requiredViewClass()); - } - - /** - * Set the charset. - * @param charset the charset - */ - public void setCharset(String charset) { - this.charset = charset; - } - - @Override - protected Class requiredViewClass() { - return MustacheView.class; - } - - @Override - protected AbstractUrlBasedView createView(String viewName) { - MustacheView view = (MustacheView) super.createView(viewName); - view.setCompiler(this.compiler); - view.setCharset(this.charset); - return view; - } - - @Override - protected AbstractUrlBasedView instantiateView() { - return (getViewClass() == MustacheView.class) ? new MustacheView() : super.instantiateView(); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/package-info.java deleted file mode 100644 index d38ab43f14ae..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/result/view/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Additional {@link org.springframework.web.reactive.result.view.View Views} for use with - * WebFlux. - */ -package org.springframework.boot.web.reactive.result.view; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/package-info.java deleted file mode 100644 index cac9fd6c6932..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Reactive web server abstractions. - */ -package org.springframework.boot.web.reactive.server; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializer.java index 09b4956b6280..998536a3236f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializer.java @@ -37,7 +37,7 @@ * For configuration examples see {@link WebApplicationInitializer}. * * @author Phillip Webb - * @since 1.4.0 + * @since 4.0.0 * @see WebApplicationInitializer */ @FunctionalInterface diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/WebServerStartStopLifecycle.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/WebServerStartStopLifecycle.java deleted file mode 100644 index a1267f4ad829..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/WebServerStartStopLifecycle.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.context; - -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.boot.web.server.WebServer; -import org.springframework.context.SmartLifecycle; - -/** - * {@link SmartLifecycle} to start and stop the {@link WebServer} in a - * {@link ServletWebServerApplicationContext}. - * - * @author Andy Wilkinson - */ -class WebServerStartStopLifecycle implements SmartLifecycle { - - private final ServletWebServerApplicationContext applicationContext; - - private final WebServer webServer; - - private volatile boolean running; - - WebServerStartStopLifecycle(ServletWebServerApplicationContext applicationContext, WebServer webServer) { - this.applicationContext = applicationContext; - this.webServer = webServer; - } - - @Override - public void start() { - this.webServer.start(); - this.running = true; - this.applicationContext - .publishEvent(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext)); - } - - @Override - public void stop() { - this.running = false; - this.webServer.stop(); - } - - @Override - public boolean isRunning() { - return this.running; - } - - @Override - public int getPhase() { - return WebServerApplicationContext.START_STOP_LIFECYCLE_PHASE; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/package-info.java deleted file mode 100644 index 31265a4af90c..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Servlet based web integrations with Spring's - * {@link org.springframework.web.context.WebApplicationContext WebApplicationContext}. - */ -package org.springframework.boot.web.servlet.context; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributes.java deleted file mode 100644 index 0caa59cf26da..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributes.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.error; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; - -import jakarta.servlet.RequestDispatcher; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import org.springframework.boot.web.error.Error; -import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpStatus; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; -import org.springframework.validation.BindingResult; -import org.springframework.validation.method.MethodValidationResult; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.WebRequest; -import org.springframework.web.servlet.HandlerExceptionResolver; -import org.springframework.web.servlet.ModelAndView; - -/** - * Default implementation of {@link ErrorAttributes}. Provides the following attributes - * when possible: - *
      - *
    • timestamp - The time that the errors were extracted
    • - *
    • status - The status code
    • - *
    • error - The error reason
    • - *
    • exception - The class name of the root exception (if configured)
    • - *
    • message - The exception message (if configured)
    • - *
    • errors - Any validation errors wrapped in {@link Error}, derived from a - * {@link BindingResult} or {@link MethodValidationResult} exception (if configured)
    • - *
    • trace - The exception stack trace (if configured)
    • - *
    • path - The URL path when the exception was raised
    • - *
    - * - * @author Phillip Webb - * @author Dave Syer - * @author Stephane Nicoll - * @author Vedran Pavic - * @author Scott Frederick - * @author Moritz Halbritter - * @author Yanming Zhou - * @author Yongjun Hong - * @since 2.0.0 - * @see ErrorAttributes - */ -@Order(Ordered.HIGHEST_PRECEDENCE) -public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered { - - private static final String ERROR_INTERNAL_ATTRIBUTE = DefaultErrorAttributes.class.getName() + ".ERROR"; - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } - - @Override - public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, - Exception ex) { - storeErrorAttributes(request, ex); - return null; - } - - private void storeErrorAttributes(HttpServletRequest request, Exception ex) { - request.setAttribute(ERROR_INTERNAL_ATTRIBUTE, ex); - } - - @Override - public Map getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { - Map errorAttributes = getErrorAttributes(webRequest, options.isIncluded(Include.STACK_TRACE)); - options.retainIncluded(errorAttributes); - return errorAttributes; - } - - private Map getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { - Map errorAttributes = new LinkedHashMap<>(); - errorAttributes.put("timestamp", new Date()); - addStatus(errorAttributes, webRequest); - addErrorDetails(errorAttributes, webRequest, includeStackTrace); - addPath(errorAttributes, webRequest); - return errorAttributes; - } - - private void addStatus(Map errorAttributes, RequestAttributes requestAttributes) { - Integer status = getAttribute(requestAttributes, RequestDispatcher.ERROR_STATUS_CODE); - if (status == null) { - errorAttributes.put("status", 999); - errorAttributes.put("error", "None"); - return; - } - errorAttributes.put("status", status); - try { - errorAttributes.put("error", HttpStatus.valueOf(status).getReasonPhrase()); - } - catch (Exception ex) { - // Unable to obtain a reason - errorAttributes.put("error", "Http Status " + status); - } - } - - private void addErrorDetails(Map errorAttributes, WebRequest webRequest, - boolean includeStackTrace) { - Throwable error = getError(webRequest); - if (error != null) { - while (error instanceof ServletException && error.getCause() != null) { - error = error.getCause(); - } - errorAttributes.put("exception", error.getClass().getName()); - if (includeStackTrace) { - addStackTrace(errorAttributes, error); - } - } - addErrorMessage(errorAttributes, webRequest, error); - } - - private void addErrorMessage(Map errorAttributes, WebRequest webRequest, Throwable error) { - BindingResult bindingResult = extractBindingResult(error); - if (bindingResult != null) { - addMessageAndErrorsFromBindingResult(errorAttributes, bindingResult); - return; - } - MethodValidationResult methodValidationResult = extractMethodValidationResult(error); - if (methodValidationResult != null) { - addMessageAndErrorsFromMethodValidationResult(errorAttributes, methodValidationResult); - return; - } - addExceptionErrorMessage(errorAttributes, webRequest, error); - } - - private void addMessageAndErrorsFromBindingResult(Map errorAttributes, BindingResult result) { - errorAttributes.put("message", "Validation failed for object='%s'. Error count: %s" - .formatted(result.getObjectName(), result.getAllErrors().size())); - errorAttributes.put("errors", Error.wrap(result.getAllErrors())); - } - - private void addMessageAndErrorsFromMethodValidationResult(Map errorAttributes, - MethodValidationResult result) { - errorAttributes.put("message", "Validation failed for method='%s'. Error count: %s" - .formatted(result.getMethod(), result.getAllErrors().size())); - errorAttributes.put("errors", Error.wrap(result.getAllErrors())); - } - - private void addExceptionErrorMessage(Map errorAttributes, WebRequest webRequest, Throwable error) { - errorAttributes.put("message", getMessage(webRequest, error)); - } - - /** - * Returns the message to be included as the value of the {@code message} error - * attribute. By default the returned message is the first of the following that is - * not empty: - *
      - *
    1. Value of the {@link RequestDispatcher#ERROR_MESSAGE} request attribute. - *
    2. Message of the given {@code error}. - *
    3. {@code No message available}. - *
    - * @param webRequest current request - * @param error current error, if any - * @return message to include in the error attributes - * @since 2.4.0 - */ - protected String getMessage(WebRequest webRequest, Throwable error) { - Object message = getAttribute(webRequest, RequestDispatcher.ERROR_MESSAGE); - if (!ObjectUtils.isEmpty(message)) { - return message.toString(); - } - if (error != null && StringUtils.hasLength(error.getMessage())) { - return error.getMessage(); - } - return "No message available"; - } - - private BindingResult extractBindingResult(Throwable error) { - if (error instanceof BindingResult bindingResult) { - return bindingResult; - } - return null; - } - - private MethodValidationResult extractMethodValidationResult(Throwable error) { - if (error instanceof MethodValidationResult methodValidationResult) { - return methodValidationResult; - } - return null; - } - - private void addStackTrace(Map errorAttributes, Throwable error) { - StringWriter stackTrace = new StringWriter(); - error.printStackTrace(new PrintWriter(stackTrace)); - stackTrace.flush(); - errorAttributes.put("trace", stackTrace.toString()); - } - - private void addPath(Map errorAttributes, RequestAttributes requestAttributes) { - String path = getAttribute(requestAttributes, RequestDispatcher.ERROR_REQUEST_URI); - if (path != null) { - errorAttributes.put("path", path); - } - } - - @Override - public Throwable getError(WebRequest webRequest) { - Throwable exception = getAttribute(webRequest, ERROR_INTERNAL_ATTRIBUTE); - if (exception == null) { - exception = getAttribute(webRequest, RequestDispatcher.ERROR_EXCEPTION); - } - return exception; - } - - @SuppressWarnings("unchecked") - private T getAttribute(RequestAttributes requestAttributes, String name) { - return (T) requestAttributes.getAttribute(name, RequestAttributes.SCOPE_REQUEST); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorAttributes.java deleted file mode 100644 index 402560585896..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/ErrorAttributes.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.error; - -import java.util.Collections; -import java.util.Map; - -import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.context.request.WebRequest; -import org.springframework.web.servlet.ModelAndView; - -/** - * Provides access to error attributes which can be logged or presented to the user. - * - * @author Phillip Webb - * @author Scott Frederick - * @since 2.0.0 - * @see DefaultErrorAttributes - */ -public interface ErrorAttributes { - - /** - * Returns a {@link Map} of the error attributes. The map can be used as the model of - * an error page {@link ModelAndView}, or returned as a - * {@link ResponseBody @ResponseBody}. - * @param webRequest the source request - * @param options options for error attribute contents - * @return a map of error attributes - * @since 2.3.0 - */ - default Map getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { - return Collections.emptyMap(); - } - - /** - * Return the underlying cause of the error or {@code null} if the error cannot be - * extracted. - * @param webRequest the source request - * @return the {@link Exception} that caused the error or {@code null} - */ - Throwable getError(WebRequest webRequest); - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/package-info.java deleted file mode 100644 index 0d3c4adccbc3..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/error/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring MVC error handling infrastructure. - */ -package org.springframework.boot.web.servlet.error; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedHiddenHttpMethodFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedHiddenHttpMethodFilter.java deleted file mode 100644 index 428c816a01ff..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/OrderedHiddenHttpMethodFilter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.filter; - -import org.springframework.core.Ordered; -import org.springframework.web.filter.HiddenHttpMethodFilter; - -/** - * {@link HiddenHttpMethodFilter} that also implements {@link Ordered}. - * - * @author Phillip Webb - * @since 2.0.0 - */ -public class OrderedHiddenHttpMethodFilter extends HiddenHttpMethodFilter implements OrderedFilter { - - /** - * The default order is high to ensure the filter is applied before Spring Security. - */ - public static final int DEFAULT_ORDER = REQUEST_WRAPPER_FILTER_MAX_ORDER - 10000; - - private int order = DEFAULT_ORDER; - - @Override - public int getOrder() { - return this.order; - } - - /** - * Set the order for this filter. - * @param order the order to set - */ - public void setOrder(int order) { - this.order = order; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/package-info.java deleted file mode 100644 index a6059020d89e..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/filter/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Spring Boot specific {@link jakarta.servlet.Filter} implementations. - */ -package org.springframework.boot.web.servlet.filter; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactory.java deleted file mode 100644 index a0e7fc7308c8..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactory.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.server; - -import java.io.File; -import java.net.URL; -import java.nio.charset.Charset; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.SessionCookieConfig; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; -import org.springframework.boot.web.server.Cookie; -import org.springframework.boot.web.server.MimeMappings; -import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Abstract base class for {@link ConfigurableServletWebServerFactory} implementations. - * - * @author Phillip Webb - * @author Dave Syer - * @author Andy Wilkinson - * @author Stephane Nicoll - * @author Ivan Sopov - * @author Eddú Meléndez - * @author Brian Clozel - * @since 2.0.0 - */ -public abstract class AbstractServletWebServerFactory extends AbstractConfigurableWebServerFactory - implements ConfigurableServletWebServerFactory { - - protected final Log logger = LogFactory.getLog(getClass()); - - private String contextPath = ""; - - private String displayName; - - private Session session = new Session(); - - private boolean registerDefaultServlet; - - private MimeMappings mimeMappings = MimeMappings.lazyCopy(MimeMappings.DEFAULT); - - private List initializers = new ArrayList<>(); - - private Jsp jsp = new Jsp(); - - private Map localeCharsetMappings = new HashMap<>(); - - private Map initParameters = Collections.emptyMap(); - - private List cookieSameSiteSuppliers = new ArrayList<>(); - - private final DocumentRoot documentRoot = new DocumentRoot(this.logger); - - private final StaticResourceJars staticResourceJars = new StaticResourceJars(); - - private final Set webListenerClassNames = new HashSet<>(); - - /** - * Create a new {@link AbstractServletWebServerFactory} instance. - */ - public AbstractServletWebServerFactory() { - } - - /** - * Create a new {@link AbstractServletWebServerFactory} instance with the specified - * port. - * @param port the port number for the web server - */ - public AbstractServletWebServerFactory(int port) { - super(port); - } - - /** - * Create a new {@link AbstractServletWebServerFactory} instance with the specified - * context path and port. - * @param contextPath the context path for the web server - * @param port the port number for the web server - */ - public AbstractServletWebServerFactory(String contextPath, int port) { - super(port); - checkContextPath(contextPath); - this.contextPath = contextPath; - } - - /** - * Returns the context path for the web server. The path will start with "/" and not - * end with "/". The root context is represented by an empty string. - * @return the context path - */ - public String getContextPath() { - return this.contextPath; - } - - @Override - public void setContextPath(String contextPath) { - checkContextPath(contextPath); - this.contextPath = contextPath; - } - - private void checkContextPath(String contextPath) { - Assert.notNull(contextPath, "'contextPath' must not be null"); - if (!contextPath.isEmpty()) { - if ("/".equals(contextPath)) { - throw new IllegalArgumentException("Root ContextPath must be specified using an empty string"); - } - if (!contextPath.startsWith("/") || contextPath.endsWith("/")) { - throw new IllegalArgumentException("ContextPath must start with '/' and not end with '/'"); - } - } - } - - public String getDisplayName() { - return this.displayName; - } - - @Override - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - /** - * Flag to indicate that the default servlet should be registered. - * @return true if the default servlet is to be registered - */ - public boolean isRegisterDefaultServlet() { - return this.registerDefaultServlet; - } - - @Override - public void setRegisterDefaultServlet(boolean registerDefaultServlet) { - this.registerDefaultServlet = registerDefaultServlet; - } - - /** - * Returns the mime-type mappings. - * @return the mimeMappings the mime-type mappings. - */ - public MimeMappings getMimeMappings() { - return this.mimeMappings; - } - - @Override - public void setMimeMappings(MimeMappings mimeMappings) { - Assert.notNull(mimeMappings, "'mimeMappings' must not be null"); - this.mimeMappings = new MimeMappings(mimeMappings); - } - - @Override - public void addMimeMappings(MimeMappings mimeMappings) { - mimeMappings.forEach((mapping) -> this.mimeMappings.add(mapping.getExtension(), mapping.getMimeType())); - } - - /** - * Returns the document root which will be used by the web context to serve static - * files. - * @return the document root - */ - public File getDocumentRoot() { - return this.documentRoot.getDirectory(); - } - - @Override - public void setDocumentRoot(File documentRoot) { - this.documentRoot.setDirectory(documentRoot); - } - - @Override - public void setInitializers(List initializers) { - Assert.notNull(initializers, "'initializers' must not be null"); - this.initializers = new ArrayList<>(initializers); - } - - @Override - public void addInitializers(ServletContextInitializer... initializers) { - Assert.notNull(initializers, "'initializers' must not be null"); - this.initializers.addAll(Arrays.asList(initializers)); - } - - public Jsp getJsp() { - return this.jsp; - } - - @Override - public void setJsp(Jsp jsp) { - this.jsp = jsp; - } - - public Session getSession() { - return this.session; - } - - @Override - public void setSession(Session session) { - this.session = session; - } - - /** - * Return the Locale to Charset mappings. - * @return the charset mappings - */ - public Map getLocaleCharsetMappings() { - return this.localeCharsetMappings; - } - - @Override - public void setLocaleCharsetMappings(Map localeCharsetMappings) { - Assert.notNull(localeCharsetMappings, "'localeCharsetMappings' must not be null"); - this.localeCharsetMappings = localeCharsetMappings; - } - - @Override - public void setInitParameters(Map initParameters) { - this.initParameters = initParameters; - } - - public Map getInitParameters() { - return this.initParameters; - } - - @Override - public void setCookieSameSiteSuppliers(List cookieSameSiteSuppliers) { - Assert.notNull(cookieSameSiteSuppliers, "'cookieSameSiteSuppliers' must not be null"); - this.cookieSameSiteSuppliers = new ArrayList<>(cookieSameSiteSuppliers); - } - - @Override - public void addCookieSameSiteSuppliers(CookieSameSiteSupplier... cookieSameSiteSuppliers) { - Assert.notNull(cookieSameSiteSuppliers, "'cookieSameSiteSuppliers' must not be null"); - this.cookieSameSiteSuppliers.addAll(Arrays.asList(cookieSameSiteSuppliers)); - } - - public List getCookieSameSiteSuppliers() { - return this.cookieSameSiteSuppliers; - } - - /** - * Utility method that can be used by subclasses wishing to combine the specified - * {@link ServletContextInitializer} parameters with those defined in this instance. - * @param initializers the initializers to merge - * @return a complete set of merged initializers (with the specified parameters - * appearing first) - */ - protected final ServletContextInitializer[] mergeInitializers(ServletContextInitializer... initializers) { - List mergedInitializers = new ArrayList<>(); - mergedInitializers.add((servletContext) -> this.initParameters.forEach(servletContext::setInitParameter)); - mergedInitializers.add(new SessionConfiguringInitializer(this.session)); - mergedInitializers.addAll(Arrays.asList(initializers)); - mergedInitializers.addAll(this.initializers); - return mergedInitializers.toArray(new ServletContextInitializer[0]); - } - - /** - * Returns whether the JSP servlet should be registered with the web server. - * @return {@code true} if the servlet should be registered, otherwise {@code false} - */ - protected boolean shouldRegisterJspServlet() { - return this.jsp != null && this.jsp.getRegistered() - && ClassUtils.isPresent(this.jsp.getClassName(), getClass().getClassLoader()); - } - - /** - * Returns the absolute document root when it points to a valid directory, logging a - * warning and returning {@code null} otherwise. - * @return the valid document root - */ - protected final File getValidDocumentRoot() { - return this.documentRoot.getValidDirectory(); - } - - protected final List getUrlsOfJarsWithMetaInfResources() { - return this.staticResourceJars.getUrls(); - } - - protected final File getValidSessionStoreDir() { - return getValidSessionStoreDir(true); - } - - protected final File getValidSessionStoreDir(boolean mkdirs) { - return this.session.getSessionStoreDirectory().getValidDirectory(mkdirs); - } - - @Override - public void addWebListeners(String... webListenerClassNames) { - this.webListenerClassNames.addAll(Arrays.asList(webListenerClassNames)); - } - - protected final Set getWebListenerClassNames() { - return this.webListenerClassNames; - } - - /** - * {@link ServletContextInitializer} to apply appropriate parts of the {@link Session} - * configuration. - */ - private static class SessionConfiguringInitializer implements ServletContextInitializer { - - private final Session session; - - SessionConfiguringInitializer(Session session) { - this.session = session; - } - - @Override - public void onStartup(ServletContext servletContext) throws ServletException { - if (this.session.getTrackingModes() != null) { - servletContext.setSessionTrackingModes(unwrap(this.session.getTrackingModes())); - } - configureSessionCookie(servletContext.getSessionCookieConfig()); - } - - private void configureSessionCookie(SessionCookieConfig config) { - Cookie cookie = this.session.getCookie(); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(cookie::getName).to(config::setName); - map.from(cookie::getDomain).to(config::setDomain); - map.from(cookie::getPath).to(config::setPath); - map.from(cookie::getHttpOnly).to(config::setHttpOnly); - map.from(cookie::getSecure).to(config::setSecure); - map.from(cookie::getMaxAge).asInt(Duration::getSeconds).to(config::setMaxAge); - map.from(cookie::getPartitioned) - .as(Object::toString) - .to((partitioned) -> config.setAttribute("Partitioned", partitioned)); - } - - private Set unwrap(Set modes) { - if (modes == null) { - return null; - } - Set result = new LinkedHashSet<>(); - for (Session.SessionTrackingMode mode : modes) { - result.add(jakarta.servlet.SessionTrackingMode.valueOf(mode.name())); - } - return result; - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ConfigurableServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ConfigurableServletWebServerFactory.java deleted file mode 100644 index 2af4a5391675..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ConfigurableServletWebServerFactory.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.server; - -import java.io.File; -import java.nio.charset.Charset; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import jakarta.servlet.ServletContext; - -import org.springframework.boot.web.server.ConfigurableWebServerFactory; -import org.springframework.boot.web.server.Cookie.SameSite; -import org.springframework.boot.web.server.MimeMappings; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.WebListenerRegistry; - -/** - * A configurable {@link ServletWebServerFactory}. - * - * @author Dave Syer - * @author Andy Wilkinson - * @author Stephane Nicoll - * @author Eddú Meléndez - * @author Brian Clozel - * @since 2.0.0 - * @see ServletWebServerFactory - * @see WebServerFactoryCustomizer - */ -public interface ConfigurableServletWebServerFactory - extends ConfigurableWebServerFactory, ServletWebServerFactory, WebListenerRegistry { - - /** - * Sets the context path for the web server. The context should start with a "/" - * character but not end with a "/" character. The default context path can be - * specified using an empty string. - * @param contextPath the contextPath to set - */ - void setContextPath(String contextPath); - - /** - * Sets the display name of the application deployed in the web server. - * @param displayName the displayName to set - * @since 1.3.0 - */ - void setDisplayName(String displayName); - - /** - * Sets the configuration that will be applied to the container's HTTP session - * support. - * @param session the session configuration - */ - void setSession(Session session); - - /** - * Set if the DefaultServlet should be registered. Defaults to {@code false} since - * 2.4. - * @param registerDefaultServlet if the default servlet should be registered - */ - void setRegisterDefaultServlet(boolean registerDefaultServlet); - - /** - * Sets the mime-type mappings. - * @param mimeMappings the mime type mappings (defaults to - * {@link MimeMappings#DEFAULT}) - */ - void setMimeMappings(MimeMappings mimeMappings); - - /** - * Adds mime-type mappings. - * @param mimeMappings the mime type mappings to add - * @since 3.3.0 - */ - void addMimeMappings(MimeMappings mimeMappings); - - /** - * Sets the document root directory which will be used by the web context to serve - * static files. - * @param documentRoot the document root or {@code null} if not required - */ - void setDocumentRoot(File documentRoot); - - /** - * Sets {@link ServletContextInitializer} that should be applied in addition to - * {@link ServletWebServerFactory#getWebServer(ServletContextInitializer...)} - * parameters. This method will replace any previously set or added initializers. - * @param initializers the initializers to set - * @see #addInitializers - */ - void setInitializers(List initializers); - - /** - * Add {@link ServletContextInitializer}s to those that should be applied in addition - * to {@link ServletWebServerFactory#getWebServer(ServletContextInitializer...)} - * parameters. - * @param initializers the initializers to add - * @see #setInitializers - */ - void addInitializers(ServletContextInitializer... initializers); - - /** - * Sets the configuration that will be applied to the server's JSP servlet. - * @param jsp the JSP servlet configuration - */ - void setJsp(Jsp jsp); - - /** - * Sets the Locale to Charset mappings. - * @param localeCharsetMappings the Locale to Charset mappings - */ - void setLocaleCharsetMappings(Map localeCharsetMappings); - - /** - * Sets the init parameters that are applied to the container's - * {@link ServletContext}. - * @param initParameters the init parameters - */ - void setInitParameters(Map initParameters); - - /** - * Sets {@link CookieSameSiteSupplier CookieSameSiteSuppliers} that should be used to - * obtain the {@link SameSite} attribute of any added cookie. This method will replace - * any previously set or added suppliers. - * @param cookieSameSiteSuppliers the suppliers to add - * @see #addCookieSameSiteSuppliers - */ - void setCookieSameSiteSuppliers(List cookieSameSiteSuppliers); - - /** - * Add {@link CookieSameSiteSupplier CookieSameSiteSuppliers} to those that should be - * used to obtain the {@link SameSite} attribute of any added cookie. - * @param cookieSameSiteSuppliers the suppliers to add - * @see #setCookieSameSiteSuppliers - */ - void addCookieSameSiteSuppliers(CookieSameSiteSupplier... cookieSameSiteSuppliers); - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/package-info.java deleted file mode 100644 index 1810f68ef4bb..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Servlet web server abstractions. - */ -package org.springframework.boot.web.servlet.server; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/ErrorPageFilter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/ErrorPageFilter.java index 65fc3a400eae..59386d6777d1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/ErrorPageFilter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/ErrorPageFilter.java @@ -38,9 +38,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.boot.web.server.ErrorPage; -import org.springframework.boot.web.server.ErrorPageRegistrar; -import org.springframework.boot.web.server.ErrorPageRegistry; +import org.springframework.boot.web.error.ErrorPage; +import org.springframework.boot.web.error.ErrorPageRegistrar; +import org.springframework.boot.web.error.ErrorPageRegistry; import org.springframework.core.Ordered; import org.springframework.util.ClassUtils; import org.springframework.web.filter.OncePerRequestFilter; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java index 328c4b49c45b..b68ff3b7f659 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java @@ -30,15 +30,20 @@ import org.apache.commons.logging.LogFactory; import reactor.core.scheduler.Schedulers; +import org.springframework.boot.ApplicationContextFactory; import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; import org.springframework.boot.builder.ParentContextApplicationContextInitializer; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; import org.springframework.boot.context.logging.LoggingApplicationListener; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.ApplicationServletEnvironment; +import org.springframework.boot.web.context.servlet.WebApplicationContextInitializer; import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.MergedAnnotations; @@ -155,7 +160,7 @@ protected WebApplicationContext createRootApplicationContext(ServletContext serv builder.initializers(new ParentContextApplicationContextInitializer(parent)); } builder.initializers(new ServletContextApplicationContextInitializer(servletContext)); - builder.contextFactory((webApplicationType) -> new AnnotationConfigServletWebServerApplicationContext()); + builder.contextFactory(new WarDeploymentApplicationContextFactory(servletContext)); builder = configure(builder); builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext)); SpringApplication application = builder.build(); @@ -277,4 +282,38 @@ public void contextDestroyed(ServletContextEvent event) { } + private static final class WarDeploymentApplicationContextFactory implements ApplicationContextFactory { + + private final ServletContext servletContext; + + private WarDeploymentApplicationContextFactory(ServletContext servletContext) { + this.servletContext = servletContext; + } + + @Override + public ConfigurableApplicationContext create(WebApplicationType webApplicationType) { + return new AnnotationConfigServletWebApplicationContext() { + + @Override + protected void onRefresh() { + super.onRefresh(); + try { + new WebApplicationContextInitializer(this) + .initialize(WarDeploymentApplicationContextFactory.this.servletContext); + } + catch (ServletException ex) { + throw new RuntimeException(ex); + } + } + + }; + } + + @Override + public ConfigurableEnvironment createEnvironment(WebApplicationType webApplicationType) { + return new ApplicationServletEnvironment(); + } + + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/MustacheView.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/MustacheView.java deleted file mode 100644 index ebd5517a8346..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/MustacheView.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.view; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.Locale; -import java.util.Map; - -import com.samskivert.mustache.Mustache.Compiler; -import com.samskivert.mustache.Template; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import org.springframework.core.io.Resource; -import org.springframework.web.servlet.View; -import org.springframework.web.servlet.view.AbstractTemplateView; - -/** - * Spring MVC {@link View} using the Mustache template engine. - * - * @author Brian Clozel - * @author Dave Syer - * @author Phillip Webb - * @since 2.0.0 - */ -public class MustacheView extends AbstractTemplateView { - - private Compiler compiler; - - private String charset; - - /** - * Set the Mustache compiler to be used by this view. - *

    - * Typically this property is not set directly. Instead a single {@link Compiler} is - * expected in the Spring application context which is used to compile Mustache - * templates. - * @param compiler the Mustache compiler - */ - public void setCompiler(Compiler compiler) { - this.compiler = compiler; - } - - /** - * Set the charset used for reading Mustache template files. - * @param charset the charset to use for reading template files - */ - public void setCharset(String charset) { - this.charset = charset; - } - - @Override - public boolean checkResource(Locale locale) throws Exception { - Resource resource = getApplicationContext().getResource(getUrl()); - return (resource != null && resource.exists()); - } - - @Override - protected void renderMergedTemplateModel(Map model, HttpServletRequest request, - HttpServletResponse response) throws Exception { - Template template = createTemplate(getApplicationContext().getResource(getUrl())); - if (template != null) { - template.execute(model, response.getWriter()); - } - } - - private Template createTemplate(Resource resource) throws IOException { - try (Reader reader = getReader(resource)) { - return this.compiler.compile(reader); - } - } - - private Reader getReader(Resource resource) throws IOException { - if (this.charset != null) { - return new InputStreamReader(resource.getInputStream(), this.charset); - } - return new InputStreamReader(resource.getInputStream()); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/MustacheViewResolver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/MustacheViewResolver.java deleted file mode 100644 index dfdd299e8a19..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/MustacheViewResolver.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.view; - -import com.samskivert.mustache.Mustache; -import com.samskivert.mustache.Mustache.Compiler; - -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.view.AbstractTemplateViewResolver; -import org.springframework.web.servlet.view.AbstractUrlBasedView; - -/** - * Spring MVC {@link ViewResolver} for Mustache. - * - * @author Brian Clozel - * @since 2.0.0 - */ -public class MustacheViewResolver extends AbstractTemplateViewResolver { - - private final Mustache.Compiler compiler; - - private String charset; - - /** - * Create a {@code MustacheViewResolver} backed by a default instance of a - * {@link Compiler}. - */ - public MustacheViewResolver() { - this.compiler = Mustache.compiler(); - setViewClass(requiredViewClass()); - } - - /** - * Create a {@code MustacheViewResolver} backed by a custom instance of a - * {@link Compiler}. - * @param compiler the Mustache compiler used to compile templates - */ - public MustacheViewResolver(Compiler compiler) { - this.compiler = compiler; - setViewClass(requiredViewClass()); - } - - @Override - protected Class requiredViewClass() { - return MustacheView.class; - } - - /** - * Set the charset. - * @param charset the charset - */ - public void setCharset(String charset) { - this.charset = charset; - } - - @Override - protected AbstractUrlBasedView buildView(String viewName) throws Exception { - MustacheView view = (MustacheView) super.buildView(viewName); - view.setCompiler(this.compiler); - view.setCharset(this.charset); - return view; - } - - @Override - protected AbstractUrlBasedView instantiateView() { - return (getViewClass() == MustacheView.class) ? new MustacheView() : super.instantiateView(); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/package-info.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/package-info.java deleted file mode 100644 index bfbed6d24c73..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/view/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Additional {@link org.springframework.web.servlet.View Views} for use with Web MVC. - */ -package org.springframework.boot.web.servlet.view; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilder.java deleted file mode 100644 index a34a688291ab..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilder.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.webservices.client; - -import java.time.Duration; -import java.util.function.Function; -import java.util.function.Supplier; - -import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; -import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; -import org.springframework.boot.http.client.JdkClientHttpRequestFactoryBuilder; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.util.Assert; -import org.springframework.ws.transport.WebServiceMessageSender; - -/** - * {@link WebServiceMessageSender} builder that can detect a suitable HTTP library based - * on the classpath. - * - * @author Stephane Nicoll - * @since 2.1.0 - * @deprecated since 3.4.0 in favor of - * {@link WebServiceMessageSenderFactory#http(ClientHttpRequestFactorySettings)} - */ -@Deprecated(since = "3.4.0", forRemoval = true) -public class HttpWebServiceMessageSenderBuilder { - - private ClientHttpRequestFactoryBuilder requestFactoryBuilder; - - private ClientHttpRequestFactorySettings requestFactorySettings = ClientHttpRequestFactorySettings.defaults(); - - /** - * Set the connection timeout. - * @param connectTimeout the connection timeout - * @return the current builder instance - */ - public HttpWebServiceMessageSenderBuilder setConnectTimeout(Duration connectTimeout) { - this.requestFactorySettings = this.requestFactorySettings.withConnectTimeout(connectTimeout); - return this; - } - - /** - * Set the read timeout. - * @param readTimeout the read timeout - * @return the current builder instance - */ - public HttpWebServiceMessageSenderBuilder setReadTimeout(Duration readTimeout) { - this.requestFactorySettings = this.requestFactorySettings.withReadTimeout(readTimeout); - return this; - } - - /** - * Set an {@link SslBundle} that will be used to configure a secure connection. - * @param sslBundle the SSL bundle - * @return the current builder instance - */ - public HttpWebServiceMessageSenderBuilder sslBundle(SslBundle sslBundle) { - this.requestFactorySettings = this.requestFactorySettings.withSslBundle(sslBundle); - return this; - } - - /** - * Set the {@code Supplier} of {@link ClientHttpRequestFactory} that should be called - * to create the HTTP-based {@link WebServiceMessageSender}. - * @param requestFactorySupplier the supplier for the request factory - * @return the current builder instance - */ - public HttpWebServiceMessageSenderBuilder requestFactory( - Supplier requestFactorySupplier) { - Assert.notNull(requestFactorySupplier, "'requestFactorySupplier' must not be null"); - this.requestFactoryBuilder = ClientHttpRequestFactoryBuilder.of(requestFactorySupplier); - return this; - } - - /** - * Set the {@code Function} of {@link ClientHttpRequestFactorySettings} to - * {@link ClientHttpRequestFactory} that should be called to create the HTTP-based - * {@link WebServiceMessageSender}. - * @param requestFactoryFunction the function for the request factory - * @return the current builder instance - * @since 3.0.0 - */ - public HttpWebServiceMessageSenderBuilder requestFactory( - Function requestFactoryFunction) { - Assert.notNull(requestFactoryFunction, "'requestFactoryFunction' must not be null"); - this.requestFactoryBuilder = requestFactoryFunction::apply; - return this; - } - - /** - * Set the {@link ClientHttpRequestFactoryBuilder} to use when creating the HTTP-based - * {@link WebServiceMessageSender}. - * @param requestFactoryBuilder the {@link ClientHttpRequestFactoryBuilder} to use - * @return this builder instance - * @since 3.4.0 - */ - public HttpWebServiceMessageSenderBuilder requestFactoryBuilder( - ClientHttpRequestFactoryBuilder requestFactoryBuilder) { - Assert.notNull(requestFactoryBuilder, "'requestFactoryBuilder' must not be null"); - this.requestFactoryBuilder = requestFactoryBuilder; - return this; - } - - /** - * Build the {@link WebServiceMessageSender} instance. - * @return the {@link WebServiceMessageSender} instance - */ - public WebServiceMessageSender build() { - ClientHttpRequestFactoryBuilder requestFactoryBuilder = getOrDetectRequestFactoryBuilder(); - return WebServiceMessageSenderFactory.http(requestFactoryBuilder, this.requestFactorySettings) - .getWebServiceMessageSender(); - } - - private ClientHttpRequestFactoryBuilder getOrDetectRequestFactoryBuilder() { - if (this.requestFactoryBuilder != null) { - return this.requestFactoryBuilder; - } - ClientHttpRequestFactoryBuilder builder = ClientHttpRequestFactoryBuilder.detect(); - if (builder instanceof JdkClientHttpRequestFactoryBuilder) { - // Same logic as earlier versions which did not support JDK client factories - return ClientHttpRequestFactoryBuilder.simple(); - } - return builder; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories index 0852534a5ce3..d2e42f9273c8 100644 --- a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories @@ -21,11 +21,6 @@ org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\ org.springframework.boot.context.config.StandardConfigDataLoader,\ org.springframework.boot.context.config.SystemEnvironmentConfigDataLoader -# Application Context Factories -org.springframework.boot.ApplicationContextFactory=\ -org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContextFactory,\ -org.springframework.boot.web.servlet.context.ServletWebServerApplicationContextFactory - # Run Listeners org.springframework.boot.SpringApplicationRunListener=\ org.springframework.boot.context.event.EventPublishingRunListener @@ -38,9 +33,7 @@ org.springframework.boot.diagnostics.FailureAnalyzers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\ org.springframework.boot.context.ContextIdApplicationContextInitializer,\ -org.springframework.boot.io.ProtocolResolverApplicationContextInitializer,\ -org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\ -org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer +org.springframework.boot.io.ProtocolResolverApplicationContextInitializer # Application Listeners org.springframework.context.ApplicationListener=\ @@ -57,8 +50,7 @@ org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\ org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,\ org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor,\ org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\ -org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\ -org.springframework.boot.reactor.ReactorEnvironmentPostProcessor +org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor # Failure Analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ @@ -79,31 +71,12 @@ org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,\ org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\ org.springframework.boot.diagnostics.analyzer.PatternParseFailureAnalyzer,\ org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\ -org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\ -org.springframework.boot.liquibase.LiquibaseChangelogMissingFailureAnalyzer,\ -org.springframework.boot.web.context.MissingWebServerFactoryBeanFailureAnalyzer,\ -org.springframework.boot.web.embedded.tomcat.ConnectorStartFailureAnalyzer,\ -org.springframework.boot.web.server.PortInUseFailureAnalyzer +org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer # Failure Analysis Reporters org.springframework.boot.diagnostics.FailureAnalysisReporter=\ org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter -# Database Initializer Detectors -org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\ -org.springframework.boot.flyway.FlywayDatabaseInitializerDetector,\ -org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializerDetector,\ -org.springframework.boot.liquibase.LiquibaseDatabaseInitializerDetector,\ -org.springframework.boot.orm.jpa.JpaDatabaseInitializerDetector,\ -org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializerDetector - -# Depends On Database Initialization Detectors -org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\ -org.springframework.boot.jdbc.SpringJdbcDependsOnDatabaseInitializationDetector,\ -org.springframework.boot.jooq.JooqDependsOnDatabaseInitializationDetector,\ -org.springframework.boot.orm.jpa.JpaDependsOnDatabaseInitializationDetector,\ -org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector - # Resource Locator Protocol Resolvers org.springframework.core.io.ProtocolResolver=\ org.springframework.boot.io.Base64ProtocolResolver @@ -111,5 +84,5 @@ org.springframework.boot.io.Base64ProtocolResolver # Resource File Path Resolvers org.springframework.boot.io.ApplicationResourceLoader$FilePathResolver=\ org.springframework.boot.io.ClassPathResourceFilePathResolver,\ -org.springframework.boot.web.reactive.context.FilteredReactiveWebContextResourceFilePathResolver,\ -org.springframework.boot.web.servlet.context.ServletContextResourceFilePathResolver +org.springframework.boot.web.context.reactive.FilteredReactiveWebContextResourceFilePathResolver,\ +org.springframework.boot.web.context.servlet.ServletContextResourceFilePathResolver diff --git a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring/aot.factories index 5d4127122e5c..61390a75beb4 100644 --- a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring/aot.factories +++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring/aot.factories @@ -5,23 +5,17 @@ org.springframework.boot.WebApplicationType$WebApplicationTypeRuntimeHints,\ org.springframework.boot.context.config.ConfigDataLocationRuntimeHints,\ org.springframework.boot.context.config.ConfigDataPropertiesRuntimeHints,\ org.springframework.boot.env.PropertySourceRuntimeHints,\ -org.springframework.boot.http.client.ClientHttpRequestFactoryRuntimeHints,\ -org.springframework.boot.jdbc.DataSourceBuilderRuntimeHints,\ org.springframework.boot.json.JacksonRuntimeHints,\ org.springframework.boot.logging.java.JavaLoggingSystemRuntimeHints,\ org.springframework.boot.logging.logback.LogbackRuntimeHints,\ org.springframework.boot.logging.structured.ElasticCommonSchemaProperties$ElasticCommonSchemaPropertiesRuntimeHints,\ org.springframework.boot.logging.structured.GraylogExtendedLogFormatProperties$GraylogExtendedLogFormatPropertiesRuntimeHints,\ -org.springframework.boot.logging.structured.StructuredLoggingJsonProperties$StructuredLoggingJsonPropertiesRuntimeHints,\ -org.springframework.boot.web.embedded.undertow.UndertowWebServer$UndertowWebServerRuntimeHints,\ -org.springframework.boot.web.server.MimeMappings$MimeMappingsRuntimeHints +org.springframework.boot.logging.structured.StructuredLoggingJsonProperties$StructuredLoggingJsonPropertiesRuntimeHints org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=\ org.springframework.boot.context.properties.ConfigurationPropertiesBeanFactoryInitializationAotProcessor,\ org.springframework.boot.env.EnvironmentPostProcessorApplicationListener$EnvironmentBeanFactoryInitializationAotProcessor,\ -org.springframework.boot.jackson.JsonComponentModule$JsonComponentBeanFactoryInitializationAotProcessor,\ org.springframework.boot.logging.structured.StructuredLoggingJsonPropertiesBeanFactoryInitializationAotProcessor org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\ -org.springframework.boot.context.properties.ConfigurationPropertiesBeanRegistrationAotProcessor,\ -org.springframework.boot.jackson.JsonMixinModuleEntriesBeanRegistrationAotProcessor +org.springframework.boot.context.properties.ConfigurationPropertiesBeanRegistrationAotProcessor diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java index 62ac0f482ebd..ea207bc69494 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java @@ -20,7 +20,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -41,7 +40,6 @@ import org.mockito.ArgumentMatchers; import org.mockito.InOrder; import org.mockito.Mockito; -import reactor.core.publisher.Mono; import org.springframework.aot.AotDetector; import org.springframework.beans.factory.BeanCreationException; @@ -50,6 +48,7 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionOverrideException; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -76,12 +75,7 @@ import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; -import org.springframework.boot.web.reactive.context.StandardReactiveWebEnvironment; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextException; @@ -117,16 +111,13 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.core.metrics.ApplicationStartup; import org.springframework.core.metrics.StartupStep; -import org.springframework.http.server.reactive.HttpHandler; import org.springframework.mock.env.MockEnvironment; -import org.springframework.test.context.support.TestPropertySourceUtils; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import org.springframework.web.context.ConfigurableWebEnvironment; import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.StandardServletEnvironment; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -430,40 +421,6 @@ void defaultApplicationContext() { assertThat(this.context).isInstanceOf(AnnotationConfigApplicationContext.class); } - @Test - void defaultApplicationContextForWeb() { - SpringApplication application = new SpringApplication(ExampleWebConfig.class); - application.setWebApplicationType(WebApplicationType.SERVLET); - this.context = application.run(); - assertThat(this.context).isInstanceOf(AnnotationConfigServletWebServerApplicationContext.class); - } - - @Test - void defaultApplicationContextForReactiveWeb() { - SpringApplication application = new SpringApplication(ExampleReactiveWebConfig.class); - application.setWebApplicationType(WebApplicationType.REACTIVE); - this.context = application.run(); - assertThat(this.context).isInstanceOf(AnnotationConfigReactiveWebServerApplicationContext.class); - } - - @Test - void environmentForWeb() { - SpringApplication application = new SpringApplication(ExampleWebConfig.class); - application.setWebApplicationType(WebApplicationType.SERVLET); - this.context = application.run(); - assertThat(this.context.getEnvironment()).isInstanceOf(StandardServletEnvironment.class); - assertThat(this.context.getEnvironment().getClass().getName()).endsWith("ApplicationServletEnvironment"); - } - - @Test - void environmentForReactiveWeb() { - SpringApplication application = new SpringApplication(ExampleReactiveWebConfig.class); - application.setWebApplicationType(WebApplicationType.REACTIVE); - this.context = application.run(); - assertThat(this.context.getEnvironment()).isInstanceOf(StandardReactiveWebEnvironment.class); - assertThat(this.context.getEnvironment().getClass().getName()).endsWith("ApplicationReactiveWebEnvironment"); - } - @Test void customEnvironment() { TestSpringApplication application = new TestSpringApplication(ExampleConfig.class); @@ -487,26 +444,14 @@ void customResourceLoader() { @Test void customResourceLoaderFromConstructor() { ResourceLoader resourceLoader = new DefaultResourceLoader(); - TestSpringApplication application = new TestSpringApplication(resourceLoader, ExampleWebConfig.class); + TestSpringApplication application = new TestSpringApplication(resourceLoader, ExampleConfig.class); this.context = application.run(); then(application.getLoader()).should().setResourceLoader(resourceLoader); } @Test void customBeanNameGenerator() { - TestSpringApplication application = new TestSpringApplication(ExampleWebConfig.class); - BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator(); - application.setBeanNameGenerator(beanNameGenerator); - this.context = application.run(); - then(application.getLoader()).should().setBeanNameGenerator(beanNameGenerator); - Object actualGenerator = this.context.getBean(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR); - assertThat(actualGenerator).isSameAs(beanNameGenerator); - } - - @Test - void customBeanNameGeneratorWithNonWebApplication() { - TestSpringApplication application = new TestSpringApplication(ExampleWebConfig.class); - application.setWebApplicationType(WebApplicationType.NONE); + TestSpringApplication application = new TestSpringApplication(ExampleConfig.class); BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator(); application.setBeanNameGenerator(beanNameGenerator); this.context = application.run(); @@ -838,13 +783,13 @@ void wildcardSources() { @Test void run() { - this.context = SpringApplication.run(ExampleWebConfig.class); + this.context = SpringApplication.run(ExampleConfig.class); assertThat(this.context).isNotNull(); } @Test void runComponents() { - this.context = SpringApplication.run(new Class[] { ExampleWebConfig.class, Object.class }, new String[0]); + this.context = SpringApplication.run(new Class[] { ExampleConfig.class, Object.class }, new String[0]); assertThat(this.context).isNotNull(); } @@ -1024,7 +969,7 @@ private void verifyRegisteredListenerSuccessEvents() { @Test void applicationListenerFromApplicationIsCalledWhenContextFailsRefreshBeforeListenerRegistration() { ApplicationListener listener = mock(ApplicationListener.class); - SpringApplication application = new SpringApplication(ExampleConfig.class); + SpringApplication application = new SpringApplication(BrokenBeanFactoryPostProcessing.class); application.addListeners(listener); assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(application::run); verifyRegisteredListenerFailedFromApplicationEvents(listener); @@ -1055,7 +1000,7 @@ private void verifyRegisteredListenerFailedFromApplicationEvents(ApplicationList @Test void applicationListenerFromContextIsCalledWhenContextFailsRefreshBeforeListenerRegistration() { final ApplicationListener listener = mock(ApplicationListener.class); - SpringApplication application = new SpringApplication(ExampleConfig.class); + SpringApplication application = new SpringApplication(BrokenBeanFactoryPostProcessing.class); application.addInitializers((applicationContext) -> applicationContext.addApplicationListener(listener)); assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(application::run); then(listener).should().onApplicationEvent(isA(ApplicationFailedEvent.class)); @@ -1110,23 +1055,6 @@ void getApplicationArgumentsBean() { assertThat(args.containsOption("debug")).isTrue(); } - @Test - void webApplicationSwitchedOffInListener() { - TestSpringApplication application = new TestSpringApplication(ExampleConfig.class); - application.addListeners((ApplicationListener) (event) -> { - assertThat(event.getEnvironment().getClass().getName()).endsWith("ApplicationServletEnvironment"); - TestPropertySourceUtils.addInlinedPropertiesToEnvironment(event.getEnvironment(), "foo=bar"); - event.getSpringApplication().setWebApplicationType(WebApplicationType.NONE); - }); - this.context = application.run(); - assertThat(this.context.getEnvironment()).isNotInstanceOf(StandardServletEnvironment.class); - assertThat(this.context.getEnvironment().getProperty("foo")).isEqualTo("bar"); - Iterator> iterator = this.context.getEnvironment().getPropertySources().iterator(); - assertThat(iterator.next().getName()).isEqualTo("configurationProperties"); - assertThat(iterator.next().getName()) - .isEqualTo(TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME); - } - @Test void nonWebApplicationConfiguredViaAPropertyHasTheCorrectTypeOfContextAndEnvironment() { ConfigurableApplicationContext context = new SpringApplication(ExampleConfig.class) @@ -1135,35 +1063,6 @@ void nonWebApplicationConfiguredViaAPropertyHasTheCorrectTypeOfContextAndEnviron assertThat(context.getEnvironment()).isNotInstanceOfAny(ConfigurableWebEnvironment.class); } - @Test - void webApplicationConfiguredViaAPropertyHasTheCorrectTypeOfContextAndEnvironment() { - ConfigurableApplicationContext context = new SpringApplication(ExampleWebConfig.class) - .run("--spring.main.web-application-type=servlet"); - assertThat(context).isInstanceOf(WebApplicationContext.class); - assertThat(context.getEnvironment()).isInstanceOf(StandardServletEnvironment.class); - assertThat(context.getEnvironment().getClass().getName()).endsWith("ApplicationServletEnvironment"); - } - - @Test - void reactiveApplicationConfiguredViaAPropertyHasTheCorrectTypeOfContextAndEnvironment() { - ConfigurableApplicationContext context = new SpringApplication(ExampleReactiveWebConfig.class) - .run("--spring.main.web-application-type=reactive"); - assertThat(context).isInstanceOf(ReactiveWebApplicationContext.class); - assertThat(context.getEnvironment()).isInstanceOf(StandardReactiveWebEnvironment.class); - assertThat(context.getEnvironment().getClass().getName()).endsWith("ApplicationReactiveWebEnvironment"); - } - - @Test - @WithResource(name = "application-withwebapplicationtype.yml", - content = "spring.main.web-application-type: reactive") - void environmentIsConvertedIfTypeDoesNotMatch() { - ConfigurableApplicationContext context = new SpringApplication(ExampleReactiveWebConfig.class) - .run("--spring.profiles.active=withwebapplicationtype"); - assertThat(context).isInstanceOf(ReactiveWebApplicationContext.class); - assertThat(context.getEnvironment()).isInstanceOf(StandardReactiveWebEnvironment.class); - assertThat(context.getEnvironment().getClass().getName()).endsWith("ApplicationReactiveWebEnvironment"); - } - @Test void failureResultsInSingleStackTrace(CapturedOutput output) throws Exception { ThreadGroup group = new ThreadGroup("main"); @@ -1716,46 +1615,33 @@ void boom() { } @Configuration(proxyBeanMethods = false) - static class ListenerConfig { + static class BrokenBeanFactoryPostProcessing { @Bean - ApplicationListener testApplicationListener() { - return mock(ApplicationListener.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class Multicaster { - - @Bean(name = AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME) - ApplicationEventMulticaster applicationEventMulticaster() { - return spy(new SimpleApplicationEventMulticaster()); + static BeanFactoryPostProcessor brokenBeanFactoryPostProcessor() { + return (beanFactory) -> { + throw new ApplicationContextException("broken"); + }; } } @Configuration(proxyBeanMethods = false) - static class ExampleWebConfig { + static class ListenerConfig { @Bean - TomcatServletWebServerFactory webServer() { - return new TomcatServletWebServerFactory(0); + ApplicationListener testApplicationListener() { + return mock(ApplicationListener.class); } } @Configuration(proxyBeanMethods = false) - static class ExampleReactiveWebConfig { - - @Bean - NettyReactiveWebServerFactory webServerFactory() { - return new NettyReactiveWebServerFactory(0); - } + static class Multicaster { - @Bean - HttpHandler httpHandler() { - return (serverHttpRequest, serverHttpResponse) -> Mono.empty(); + @Bean(name = AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME) + ApplicationEventMulticaster applicationEventMulticaster() { + return spy(new SimpleApplicationEventMulticaster()); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/admin/SpringApplicationAdminMXBeanRegistrarTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/admin/SpringApplicationAdminMXBeanRegistrarTests.java index d49a94e91fec..55aa79829f24 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/admin/SpringApplicationAdminMXBeanRegistrarTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/admin/SpringApplicationAdminMXBeanRegistrarTests.java @@ -17,6 +17,7 @@ package org.springframework.boot.admin; import java.lang.management.ManagementFactory; +import java.util.Map; import javax.management.InstanceNotFoundException; import javax.management.MBeanServer; @@ -34,6 +35,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.env.MapPropertySource; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -111,6 +113,19 @@ void environmentIsExposed() { assertThat(getProperty(objectName, "does.not.exist.test")).isNull(); } + @Test + void whenEnvironmentContainsServerPortsPropertySourceEmbeddedWebApplicationIsDetected() { + final ObjectName objectName = createObjectName(OBJECT_NAME); + SpringApplication application = new SpringApplication(Config.class); + application.setWebApplicationType(WebApplicationType.NONE); + application.addInitializers((context) -> context.getEnvironment() + .getPropertySources() + .addLast(new MapPropertySource("server.ports", Map.of("local.server.port", "8910")))); + this.context = application.run("--foo.bar=blam"); + assertThat(isApplicationReady(objectName)).isTrue(); + assertThat(isApplicationEmbeddedWebApplication(objectName)).isTrue(); + } + @Test void shutdownApp() { final ObjectName objectName = createObjectName(OBJECT_NAME); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java index 52bc87aa9570..b1483d88b7b0 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java @@ -274,7 +274,7 @@ void initializersCreatedOnce() { SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class) .web(WebApplicationType.NONE); this.context = application.run(); - assertThat(application.application().getInitializers()).hasSize(5); + assertThat(application.application().getInitializers()).hasSize(3); } @Test @@ -283,7 +283,7 @@ void initializersCreatedOnceForChild() { .child(ChildConfig.class) .web(WebApplicationType.NONE); this.context = application.run(); - assertThat(application.application().getInitializers()).hasSize(6); + assertThat(application.application().getInitializers()).hasSize(4); } @Test @@ -293,7 +293,7 @@ void initializersIncludeDefaults() { .initializers((ConfigurableApplicationContext applicationContext) -> { }); this.context = application.run(); - assertThat(application.application().getInitializers()).hasSize(6); + assertThat(application.application().getInitializers()).hasSize(4); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/annotation/ConfigurationsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/annotation/ConfigurationsTests.java index 056208925c99..6985c2a31cb3 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/annotation/ConfigurationsTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/annotation/ConfigurationsTests.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -50,27 +49,6 @@ void createWhenClassesIsNullShouldThrowException() { .withMessageContaining("'classes' must not be null"); } - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void createShouldSortClassesUsingSortMethod() { - TestDeprecatedSortedConfigurations configurations = new TestDeprecatedSortedConfigurations( - Arrays.asList(OutputStream.class, InputStream.class)); - assertThat(configurations.getClasses()).containsExactly(InputStream.class, OutputStream.class); - } - - @Test - @Deprecated(since = "3.4.0", forRemoval = true) - void getClassesShouldMergeByClassAndSortUsingSortMethod() { - Configurations c1 = new TestDeprecatedSortedConfigurations( - Arrays.asList(OutputStream.class, InputStream.class)); - Configurations c2 = new TestConfigurations(Collections.singletonList(Short.class)); - Configurations c3 = new TestDeprecatedSortedConfigurations(Arrays.asList(String.class, Integer.class)); - Configurations c4 = new TestConfigurations(Arrays.asList(Long.class, Byte.class)); - Class[] classes = Configurations.getClasses(c1, c2, c3, c4); - assertThat(classes).containsExactly(Short.class, Long.class, Byte.class, InputStream.class, Integer.class, - OutputStream.class, String.class); - } - @Test void createShouldSortClasses() { TestConfigurations configurations = new TestConfigurations(Sorter.instance, OutputStream.class, @@ -146,26 +124,6 @@ protected Configurations merge(Set> mergedClasses) { } - @Order(Ordered.LOWEST_PRECEDENCE) - @SuppressWarnings("removal") - static class TestDeprecatedSortedConfigurations extends Configurations { - - protected TestDeprecatedSortedConfigurations(Collection> classes) { - super(classes); - } - - @Override - protected Collection> sort(Collection> classes) { - return Sorter.instance.apply(classes); - } - - @Override - protected Configurations merge(Set> mergedClasses) { - return new TestDeprecatedSortedConfigurations(mergedClasses); - } - - } - static class Sorter implements UnaryOperator>> { static final Sorter instance = new Sorter(); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerIntegrationTests.java index 3feaa086b2c1..890a0d3a6d23 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerIntegrationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/logging/LoggingApplicationListenerIntegrationTests.java @@ -30,7 +30,9 @@ import org.springframework.boot.context.event.ApplicationStartingEvent; import org.springframework.boot.logging.LogFile; import org.springframework.boot.logging.LoggingSystem; +import org.springframework.boot.logging.LoggingSystemFactory; import org.springframework.boot.logging.LoggingSystemProperty; +import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; import org.springframework.context.ApplicationListener; @@ -44,6 +46,10 @@ * * @author Stephane Nicoll */ +@WithResource(name = "META-INF/spring.factories", + content = """ + org.springframework.boot.logging.LoggingSystemFactory=org.springframework.boot.context.logging.LoggingApplicationListenerIntegrationTests$MockLoggingSystemFactory + """) @ExtendWith(OutputCaptureExtension.class) class LoggingApplicationListenerIntegrationTests { @@ -110,4 +116,22 @@ static class Config { } + static class MockLoggingSystemFactory implements LoggingSystemFactory { + + @Override + public LoggingSystem getLoggingSystem(ClassLoader classLoader) { + return new MockLoggingSystem(); + } + + } + + static class MockLoggingSystem extends LoggingSystem { + + @Override + public void beforeInitialize() { + + } + + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/FailureAnalyzersIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/FailureAnalyzersIntegrationTests.java index 037f148adfc8..ef143f32f907 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/FailureAnalyzersIntegrationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/FailureAnalyzersIntegrationTests.java @@ -24,8 +24,8 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; -import org.springframework.boot.web.server.PortInUseException; import org.springframework.context.annotation.Configuration; +import org.springframework.web.util.pattern.PathPatternParser; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatException; @@ -50,7 +50,7 @@ static class TestConfiguration { @PostConstruct void fail() { - throw new PortInUseException(8080); + new PathPatternParser().parse("{ }"); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorBuilderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorBuilderTests.java deleted file mode 100644 index cb60e06760a3..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/http/client/reactive/ClientHttpConnectorBuilderTests.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.http.client.reactive; - -import java.net.URI; -import java.time.Duration; -import java.util.List; -import java.util.function.Function; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.reactive.ClientHttpConnector; -import org.springframework.http.client.reactive.ClientHttpRequest; -import org.springframework.http.client.reactive.ClientHttpResponse; -import org.springframework.http.client.reactive.HttpComponentsClientHttpConnector; -import org.springframework.http.client.reactive.JdkClientHttpConnector; -import org.springframework.http.client.reactive.JettyClientHttpConnector; -import org.springframework.http.client.reactive.ReactorClientHttpConnector; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link ClientHttpConnectorBuilder}. - * - * @author Phillip Webb - */ -class ClientHttpConnectorBuilderTests { - - @Test - void withCustomizerAppliesCustomizers() { - ClientHttpConnectorBuilder builder = (settings) -> new JdkClientHttpConnector(); - builder = builder.withCustomizer(this::setJdkReadTimeout); - JdkClientHttpConnector connector = builder.build(null); - assertThat(connector).extracting("readTimeout").isEqualTo(Duration.ofSeconds(5)); - } - - @Test - void withCustomizersAppliesCustomizers() { - ClientHttpConnectorBuilder builder = (settings) -> new JdkClientHttpConnector(); - builder = builder.withCustomizers(List.of(this::setJdkReadTimeout)); - JdkClientHttpConnector connector = builder.build(null); - assertThat(connector).extracting("readTimeout").isEqualTo(Duration.ofSeconds(5)); - } - - @Test - void reactorReturnsReactorFactoryBuilder() { - assertThat(ClientHttpConnectorBuilder.reactor()).isInstanceOf(ReactorClientHttpConnectorBuilder.class); - } - - @Test - void jettyReturnsJettyFactoryBuilder() { - assertThat(ClientHttpConnectorBuilder.jetty()).isInstanceOf(JettyClientHttpConnectorBuilder.class); - } - - @Test - void httpComponentsReturnsHttpComponentsFactoryBuilder() { - assertThat(ClientHttpConnectorBuilder.httpComponents()) - .isInstanceOf(HttpComponentsClientHttpConnectorBuilder.class); - } - - @Test - void jdkReturnsJdkFactoryBuilder() { - assertThat(ClientHttpConnectorBuilder.jdk()).isInstanceOf(JdkClientHttpConnectorBuilder.class); - } - - @Test - void ofWhenExactlyClientHttpRequestFactoryTypeThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> ClientHttpConnectorBuilder.of(ClientHttpConnector.class)) - .withMessage("'clientHttpConnectorType' must be an implementation of ClientHttpConnector"); - } - - @Test - void ofWhenReactorFactoryReturnsReactorFactoryBuilder() { - assertThat(ClientHttpConnectorBuilder.of(ReactorClientHttpConnector.class)) - .isInstanceOf(ReactorClientHttpConnectorBuilder.class); - } - - @Test - void ofWhenJettyFactoryReturnsReactorFactoryBuilder() { - assertThat(ClientHttpConnectorBuilder.of(JettyClientHttpConnector.class)) - .isInstanceOf(JettyClientHttpConnectorBuilder.class); - } - - @Test - void ofWhenHttpComponentsFactoryReturnsHttpComponentsFactoryBuilder() { - assertThat(ClientHttpConnectorBuilder.of(HttpComponentsClientHttpConnector.class)) - .isInstanceOf(HttpComponentsClientHttpConnectorBuilder.class); - } - - @Test - void ofWhenJdkFactoryReturnsJdkFactoryBuilder() { - assertThat(ClientHttpConnectorBuilder.of(JdkClientHttpConnector.class)) - .isInstanceOf(JdkClientHttpConnectorBuilder.class); - } - - @Test - void ofWhenUnknownTypeThrowsException() { - assertThatIllegalArgumentException() - .isThrownBy(() -> ClientHttpConnectorBuilder.of(TestClientHttpConnector.class)) - .withMessage("'clientHttpConnectorType' " + TestClientHttpConnector.class.getName() + " is not supported"); - } - - @Test - void detectWhenReactor() { - assertThat(ClientHttpConnectorBuilder.detect()).isInstanceOf(ReactorClientHttpConnectorBuilder.class); - } - - @Test - @ClassPathExclusions({ "reactor-netty-http-*.jar" }) - void detectWhenJetty() { - assertThat(ClientHttpConnectorBuilder.detect()).isInstanceOf(JettyClientHttpConnectorBuilder.class); - } - - @Test - @ClassPathExclusions({ "reactor-netty-http-*.jar", "jetty-client-*.jar" }) - void detectWhenHttpComponents() { - assertThat(ClientHttpConnectorBuilder.detect()).isInstanceOf(HttpComponentsClientHttpConnectorBuilder.class); - } - - @Test - @ClassPathExclusions({ "reactor-netty-http-*.jar", "jetty-client-*.jar", "httpclient5-*.jar" }) - void detectWhenJdk() { - assertThat(ClientHttpConnectorBuilder.detect()).isInstanceOf(JdkClientHttpConnectorBuilder.class); - } - - private void setJdkReadTimeout(JdkClientHttpConnector factory) { - factory.setReadTimeout(Duration.ofSeconds(5)); - } - - public static class TestClientHttpConnector implements ClientHttpConnector { - - @Override - public Mono connect(HttpMethod method, URI uri, - Function> requestCallback) { - return null; - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/ApplicationNameConverterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/ApplicationNameConverterTests.java deleted file mode 100644 index 078b3e6db382..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/ApplicationNameConverterTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.logging.logback; - -import java.util.Collections; - -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.spi.LoggerContextVO; -import ch.qos.logback.classic.spi.LoggingEvent; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.logging.LoggingSystemProperty; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ApplicationNameConverter}. - * - * @author Andy Wilkinson - */ -@SuppressWarnings({ "deprecation", "removal" }) -class ApplicationNameConverterTests { - - private final ApplicationNameConverter converter; - - private final LoggingEvent event = new LoggingEvent(); - - ApplicationNameConverterTests() { - this.converter = new ApplicationNameConverter(); - this.converter.setContext(new LoggerContext()); - this.event.setLoggerContextRemoteView( - new LoggerContextVO("test", Collections.emptyMap(), System.currentTimeMillis())); - } - - @Test - void whenNoLoggedApplicationNameConvertReturnsEmptyString() { - withLoggedApplicationName(null, () -> { - this.converter.start(); - String converted = this.converter.convert(this.event); - assertThat(converted).isEqualTo(""); - }); - } - - @Test - void whenLoggedApplicationNameConvertReturnsIt() { - withLoggedApplicationName("my-application", () -> { - this.converter.start(); - String converted = this.converter.convert(this.event); - assertThat(converted).isEqualTo("my-application"); - }); - } - - private void withLoggedApplicationName(String name, Runnable action) { - if (name == null) { - System.clearProperty(LoggingSystemProperty.APPLICATION_NAME.getEnvironmentVariableName()); - } - else { - System.setProperty(LoggingSystemProperty.APPLICATION_NAME.getEnvironmentVariableName(), name); - } - try { - action.run(); - } - finally { - System.clearProperty(LoggingSystemProperty.APPLICATION_NAME.getEnvironmentVariableName()); - } - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java index 342cf6a88399..9f251df2e354 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java @@ -301,18 +301,6 @@ void getLoggerConfigurationForLoggerThatDoesNotExistShouldReturnNull() { assertThat(configuration).isNull(); } - @Test - @Deprecated(since = "3.3.5", forRemoval = true) - void getLoggerConfigurationForALL() { - this.loggingSystem.beforeInitialize(); - initialize(this.initializationContext, null, null); - Logger logger = (Logger) LoggerFactory.getILoggerFactory().getLogger(getClass().getName()); - logger.setLevel(Level.ALL); - LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(getClass().getName()); - assertThat(configuration) - .isEqualTo(new LoggerConfiguration(getClass().getName(), LogLevel.TRACE, LogLevel.TRACE)); - } - @Test void systemLevelTraceShouldReturnNativeLevelTraceNotAll() { this.loggingSystem.beforeInitialize(); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/AbstractClientHttpRequestFactoriesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/AbstractClientHttpRequestFactoriesTests.java deleted file mode 100644 index e9c13f3e26bb..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/AbstractClientHttpRequestFactoriesTests.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.time.Duration; - -import javax.net.ssl.SSLHandshakeException; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.junit.jupiter.api.Assumptions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslBundleKey; -import org.springframework.boot.ssl.jks.JksSslStoreBundle; -import org.springframework.boot.ssl.jks.JksSslStoreDetails; -import org.springframework.boot.testsupport.classpath.resources.WithPackageResources; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.Ssl; -import org.springframework.boot.web.server.Ssl.ClientAuth; -import org.springframework.boot.web.server.WebServer; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * Base classes for testing of {@link ClientHttpRequestFactories} with different HTTP - * clients on the classpath. - * - * @param the {@link ClientHttpRequestFactory} to be produced - * @author Andy Wilkinson - */ -@DirtiesUrlFactories -@SuppressWarnings("removal") -abstract class AbstractClientHttpRequestFactoriesTests { - - private final Class requestFactoryType; - - protected AbstractClientHttpRequestFactoriesTests(Class requestFactoryType) { - this.requestFactoryType = requestFactoryType; - } - - @Test - @SuppressWarnings("deprecation") - void getReturnsRequestFactoryOfExpectedType() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories - .get(ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(this.requestFactoryType); - } - - @Test - @SuppressWarnings("deprecation") - void getOfGeneralTypeReturnsRequestFactoryOfExpectedType() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(ClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(this.requestFactoryType); - } - - @Test - @SuppressWarnings("deprecation") - void getOfSpecificTypeReturnsRequestFactoryOfExpectedType() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(this.requestFactoryType, - ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(this.requestFactoryType); - } - - @Test - @SuppressWarnings({ "deprecation", "unchecked" }) - void getReturnsRequestFactoryWithConfiguredConnectTimeout() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories - .get(ClientHttpRequestFactorySettings.DEFAULTS.withConnectTimeout(Duration.ofSeconds(60))); - assertThat(connectTimeout((T) requestFactory)).isEqualTo(Duration.ofSeconds(60).toMillis()); - } - - @Test - @SuppressWarnings({ "deprecation", "unchecked" }) - void getReturnsRequestFactoryWithConfiguredReadTimeout() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories - .get(ClientHttpRequestFactorySettings.DEFAULTS.withReadTimeout(Duration.ofSeconds(120))); - assertThat(readTimeout((T) requestFactory)).isEqualTo(Duration.ofSeconds(120).toMillis()); - } - - @Test - @SuppressWarnings("deprecation") - void shouldSetConnectTimeoutsWhenUsingReflective() { - Assumptions.assumeTrue(supportsSettingConnectTimeout()); - ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS - .withConnectTimeout(Duration.ofSeconds(1)); - T requestFactory = ClientHttpRequestFactories - .get(() -> ClientHttpRequestFactories.get(this.requestFactoryType, settings), settings); - assertThat(connectTimeout(requestFactory)).isEqualTo(1000); - } - - @Test - @SuppressWarnings("deprecation") - void shouldSetReadTimeoutsWhenUsingReflective() { - Assumptions.assumeTrue(supportsSettingReadTimeout()); - ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS - .withReadTimeout(Duration.ofSeconds(2)); - T requestFactory = ClientHttpRequestFactories - .get(() -> ClientHttpRequestFactories.get(this.requestFactoryType, settings), settings); - assertThat(readTimeout(requestFactory)).isEqualTo(2000); - } - - @ParameterizedTest - @SuppressWarnings("deprecation") - @ValueSource(strings = { "GET", "POST" }) - @WithPackageResources("test.jks") - void connectWithSslBundle(String httpMethod) throws Exception { - TomcatServletWebServerFactory webServerFactory = new TomcatServletWebServerFactory(0); - Ssl ssl = new Ssl(); - ssl.setClientAuth(ClientAuth.NEED); - ssl.setKeyPassword("password"); - ssl.setKeyStore("classpath:test.jks"); - ssl.setTrustStore("classpath:test.jks"); - webServerFactory.setSsl(ssl); - WebServer webServer = webServerFactory - .getWebServer((context) -> context.addServlet("test", TestServlet.class).addMapping("/")); - try { - webServer.start(); - int port = webServer.getPort(); - URI uri = new URI("https://localhost:%s".formatted(port)); - ClientHttpRequestFactory insecureRequestFactory = ClientHttpRequestFactories - .get(ClientHttpRequestFactorySettings.DEFAULTS); - ClientHttpRequest insecureRequest = insecureRequestFactory.createRequest(uri, HttpMethod.GET); - assertThatExceptionOfType(SSLHandshakeException.class) - .isThrownBy(() -> insecureRequest.execute().getBody()); - JksSslStoreDetails storeDetails = JksSslStoreDetails.forLocation("classpath:test.jks"); - JksSslStoreBundle stores = new JksSslStoreBundle(storeDetails, storeDetails); - SslBundle sslBundle = SslBundle.of(stores, SslBundleKey.of("password")); - ClientHttpRequestFactory secureRequestFactory = ClientHttpRequestFactories - .get(ClientHttpRequestFactorySettings.DEFAULTS.withSslBundle(sslBundle)); - ClientHttpRequest secureRequest = secureRequestFactory.createRequest(uri, HttpMethod.valueOf(httpMethod)); - String secureResponse = StreamUtils.copyToString(secureRequest.execute().getBody(), StandardCharsets.UTF_8); - assertThat(secureResponse).contains("Received " + httpMethod + " request to /"); - } - finally { - webServer.stop(); - } - } - - protected abstract boolean supportsSettingConnectTimeout(); - - protected abstract long connectTimeout(T requestFactory); - - protected abstract boolean supportsSettingReadTimeout(); - - protected abstract long readTimeout(T requestFactory); - - public static class TestServlet extends HttpServlet { - - @Override - public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { - res.getWriter().println("Received " + req.getMethod() + " request to " + req.getRequestURI()); - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesHttpComponentsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesHttpComponentsTests.java deleted file mode 100644 index 336e1286b7b3..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesHttpComponentsTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import org.apache.hc.client5.http.HttpRoute; -import org.apache.hc.client5.http.classic.HttpClient; -import org.apache.hc.core5.function.Resolver; -import org.apache.hc.core5.http.io.SocketConfig; - -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.test.util.ReflectionTestUtils; - -/** - * Tests for {@link ClientHttpRequestFactories} when Apache Http Components is the - * predominant HTTP client. - * - * @author Andy Wilkinson - */ -@SuppressWarnings("removal") -class ClientHttpRequestFactoriesHttpComponentsTests - extends AbstractClientHttpRequestFactoriesTests { - - ClientHttpRequestFactoriesHttpComponentsTests() { - super(HttpComponentsClientHttpRequestFactory.class); - } - - @Override - protected long connectTimeout(HttpComponentsClientHttpRequestFactory requestFactory) { - return (long) ReflectionTestUtils.getField(requestFactory, "connectTimeout"); - } - - @Override - @SuppressWarnings("unchecked") - protected long readTimeout(HttpComponentsClientHttpRequestFactory requestFactory) { - HttpClient httpClient = requestFactory.getHttpClient(); - Object connectionManager = ReflectionTestUtils.getField(httpClient, "connManager"); - SocketConfig socketConfig = ((Resolver) ReflectionTestUtils.getField(connectionManager, - "socketConfigResolver")) - .resolve(null); - return socketConfig.getSoTimeout().toMilliseconds(); - } - - @Override - protected boolean supportsSettingConnectTimeout() { - return true; - } - - @Override - protected boolean supportsSettingReadTimeout() { - return false; - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesJettyTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesJettyTests.java deleted file mode 100644 index 1bebc6a8f2ff..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesJettyTests.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import org.eclipse.jetty.client.HttpClient; - -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.http.client.JettyClientHttpRequestFactory; -import org.springframework.test.util.ReflectionTestUtils; - -/** - * Tests for {@link ClientHttpRequestFactories} when Jetty is the predominant HTTP client. - * - * @author Arjen Poutsma - */ -@ClassPathExclusions("httpclient5-*.jar") -@SuppressWarnings("removal") -class ClientHttpRequestFactoriesJettyTests - extends AbstractClientHttpRequestFactoriesTests { - - ClientHttpRequestFactoriesJettyTests() { - super(JettyClientHttpRequestFactory.class); - } - - @Override - protected long connectTimeout(JettyClientHttpRequestFactory requestFactory) { - return ((HttpClient) ReflectionTestUtils.getField(requestFactory, "httpClient")).getConnectTimeout(); - } - - @Override - protected long readTimeout(JettyClientHttpRequestFactory requestFactory) { - return (long) ReflectionTestUtils.getField(requestFactory, "readTimeout"); - } - - @Override - protected boolean supportsSettingConnectTimeout() { - return true; - } - - @Override - protected boolean supportsSettingReadTimeout() { - return true; - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesReactorTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesReactorTests.java deleted file mode 100644 index 79063d4a46ae..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesReactorTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import java.time.Duration; - -import io.netty.channel.ChannelOption; -import reactor.netty.http.client.HttpClient; - -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.http.client.ReactorClientHttpRequestFactory; -import org.springframework.test.util.ReflectionTestUtils; - -/** - * Tests for {@link ClientHttpRequestFactories} when Reactor Netty is the predominant HTTP - * client. - * - * @author Andy Wilkinson - */ -@ClassPathExclusions({ "httpclient5-*.jar", "jetty-client-*.jar" }) -@SuppressWarnings("removal") -class ClientHttpRequestFactoriesReactorTests - extends AbstractClientHttpRequestFactoriesTests { - - ClientHttpRequestFactoriesReactorTests() { - super(ReactorClientHttpRequestFactory.class); - } - - @Override - protected long connectTimeout(ReactorClientHttpRequestFactory requestFactory) { - return (int) ((HttpClient) ReflectionTestUtils.getField(requestFactory, "httpClient")).configuration() - .options() - .get(ChannelOption.CONNECT_TIMEOUT_MILLIS); - } - - @Override - protected long readTimeout(ReactorClientHttpRequestFactory requestFactory) { - return ((Duration) ReflectionTestUtils.getField(requestFactory, "readTimeout")).toMillis(); - } - - @Override - protected boolean supportsSettingConnectTimeout() { - return true; - } - - @Override - protected boolean supportsSettingReadTimeout() { - return true; - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesSimpleTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesSimpleTests.java deleted file mode 100644 index b697d7029009..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesSimpleTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.test.util.ReflectionTestUtils; - -/** - * Tests for {@link ClientHttpRequestFactories} when the simple JDK-based client is the - * predominant HTTP client. - * - * @author Andy Wilkinson - */ -@ClassPathExclusions({ "httpclient5-*.jar", "jetty-client-*.jar", "reactor-netty-http-*.jar" }) -@SuppressWarnings("removal") -class ClientHttpRequestFactoriesSimpleTests - extends AbstractClientHttpRequestFactoriesTests { - - ClientHttpRequestFactoriesSimpleTests() { - super(SimpleClientHttpRequestFactory.class); - } - - @Override - protected long connectTimeout(SimpleClientHttpRequestFactory requestFactory) { - return (int) ReflectionTestUtils.getField(requestFactory, "connectTimeout"); - } - - @Override - protected long readTimeout(SimpleClientHttpRequestFactory requestFactory) { - return (int) ReflectionTestUtils.getField(requestFactory, "readTimeout"); - } - - @Override - protected boolean supportsSettingConnectTimeout() { - return true; - } - - @Override - protected boolean supportsSettingReadTimeout() { - return true; - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesTests.java deleted file mode 100644 index a1b6aff1ba0e..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesTests.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import java.net.URI; -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -import org.springframework.http.HttpMethod; -import org.springframework.http.client.BufferingClientHttpRequestFactory; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.http.client.JdkClientHttpRequestFactory; -import org.springframework.http.client.ReactorClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link ClientHttpRequestFactories}. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class ClientHttpRequestFactoriesTests { - - @Test - void getReturnsRequestFactoryOfExpectedType() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories - .get(ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(HttpComponentsClientHttpRequestFactory.class); - } - - @Test - void getOfGeneralTypeReturnsRequestFactoryOfExpectedType() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(ClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(HttpComponentsClientHttpRequestFactory.class); - } - - @Test - void getOfSimpleFactoryReturnsSimpleFactory() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(SimpleClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(SimpleClientHttpRequestFactory.class); - } - - @Test - void getOfHttpComponentsFactoryReturnsHttpComponentsFactory() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories - .get(HttpComponentsClientHttpRequestFactory.class, ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(HttpComponentsClientHttpRequestFactory.class); - } - - @Test - void getOfReactorFactoryReturnsReactorFactory() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(ReactorClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(ReactorClientHttpRequestFactory.class); - } - - @Test - void getOfJdkFactoryReturnsJdkFactory() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(JdkClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(JdkClientHttpRequestFactory.class); - } - - @Test - void getOfUnknownTypeCreatesFactory() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(TestClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS); - assertThat(requestFactory).isInstanceOf(TestClientHttpRequestFactory.class); - } - - @Test - void getOfUnknownTypeWithConnectTimeoutCreatesFactoryAndConfiguresConnectTimeout() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(TestClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS.withConnectTimeout(Duration.ofSeconds(60))); - assertThat(requestFactory).isInstanceOf(TestClientHttpRequestFactory.class); - assertThat(((TestClientHttpRequestFactory) requestFactory).connectTimeout) - .isEqualTo(Duration.ofSeconds(60).toMillis()); - } - - @Test - void getOfUnknownTypeWithReadTimeoutCreatesFactoryAndConfiguresReadTimeout() { - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(TestClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS.withReadTimeout(Duration.ofSeconds(90))); - assertThat(requestFactory).isInstanceOf(TestClientHttpRequestFactory.class); - assertThat(((TestClientHttpRequestFactory) requestFactory).readTimeout) - .isEqualTo(Duration.ofSeconds(90).toMillis()); - } - - @Test - void getOfUnconfigurableTypeWithConnectTimeoutThrows() { - assertThatIllegalStateException() - .isThrownBy(() -> ClientHttpRequestFactories.get(UnconfigurableClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS.withConnectTimeout(Duration.ofSeconds(60)))) - .withMessageContaining("suitable setConnectTimeout method"); - } - - @Test - void getOfUnconfigurableTypeWithReadTimeoutThrows() { - assertThatIllegalStateException() - .isThrownBy(() -> ClientHttpRequestFactories.get(UnconfigurableClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS.withReadTimeout(Duration.ofSeconds(60)))) - .withMessageContaining("suitable setReadTimeout method"); - } - - @Test - void getOfTypeWithDeprecatedConnectTimeoutThrowsWithConnectTimeout() { - assertThatIllegalStateException() - .isThrownBy(() -> ClientHttpRequestFactories.get(DeprecatedMethodsClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS.withConnectTimeout(Duration.ofSeconds(60)))) - .withMessageContaining("setConnectTimeout method marked as deprecated"); - } - - @Test - void getOfTypeWithDeprecatedReadTimeoutThrowsWithReadTimeout() { - assertThatIllegalStateException() - .isThrownBy(() -> ClientHttpRequestFactories.get(DeprecatedMethodsClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS.withReadTimeout(Duration.ofSeconds(60)))) - .withMessageContaining("setReadTimeout method marked as deprecated"); - } - - @Test - void connectTimeoutCanBeConfiguredOnAWrappedRequestFactory() { - SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); - BufferingClientHttpRequestFactory result = ClientHttpRequestFactories.get( - () -> new BufferingClientHttpRequestFactory(requestFactory), - ClientHttpRequestFactorySettings.DEFAULTS.withConnectTimeout(Duration.ofMillis(1234))); - assertThat(result).extracting("requestFactory").isSameAs(requestFactory); - assertThat(requestFactory).hasFieldOrPropertyWithValue("connectTimeout", 1234); - } - - @Test - void readTimeoutCanBeConfiguredOnAWrappedRequestFactory() { - SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); - BufferingClientHttpRequestFactory result = ClientHttpRequestFactories.get( - () -> new BufferingClientHttpRequestFactory(requestFactory), - ClientHttpRequestFactorySettings.DEFAULTS.withReadTimeout(Duration.ofMillis(1234))); - assertThat(result).extracting("requestFactory").isSameAs(requestFactory); - assertThat(requestFactory).hasFieldOrPropertyWithValue("readTimeout", 1234); - } - - @Test - void reflectiveShouldFavorDurationTimeoutMethods() { - IntAndDurationTimeoutsClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get( - IntAndDurationTimeoutsClientHttpRequestFactory.class, - ClientHttpRequestFactorySettings.DEFAULTS.withConnectTimeout(Duration.ofSeconds(1)) - .withReadTimeout(Duration.ofSeconds(2))); - assertThat((requestFactory).connectTimeout).isZero(); - assertThat((requestFactory).readTimeout).isZero(); - assertThat((requestFactory).connectTimeoutDuration).isEqualTo(Duration.ofSeconds(1)); - assertThat((requestFactory).readTimeoutDuration).isEqualTo(Duration.ofSeconds(2)); - } - - public static class TestClientHttpRequestFactory implements ClientHttpRequestFactory { - - private int connectTimeout; - - private int readTimeout; - - @Override - public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { - throw new UnsupportedOperationException(); - } - - public void setConnectTimeout(int timeout) { - this.connectTimeout = timeout; - } - - public void setReadTimeout(int timeout) { - this.readTimeout = timeout; - } - - } - - public static class UnconfigurableClientHttpRequestFactory implements ClientHttpRequestFactory { - - @Override - public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { - throw new UnsupportedOperationException(); - } - - } - - public static class DeprecatedMethodsClientHttpRequestFactory implements ClientHttpRequestFactory { - - @Override - public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { - throw new UnsupportedOperationException(); - } - - @Deprecated(since = "3.0.0", forRemoval = false) - public void setConnectTimeout(int timeout) { - } - - @Deprecated(since = "3.0.0", forRemoval = false) - public void setReadTimeout(int timeout) { - } - - @Deprecated(since = "3.0.0", forRemoval = false) - public void setBufferRequestBody(boolean bufferRequestBody) { - } - - } - - public static class IntAndDurationTimeoutsClientHttpRequestFactory implements ClientHttpRequestFactory { - - private int readTimeout; - - private int connectTimeout; - - private Duration readTimeoutDuration; - - private Duration connectTimeoutDuration; - - @Override - public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { - throw new UnsupportedOperationException(); - } - - public void setConnectTimeout(int timeout) { - this.connectTimeout = timeout; - } - - public void setReadTimeout(int timeout) { - this.readTimeout = timeout; - } - - public void setConnectTimeout(Duration timeout) { - this.connectTimeoutDuration = timeout; - } - - public void setReadTimeout(Duration timeout) { - this.readTimeoutDuration = timeout; - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettingsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettingsTests.java deleted file mode 100644 index 2798f61da406..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettingsTests.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.client; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.ssl.SslBundle; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ClientHttpRequestFactorySettings}. - * - * @author Phillip Webb - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class ClientHttpRequestFactorySettingsTests { - - private static final Duration ONE_SECOND = Duration.ofSeconds(1); - - @Test - void defaultsHasNullValues() { - ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS; - assertThat(settings.connectTimeout()).isNull(); - assertThat(settings.readTimeout()).isNull(); - assertThat(settings.sslBundle()).isNull(); - } - - @Test - void withConnectTimeoutReturnsInstanceWithUpdatedConnectionTimeout() { - ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS - .withConnectTimeout(ONE_SECOND); - assertThat(settings.connectTimeout()).isEqualTo(ONE_SECOND); - assertThat(settings.readTimeout()).isNull(); - assertThat(settings.sslBundle()).isNull(); - } - - @Test - void withReadTimeoutReturnsInstanceWithUpdatedReadTimeout() { - ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS - .withReadTimeout(ONE_SECOND); - assertThat(settings.connectTimeout()).isNull(); - assertThat(settings.readTimeout()).isEqualTo(ONE_SECOND); - assertThat(settings.sslBundle()).isNull(); - } - - @Test - void withSslBundleReturnsInstanceWithUpdatedSslBundle() { - SslBundle sslBundle = mock(SslBundle.class); - ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS.withSslBundle(sslBundle); - assertThat(settings.connectTimeout()).isNull(); - assertThat(settings.readTimeout()).isNull(); - assertThat(settings.sslBundle()).isSameAs(sslBundle); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResourceFilePathResolverIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResourceFilePathResolverIntegrationTests.java similarity index 94% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResourceFilePathResolverIntegrationTests.java rename to spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResourceFilePathResolverIntegrationTests.java index ae86edcf5349..98fed1a28b9a 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/FilteredReactiveWebContextResourceFilePathResolverIntegrationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/reactive/FilteredReactiveWebContextResourceFilePathResolverIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import java.io.File; @@ -51,7 +51,7 @@ void getResourceWhenFilteredReactiveWebContextResource() { .get(new AnnotationConfigReactiveWebApplicationContext(), false); Resource resource = resourceLoader.getResource("src/main/resources/a-file"); assertThat(resource).isInstanceOf(ClassUtils.resolveClassName( - "org.springframework.boot.web.reactive.context.FilteredReactiveWebContextResource", null)); + "org.springframework.boot.web.context.reactive.FilteredReactiveWebContextResource", null)); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContextTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/reactive/GenericReactiveWebApplicationContextTests.java similarity index 95% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContextTests.java rename to spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/reactive/GenericReactiveWebApplicationContextTests.java index b30d1f7facc7..0e2e899fc065 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContextTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/reactive/GenericReactiveWebApplicationContextTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.reactive.context; +package org.springframework.boot.web.context.reactive; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletContextResourceFilePathResolverIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/servlet/ServletContextResourceFilePathResolverIntegrationTests.java similarity index 97% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletContextResourceFilePathResolverIntegrationTests.java rename to spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/servlet/ServletContextResourceFilePathResolverIntegrationTests.java index 156d892ea70f..f612c8bc8a06 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletContextResourceFilePathResolverIntegrationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/servlet/ServletContextResourceFilePathResolverIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.servlet.context; +package org.springframework.boot.web.context.servlet; import java.io.File; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributesTests.java deleted file mode 100644 index 52f2b7e6a977..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributesTests.java +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.error; - -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.core.MethodParameter; -import org.springframework.http.HttpStatus; -import org.springframework.http.codec.HttpMessageReader; -import org.springframework.http.codec.ServerCodecConfigurer; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.web.server.MockServerWebExchange; -import org.springframework.validation.BindingResult; -import org.springframework.validation.MapBindingResult; -import org.springframework.validation.ObjectError; -import org.springframework.validation.method.MethodValidationResult; -import org.springframework.validation.method.ParameterValidationResult; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.support.WebExchangeBindException; -import org.springframework.web.method.annotation.HandlerMethodValidationException; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.server.ResponseStatusException; -import org.springframework.web.server.ServerWebExchange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link DefaultErrorAttributes}. - * - * @author Brian Clozel - * @author Stephane Nicoll - * @author Scott Frederick - * @author Moritz Halbritter - * @author Yanming Zhou - * @author Yongjun Hong - */ -class DefaultErrorAttributesTests { - - private static final ResponseStatusException NOT_FOUND = new ResponseStatusException(HttpStatus.NOT_FOUND); - - private DefaultErrorAttributes errorAttributes = new DefaultErrorAttributes(); - - private final List> readers = ServerCodecConfigurer.create().getReaders(); - - @Test - void missingExceptionAttribute() { - MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test").build()); - ServerRequest request = ServerRequest.create(exchange, this.readers); - assertThatIllegalStateException() - .isThrownBy(() -> this.errorAttributes.getErrorAttributes(request, ErrorAttributeOptions.defaults())) - .withMessageContaining("Missing exception attribute in ServerWebExchange"); - } - - @Test - void includeTimeStamp() { - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), - ErrorAttributeOptions.defaults()); - assertThat(attributes.get("timestamp")).isInstanceOf(Date.class); - } - - @Test - void defaultStatusCode() { - Error error = new OutOfMemoryError("Test error"); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), - ErrorAttributeOptions.defaults()); - assertThat(attributes).containsEntry("error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); - assertThat(attributes).containsEntry("status", 500); - } - - @Test - void annotatedResponseStatusCode() { - Exception error = new CustomException(); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), - ErrorAttributeOptions.defaults()); - assertThat(attributes).containsEntry("error", HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); - assertThat(attributes).doesNotContainKey("message"); - assertThat(attributes).containsEntry("status", HttpStatus.I_AM_A_TEAPOT.value()); - } - - @Test - void annotatedResponseStatusCodeWithExceptionMessage() { - Exception error = new CustomException("Test Message"); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), - ErrorAttributeOptions.of(Include.MESSAGE, Include.STATUS, Include.ERROR)); - assertThat(attributes).containsEntry("error", HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); - assertThat(attributes).containsEntry("message", "Test Message"); - assertThat(attributes).containsEntry("status", HttpStatus.I_AM_A_TEAPOT.value()); - } - - @Test - void annotatedResponseStatusCodeWithCustomReasonPhrase() { - Exception error = new Custom2Exception(); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), - ErrorAttributeOptions.of(Include.MESSAGE, Include.STATUS, Include.ERROR)); - assertThat(attributes).containsEntry("error", HttpStatus.I_AM_A_TEAPOT.getReasonPhrase()); - assertThat(attributes).containsEntry("status", HttpStatus.I_AM_A_TEAPOT.value()); - assertThat(attributes).containsEntry("message", "Nope!"); - } - - @Test - void includeStatusCode() { - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), - ErrorAttributeOptions.defaults()); - assertThat(attributes).containsEntry("error", HttpStatus.NOT_FOUND.getReasonPhrase()); - assertThat(attributes).containsEntry("status", 404); - } - - @Test - void getError() { - Error error = new OutOfMemoryError("Test error"); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - ServerRequest serverRequest = buildServerRequest(request, error); - Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, - ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).containsEntry("message", "Test error"); - } - - @Test - void excludeMessage() { - Error error = new OutOfMemoryError("Test error"); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - ServerRequest serverRequest = buildServerRequest(request, error); - Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, - ErrorAttributeOptions.defaults()); - assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); - assertThat(attributes).doesNotContainKey("message"); - } - - @Test - void includeException() { - RuntimeException error = new RuntimeException("Test"); - this.errorAttributes = new DefaultErrorAttributes(); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - ServerRequest serverRequest = buildServerRequest(request, error); - Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, - ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE)); - assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); - assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); - assertThat(attributes).containsEntry("message", "Test"); - } - - @Test - void processResponseStatusException() { - RuntimeException nested = new RuntimeException("Test"); - ResponseStatusException error = new ResponseStatusException(HttpStatus.BAD_REQUEST, "invalid request", nested); - this.errorAttributes = new DefaultErrorAttributes(); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - ServerRequest serverRequest = buildServerRequest(request, error); - Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, - ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE, Include.STATUS)); - assertThat(attributes).containsEntry("status", 400); - assertThat(attributes).containsEntry("message", "invalid request"); - assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); - assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); - } - - @Test - void processResponseStatusExceptionWithNoNestedCause() { - ResponseStatusException error = new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, - "could not process request"); - this.errorAttributes = new DefaultErrorAttributes(); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - ServerRequest serverRequest = buildServerRequest(request, error); - Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, - ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE, Include.STATUS)); - assertThat(attributes).containsEntry("status", 406); - assertThat(attributes).containsEntry("message", "could not process request"); - assertThat(attributes).containsEntry("exception", ResponseStatusException.class.getName()); - assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); - } - - @Test - void notIncludeTrace() { - RuntimeException ex = new RuntimeException("Test"); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), - ErrorAttributeOptions.defaults()); - assertThat(attributes).doesNotContainKey("trace"); - } - - @Test - void includeTrace() { - RuntimeException ex = new RuntimeException("Test"); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), - ErrorAttributeOptions.of(Include.STACK_TRACE)); - assertThat(attributes.get("trace").toString()).startsWith("java.lang"); - } - - @Test - void includePathByDefault() { - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), - ErrorAttributeOptions.defaults()); - assertThat(attributes).containsEntry("path", "/test"); - } - - @Test - void includePath() { - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), - ErrorAttributeOptions.of(Include.PATH)); - assertThat(attributes).containsEntry("path", "/test"); - } - - @Test - void pathShouldIncludeContext() { - MockServerHttpRequest request = MockServerHttpRequest.get("/context/test").contextPath("/context").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), - ErrorAttributeOptions.of(Include.PATH)); - assertThat(attributes).containsEntry("path", "/context/test"); - } - - @Test - void excludePath() { - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), - ErrorAttributeOptions.of()); - assertThat(attributes).doesNotContainEntry("path", "/test"); - } - - @Test - void includeLogPrefix() { - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - ServerRequest serverRequest = buildServerRequest(request, NOT_FOUND); - Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, - ErrorAttributeOptions.defaults()); - assertThat(attributes).containsEntry("requestId", serverRequest.exchange().getRequest().getId()); - } - - @Test - void extractBindingResultErrors() throws Exception { - Method method = getClass().getDeclaredMethod("method", String.class); - MethodParameter stringParam = new MethodParameter(method, 0); - BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); - bindingResult.addError(new ObjectError("c", "d")); - Exception ex = new WebExchangeBindException(stringParam, bindingResult); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), - ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); - assertThat(attributes.get("message")).asString() - .startsWith("Validation failed for argument at index 0 in method: " - + "int org.springframework.boot.web.reactive.error.DefaultErrorAttributesTests" - + ".method(java.lang.String), with 1 error(s)"); - assertThat(attributes).containsEntry("errors", - org.springframework.boot.web.error.Error.wrap(bindingResult.getAllErrors())); - } - - @Test - void extractBindingResultErrorsThatCausedAResponseStatusException() throws Exception { - Method method = getClass().getDeclaredMethod("method", String.class); - MethodParameter stringParam = new MethodParameter(method, 0); - BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); - bindingResult.addError(new ObjectError("c", "d")); - Exception ex = new WebExchangeBindException(stringParam, bindingResult); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes( - buildServerRequest(request, new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid", ex)), - ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); - assertThat(attributes.get("message")).isEqualTo("Invalid"); - assertThat(attributes).containsEntry("errors", - org.springframework.boot.web.error.Error.wrap(bindingResult.getAllErrors())); - } - - @Test - void extractMethodValidationResultErrors() throws Exception { - Object target = "test"; - Method method = String.class.getMethod("substring", int.class); - MethodParameter parameter = new MethodParameter(method, 0); - MethodValidationResult methodValidationResult = MethodValidationResult.create(target, method, - List.of(new ParameterValidationResult(parameter, -1, - List.of(new ObjectError("beginIndex", "beginIndex is negative")), null, null, null, - (error, sourceType) -> { - throw new IllegalArgumentException("No source object of the given type"); - }))); - HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), - ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); - assertThat(attributes.get("message")).asString() - .isEqualTo( - "Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1"); - assertThat(attributes).containsEntry("errors", - org.springframework.boot.web.error.Error.wrap(methodValidationResult.getAllErrors())); - } - - @Test - void extractBindingResultErrorsExcludeMessageAndErrors() throws Exception { - Method method = getClass().getDeclaredMethod("method", String.class); - MethodParameter stringParam = new MethodParameter(method, 0); - BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); - bindingResult.addError(new ObjectError("c", "d")); - Exception ex = new WebExchangeBindException(stringParam, bindingResult); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), - ErrorAttributeOptions.defaults()); - assertThat(attributes).doesNotContainKey("message"); - assertThat(attributes).doesNotContainKey("errors"); - } - - @Test - void extractParameterValidationResultErrors() throws Exception { - Object target = "test"; - Method method = String.class.getMethod("substring", int.class); - MethodParameter parameter = new MethodParameter(method, 0); - ParameterValidationResult parameterValidationResult = new ParameterValidationResult(parameter, -1, - List.of(new ObjectError("beginIndex", "beginIndex is negative")), null, null, null, - (error, sourceType) -> { - throw new IllegalArgumentException("No source object of the given type"); - }); - MethodValidationResult methodValidationResult = MethodValidationResult.create(target, method, - List.of(parameterValidationResult)); - HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - Map attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), - ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); - assertThat(attributes.get("message")).asString() - .isEqualTo( - "Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1"); - assertThat(attributes).containsEntry("errors", - org.springframework.boot.web.error.Error.wrap(methodValidationResult.getAllErrors())); - } - - @Test - void excludeStatus() { - ResponseStatusException error = new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, - "could not process request"); - this.errorAttributes = new DefaultErrorAttributes(); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - ServerRequest serverRequest = buildServerRequest(request, error); - Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, - ErrorAttributeOptions.defaults().excluding(Include.STATUS)); - assertThat(attributes).doesNotContainKey("status"); - } - - @Test - void excludeError() { - ResponseStatusException error = new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, - "could not process request"); - this.errorAttributes = new DefaultErrorAttributes(); - MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); - ServerRequest serverRequest = buildServerRequest(request, error); - Map attributes = this.errorAttributes.getErrorAttributes(serverRequest, - ErrorAttributeOptions.defaults().excluding(Include.ERROR)); - assertThat(attributes).doesNotContainKey("error"); - } - - private ServerRequest buildServerRequest(MockServerHttpRequest request, Throwable error) { - ServerWebExchange exchange = MockServerWebExchange.from(request); - this.errorAttributes.storeErrorInformation(error, exchange); - return ServerRequest.create(exchange, this.readers); - } - - int method(String firstParam) { - return 42; - } - - @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) - static class CustomException extends RuntimeException { - - CustomException() { - } - - CustomException(String message) { - super(message); - } - - } - - @ResponseStatus(value = HttpStatus.I_AM_A_TEAPOT, reason = "Nope!") - static class Custom2Exception extends RuntimeException { - - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/result/view/MustacheViewResolverTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/result/view/MustacheViewResolverTests.java deleted file mode 100644 index 8acc22846b5c..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/result/view/MustacheViewResolverTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.result.view; - -import java.time.Duration; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.context.support.GenericApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MustacheViewResolver}. - * - * @author Brian Clozel - */ -class MustacheViewResolverTests { - - private final MustacheViewResolver resolver = new MustacheViewResolver(); - - @BeforeEach - void init() { - GenericApplicationContext applicationContext = new GenericApplicationContext(); - applicationContext.refresh(); - this.resolver.setApplicationContext(applicationContext); - this.resolver.setPrefix("classpath:"); - this.resolver.setSuffix(".html"); - } - - @Test - void resolveNonExistent() { - assertThat(this.resolver.resolveViewName("bar", null).block(Duration.ofSeconds(30))).isNull(); - } - - @Test - @WithResource(name = "template.html", content = "Hello {{World}}") - void resolveExisting() { - assertThat(this.resolver.resolveViewName("template", null).block(Duration.ofSeconds(30))).isNotNull(); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/result/view/MustacheViewTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/result/view/MustacheViewTests.java deleted file mode 100644 index b7548d9e18f5..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/result/view/MustacheViewTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.reactive.result.view; - -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.Collections; - -import com.samskivert.mustache.Mustache; -import org.junit.jupiter.api.Test; -import reactor.test.StepVerifier; - -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.context.support.StaticApplicationContext; -import org.springframework.http.MediaType; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.web.server.MockServerWebExchange; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MustacheView}. - * - * @author Brian Clozel - */ -class MustacheViewTests { - - private final StaticApplicationContext context = new StaticApplicationContext(); - - @Test - @WithResource(name = "template.html", content = "Hello {{World}}") - void viewResolvesHandlebars() { - MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test").build()); - MustacheView view = new MustacheView(); - view.setCompiler(Mustache.compiler()); - view.setUrl("classpath:template.html"); - view.setCharset(StandardCharsets.UTF_8.displayName()); - view.setApplicationContext(this.context); - view.render(Collections.singletonMap("World", "Spring"), MediaType.TEXT_HTML, exchange) - .block(Duration.ofSeconds(30)); - StepVerifier.create(exchange.getResponse().getBodyAsString()) - .assertNext((body) -> assertThat(body).isEqualToIgnoringWhitespace("Hello Spring")) - .expectComplete() - .verify(Duration.ofSeconds(30)); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/FilterRegistrationIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/FilterRegistrationIntegrationTests.java index fc9acf550353..b6da2db8252d 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/FilterRegistrationIntegrationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/FilterRegistrationIntegrationTests.java @@ -16,17 +16,26 @@ package org.springframework.boot.web.servlet; +import java.util.Collections; + import jakarta.servlet.Filter; +import jakarta.servlet.FilterRegistration.Dynamic; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.boot.web.context.servlet.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.web.context.servlet.WebApplicationContextInitializer; import org.springframework.boot.web.servlet.mock.MockFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; /** * Integration tests for {@link Filter} registration. @@ -35,7 +44,7 @@ */ class FilterRegistrationIntegrationTests { - private AnnotationConfigServletWebServerApplicationContext context; + private AnnotationConfigServletWebApplicationContext context; @AfterEach void cleanUp() { @@ -47,28 +56,31 @@ void cleanUp() { @Test void normalFiltersAreRegistered() { load(FilterConfiguration.class); - assertThat(this.context.getServletContext().getFilterRegistrations()).hasSize(1); + then(this.context.getServletContext()).should() + .addFilter("myFilter", this.context.getBean("myFilter", MockFilter.class)); } @Test void scopedTargetFiltersAreNotRegistered() { load(ScopedTargetFilterConfiguration.class); - assertThat(this.context.getServletContext().getFilterRegistrations()).isEmpty(); + then(this.context.getServletContext()).should(times(0)).addFilter(any(String.class), any(Filter.class)); } private void load(Class configuration) { - this.context = new AnnotationConfigServletWebServerApplicationContext(ContainerConfiguration.class, - configuration); - } - - @Configuration(proxyBeanMethods = false) - static class ContainerConfiguration { - - @Bean - TomcatServletWebServerFactory webServerFactory() { - return new TomcatServletWebServerFactory(0); + ServletContext servletContext = mock(ServletContext.class); + given(servletContext.addFilter(any(), any(Filter.class))).willReturn(mock(Dynamic.class)); + given(servletContext.getInitParameterNames()).willReturn(Collections.emptyEnumeration()); + given(servletContext.getAttributeNames()).willReturn(Collections.emptyEnumeration()); + this.context = new AnnotationConfigServletWebApplicationContext(); + this.context.setServletContext(servletContext); + this.context.register(configuration); + this.context.refresh(); + try { + new WebApplicationContextInitializer(this.context).initialize(servletContext); + } + catch (ServletException ex) { + throw new RuntimeException(ex); } - } @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanIntegrationTests.java deleted file mode 100644 index f63d69e682d5..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanIntegrationTests.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.Map; -import java.util.Properties; -import java.util.stream.Stream; - -import jakarta.servlet.MultipartConfigElement; -import jakarta.servlet.annotation.WebFilter; -import jakarta.servlet.annotation.WebListener; -import jakarta.servlet.annotation.WebServlet; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.io.TempDir; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.testsupport.classpath.ForkedClassPath; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.boot.web.servlet.testcomponents.filter.TestFilter; -import org.springframework.boot.web.servlet.testcomponents.listener.TestListener; -import org.springframework.boot.web.servlet.testcomponents.servlet.TestMultipartServlet; -import org.springframework.boot.web.servlet.testcomponents.servlet.TestServlet; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link ServletComponentScan @ServletComponentScan} - * - * @author Andy Wilkinson - */ -@DirtiesUrlFactories -class ServletComponentScanIntegrationTests { - - private AnnotationConfigServletWebServerApplicationContext context; - - @TempDir - File temp; - - @AfterEach - void cleanUp() { - if (this.context != null) { - this.context.close(); - } - } - - @ParameterizedTest(name = "{0}") - @MethodSource("testConfiguration") - @ForkedClassPath - void componentsAreRegistered(String serverName, Class configuration) { - this.context = new AnnotationConfigServletWebServerApplicationContext(); - this.context.register(configuration); - new ServerPortInfoApplicationContextInitializer().initialize(this.context); - this.context.refresh(); - String port = this.context.getEnvironment().getProperty("local.server.port"); - String response = new RestTemplate().getForObject("http://localhost:" + port + "/test", String.class); - assertThat(response).isEqualTo("alpha bravo charlie"); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("testConfiguration") - @ForkedClassPath - void indexedComponentsAreRegistered(String serverName, Class configuration) throws IOException { - writeIndex(this.temp); - this.context = new AnnotationConfigServletWebServerApplicationContext(); - try (URLClassLoader classLoader = new URLClassLoader(new URL[] { this.temp.toURI().toURL() }, - getClass().getClassLoader())) { - this.context.setClassLoader(classLoader); - this.context.register(configuration); - new ServerPortInfoApplicationContextInitializer().initialize(this.context); - this.context.refresh(); - String port = this.context.getEnvironment().getProperty("local.server.port"); - String response = new RestTemplate().getForObject("http://localhost:" + port + "/test", String.class); - assertThat(response).isEqualTo("alpha bravo charlie"); - } - } - - @ParameterizedTest(name = "{0}") - @MethodSource("testConfiguration") - @ForkedClassPath - void multipartConfigIsHonoured(String serverName, Class configuration) { - this.context = new AnnotationConfigServletWebServerApplicationContext(); - this.context.register(configuration); - new ServerPortInfoApplicationContextInitializer().initialize(this.context); - this.context.refresh(); - @SuppressWarnings("rawtypes") - Map beans = this.context.getBeansOfType(ServletRegistrationBean.class); - ServletRegistrationBean servletRegistrationBean = beans.get(TestMultipartServlet.class.getName()); - assertThat(servletRegistrationBean).isNotNull(); - MultipartConfigElement multipartConfig = servletRegistrationBean.getMultipartConfig(); - assertThat(multipartConfig).isNotNull(); - assertThat(multipartConfig.getLocation()).isEqualTo("test"); - assertThat(multipartConfig.getMaxRequestSize()).isEqualTo(2048); - assertThat(multipartConfig.getMaxFileSize()).isEqualTo(1024); - assertThat(multipartConfig.getFileSizeThreshold()).isEqualTo(512); - } - - private void writeIndex(File temp) throws IOException { - File metaInf = new File(temp, "META-INF"); - metaInf.mkdirs(); - Properties index = new Properties(); - index.setProperty(TestFilter.class.getName(), WebFilter.class.getName()); - index.setProperty(TestListener.class.getName(), WebListener.class.getName()); - index.setProperty(TestServlet.class.getName(), WebServlet.class.getName()); - try (FileWriter writer = new FileWriter(new File(metaInf, "spring.components"))) { - index.store(writer, null); - } - } - - static Stream testConfiguration() { - return Stream.of(Arguments.of("Jetty", JettyTestConfiguration.class), - Arguments.of("Tomcat", TomcatTestConfiguration.class), - Arguments.of("Undertow", UndertowTestConfiguration.class)); - } - - @ServletComponentScan(basePackages = "org.springframework.boot.web.servlet.testcomponents") - abstract static class AbstractTestConfiguration { - - @Bean - protected ServletWebServerFactory webServerFactory(ObjectProvider webListenerRegistrars) { - ConfigurableServletWebServerFactory factory = createWebServerFactory(); - webListenerRegistrars.orderedStream().forEach((registrar) -> registrar.register(factory)); - return factory; - } - - abstract ConfigurableServletWebServerFactory createWebServerFactory(); - - } - - @Configuration(proxyBeanMethods = false) - static class JettyTestConfiguration extends AbstractTestConfiguration { - - @Override - ConfigurableServletWebServerFactory createWebServerFactory() { - return new JettyServletWebServerFactory(0); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TomcatTestConfiguration extends AbstractTestConfiguration { - - @Override - ConfigurableServletWebServerFactory createWebServerFactory() { - return new TomcatServletWebServerFactory(0); - } - - } - - @Configuration(proxyBeanMethods = false) - static class UndertowTestConfiguration extends AbstractTestConfiguration { - - @Override - ConfigurableServletWebServerFactory createWebServerFactory() { - return new UndertowServletWebServerFactory(0); - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerMvcIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerMvcIntegrationTests.java deleted file mode 100644 index c8b4822d84db..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/ServletWebServerMvcIntegrationTests.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.context; - -import java.net.URI; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link ServletWebServerApplicationContext} and {@link WebServer}s - * running Spring MVC. - * - * @author Phillip Webb - * @author Ivan Sopov - */ -@DirtiesUrlFactories -class ServletWebServerMvcIntegrationTests { - - private AnnotationConfigServletWebServerApplicationContext context; - - @AfterEach - void closeContext() { - try { - this.context.close(); - } - catch (Exception ex) { - // Ignore - } - } - - @Test - void tomcat() throws Exception { - this.context = new AnnotationConfigServletWebServerApplicationContext(TomcatConfig.class); - doTest(this.context, "/hello"); - } - - @Test - void jetty() throws Exception { - this.context = new AnnotationConfigServletWebServerApplicationContext(JettyConfig.class); - doTest(this.context, "/hello"); - } - - @Test - void undertow() throws Exception { - this.context = new AnnotationConfigServletWebServerApplicationContext(UndertowConfig.class); - doTest(this.context, "/hello"); - } - - @Test - @WithResource(name = "conf.properties", content = "context=/example") - void advancedConfig() throws Exception { - this.context = new AnnotationConfigServletWebServerApplicationContext(AdvancedConfig.class); - doTest(this.context, "/example/spring/hello"); - } - - private void doTest(AnnotationConfigServletWebServerApplicationContext context, String resourcePath) - throws Exception { - SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory(); - ClientHttpRequest request = clientHttpRequestFactory.createRequest( - new URI("http://localhost:" + context.getWebServer().getPort() + resourcePath), HttpMethod.GET); - try (ClientHttpResponse response = request.execute()) { - assertThat(response.getBody()).hasContent("Hello World"); - } - } - - // Simple main method for testing in a browser - @SuppressWarnings("resource") - static void main(String[] args) { - new AnnotationConfigServletWebServerApplicationContext(JettyServletWebServerFactory.class, Config.class); - } - - @Configuration(proxyBeanMethods = false) - @Import(Config.class) - static class TomcatConfig { - - @Bean - ServletWebServerFactory webServerFactory() { - return new TomcatServletWebServerFactory(0); - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(Config.class) - static class JettyConfig { - - @Bean - ServletWebServerFactory webServerFactory() { - return new JettyServletWebServerFactory(0); - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(Config.class) - static class UndertowConfig { - - @Bean - ServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory(0); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableWebMvc - static class Config { - - @Bean - DispatcherServlet dispatcherServlet() { - return new DispatcherServlet(); - // Alternatively you can use ServletContextInitializer beans including - // ServletRegistration and FilterRegistration. Read the - // EmbeddedWebApplicationContext Javadoc for details. - } - - @Bean - HelloWorldController helloWorldController() { - return new HelloWorldController(); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableWebMvc - @PropertySource("classpath:conf.properties") - static class AdvancedConfig { - - private final Environment env; - - AdvancedConfig(Environment env) { - this.env = env; - } - - @Bean - ServletWebServerFactory webServerFactory() { - JettyServletWebServerFactory factory = new JettyServletWebServerFactory(0); - factory.setContextPath(this.env.getProperty("context")); - return factory; - } - - @Bean - ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) { - ServletRegistrationBean registration = new ServletRegistrationBean<>(dispatcherServlet); - registration.addUrlMappings("/spring/*"); - return registration; - } - - @Bean - DispatcherServlet dispatcherServlet() { - // Can configure dispatcher servlet here as would usually do through - // init-params - return new DispatcherServlet(); - } - - @Bean - HelloWorldController helloWorldController() { - return new HelloWorldController(); - } - - } - - @Controller - static class HelloWorldController { - - @RequestMapping("/hello") - @ResponseBody - String sayHello() { - return "Hello World"; - } - - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributesTests.java deleted file mode 100644 index f25b2473a129..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/error/DefaultErrorAttributesTests.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.error; - -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import jakarta.servlet.ServletException; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.error.ErrorAttributeOptions.Include; -import org.springframework.context.MessageSourceResolvable; -import org.springframework.core.MethodParameter; -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.util.ReflectionUtils; -import org.springframework.validation.BindException; -import org.springframework.validation.BindingResult; -import org.springframework.validation.MapBindingResult; -import org.springframework.validation.ObjectError; -import org.springframework.validation.method.MethodValidationResult; -import org.springframework.validation.method.ParameterValidationResult; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.context.request.ServletWebRequest; -import org.springframework.web.context.request.WebRequest; -import org.springframework.web.method.annotation.HandlerMethodValidationException; -import org.springframework.web.servlet.ModelAndView; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link DefaultErrorAttributes}. - * - * @author Phillip Webb - * @author Vedran Pavic - * @author Scott Frederick - * @author Moritz Halbritter - * @author Yanming Zhou - */ -class DefaultErrorAttributesTests { - - private final DefaultErrorAttributes errorAttributes = new DefaultErrorAttributes(); - - private final MockHttpServletRequest request = new MockHttpServletRequest(); - - private final WebRequest webRequest = new ServletWebRequest(this.request); - - @Test - void includeTimeStamp() { - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults()); - assertThat(attributes.get("timestamp")).isInstanceOf(Date.class); - } - - @Test - void specificStatusCode() { - this.request.setAttribute("jakarta.servlet.error.status_code", 404); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults()); - assertThat(attributes).containsEntry("error", HttpStatus.NOT_FOUND.getReasonPhrase()); - assertThat(attributes).containsEntry("status", 404); - } - - @Test - void missingStatusCode() { - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults()); - assertThat(attributes).containsEntry("error", "None"); - assertThat(attributes).containsEntry("status", 999); - } - - @Test - void mvcError() { - RuntimeException ex = new RuntimeException("Test"); - ModelAndView modelAndView = this.errorAttributes.resolveException(this.request, null, null, ex); - this.request.setAttribute("jakarta.servlet.error.exception", new RuntimeException("Ignored")); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); - assertThat(modelAndView).isNull(); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).containsEntry("message", "Test"); - } - - @Test - void servletErrorWithMessage() { - RuntimeException ex = new RuntimeException("Test"); - this.request.setAttribute("jakarta.servlet.error.exception", ex); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).containsEntry("message", "Test"); - } - - @Test - void servletErrorWithoutMessage() { - RuntimeException ex = new RuntimeException("Test"); - this.request.setAttribute("jakarta.servlet.error.exception", ex); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults()); - assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(ex); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).doesNotContainKey("message"); - } - - @Test - void servletMessageWithMessage() { - this.request.setAttribute("jakarta.servlet.error.message", "Test"); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).containsEntry("message", "Test"); - } - - @Test - void servletMessageWithoutMessage() { - this.request.setAttribute("jakarta.servlet.error.message", "Test"); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults()); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).doesNotContainKey("message"); - } - - @Test - void nullExceptionMessage() { - this.request.setAttribute("jakarta.servlet.error.exception", new RuntimeException()); - this.request.setAttribute("jakarta.servlet.error.message", "Test"); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).containsEntry("message", "Test"); - } - - @Test - void nullExceptionMessageAndServletMessage() { - this.request.setAttribute("jakarta.servlet.error.exception", new RuntimeException()); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).containsEntry("message", "No message available"); - } - - @Test - void unwrapServletException() { - RuntimeException ex = new RuntimeException("Test"); - ServletException wrapped = new ServletException(new ServletException(ex)); - this.request.setAttribute("jakarta.servlet.error.exception", wrapped); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(wrapped); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).containsEntry("message", "Test"); - } - - @Test - void getError() { - Error error = new OutOfMemoryError("Test error"); - this.request.setAttribute("jakarta.servlet.error.exception", error); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(this.errorAttributes.getError(this.webRequest)).isSameAs(error); - assertThat(attributes).doesNotContainKey("exception"); - assertThat(attributes).containsEntry("message", "Test error"); - } - - @Test - void withBindingErrors() { - BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); - bindingResult.addError(new ObjectError("c", "d")); - Exception ex = new BindException(bindingResult); - testBindingResult(bindingResult, ex, ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); - } - - @Test - void withoutBindingErrors() { - BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); - bindingResult.addError(new ObjectError("c", "d")); - Exception ex = new BindException(bindingResult); - testBindingResult(bindingResult, ex, ErrorAttributeOptions.defaults()); - } - - @Test - void withMethodArgumentNotValidExceptionBindingErrors() { - Method method = ReflectionUtils.findMethod(String.class, "substring", int.class); - MethodParameter parameter = new MethodParameter(method, 0); - BindingResult bindingResult = new MapBindingResult(Collections.singletonMap("a", "b"), "objectName"); - bindingResult.addError(new ObjectError("c", "d")); - Exception ex = new MethodArgumentNotValidException(parameter, bindingResult); - testBindingResult(bindingResult, ex, ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); - } - - @Test - void withHandlerMethodValidationExceptionBindingErrors() { - Object target = "test"; - Method method = ReflectionUtils.findMethod(String.class, "substring", int.class); - MethodParameter parameter = new MethodParameter(method, 0); - MethodValidationResult methodValidationResult = MethodValidationResult.create(target, method, - List.of(new ParameterValidationResult(parameter, -1, - List.of(new ObjectError("beginIndex", "beginIndex is negative")), null, null, null, - (error, sourceType) -> { - throw new IllegalArgumentException("No source object of the given type"); - }))); - HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult); - testErrors(methodValidationResult.getAllErrors(), - "Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1", - ex, ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); - } - - private void testBindingResult(BindingResult bindingResult, Exception ex, ErrorAttributeOptions options) { - testErrors(bindingResult.getAllErrors(), "Validation failed for object='objectName'. Error count: 1", ex, - options); - } - - private void testErrors(List errors, String expectedMessage, Exception ex, - ErrorAttributeOptions options) { - this.request.setAttribute("jakarta.servlet.error.exception", ex); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, options); - if (options.isIncluded(Include.MESSAGE)) { - assertThat(attributes).containsEntry("message", expectedMessage); - } - else { - assertThat(attributes).doesNotContainKey("message"); - } - if (options.isIncluded(Include.BINDING_ERRORS)) { - assertThat(attributes).containsEntry("errors", org.springframework.boot.web.error.Error.wrap(errors)); - } - else { - assertThat(attributes).doesNotContainKey("errors"); - } - } - - @Test - void withExceptionAttribute() { - DefaultErrorAttributes errorAttributes = new DefaultErrorAttributes(); - RuntimeException ex = new RuntimeException("Test"); - this.request.setAttribute("jakarta.servlet.error.exception", ex); - Map attributes = errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE)); - assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); - assertThat(attributes).containsEntry("message", "Test"); - } - - @Test - void withStackTraceAttribute() { - RuntimeException ex = new RuntimeException("Test"); - this.request.setAttribute("jakarta.servlet.error.exception", ex); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.STACK_TRACE)); - assertThat(attributes.get("trace").toString()).startsWith("java.lang"); - } - - @Test - void withoutStackTraceAttribute() { - RuntimeException ex = new RuntimeException("Test"); - this.request.setAttribute("jakarta.servlet.error.exception", ex); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults()); - assertThat(attributes).doesNotContainKey("trace"); - } - - @Test - void shouldIncludePathByDefault() { - this.request.setAttribute("jakarta.servlet.error.request_uri", "path"); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults()); - assertThat(attributes).containsEntry("path", "path"); - } - - @Test - void shouldIncludePath() { - this.request.setAttribute("jakarta.servlet.error.request_uri", "path"); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of(Include.PATH)); - assertThat(attributes).containsEntry("path", "path"); - } - - @Test - void shouldExcludePath() { - this.request.setAttribute("jakarta.servlet.error.request_uri", "path"); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.of()); - assertThat(attributes).doesNotContainEntry("path", "path"); - } - - @Test - void whenGetMessageIsOverriddenThenMessageAttributeContainsValueReturnedFromIt() { - Map attributes = new DefaultErrorAttributes() { - - @Override - protected String getMessage(WebRequest webRequest, Throwable error) { - return "custom message"; - } - - }.getErrorAttributes(this.webRequest, ErrorAttributeOptions.of(Include.MESSAGE)); - assertThat(attributes).containsEntry("message", "custom message"); - } - - @Test - void excludeStatus() { - this.request.setAttribute("jakarta.servlet.error.status_code", 404); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults().excluding(Include.STATUS)); - assertThat(attributes).doesNotContainKey("status"); - } - - @Test - void excludeError() { - this.request.setAttribute("jakarta.servlet.error.status_code", 404); - Map attributes = this.errorAttributes.getErrorAttributes(this.webRequest, - ErrorAttributeOptions.defaults().excluding(Include.ERROR)); - assertThat(attributes).doesNotContainKey("error"); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterTests.java index 0c7701109c28..05af53e67a37 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/ErrorPageFilterTests.java @@ -35,7 +35,7 @@ import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; -import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.web.error.ErrorPage; import org.springframework.http.HttpStatus; import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockFilterConfig; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializerTests.java index bfdbecf4be69..50f2c6e1b68f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializerTests.java @@ -40,13 +40,9 @@ import org.springframework.boot.context.logging.LoggingApplicationListener; import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.core.Ordered; @@ -126,60 +122,43 @@ void shutdownHooksAreNotRegistered() throws ServletException { @Test void errorPageFilterRegistrationCanBeDisabled() { - WebServer webServer = new UndertowServletWebServerFactory(0).getWebServer((servletContext) -> { - try (AbstractApplicationContext context = (AbstractApplicationContext) new WithErrorPageFilterNotRegistered() - .createRootApplicationContext(servletContext)) { - assertThat(context.getBeansOfType(ErrorPageFilter.class)).isEmpty(); - } - }); - try { - webServer.start(); - } - finally { - webServer.stop(); + try (AbstractApplicationContext context = (AbstractApplicationContext) new WithErrorPageFilterNotRegistered() + .createRootApplicationContext(this.servletContext)) { + Map errorPageFilterBeans = context.getBeansOfType(ErrorPageFilter.class); + assertThat(errorPageFilterBeans).isEmpty(); } } @Test @SuppressWarnings("rawtypes") void errorPageFilterIsRegisteredWithNearHighestPrecedence() { - WebServer webServer = new UndertowServletWebServerFactory(0).getWebServer((servletContext) -> { - try (AbstractApplicationContext context = (AbstractApplicationContext) new WithErrorPageFilter() - .createRootApplicationContext(servletContext)) { - Map registrations = context - .getBeansOfType(FilterRegistrationBean.class); - assertThat(registrations).hasSize(1); - FilterRegistrationBean errorPageFilterRegistration = registrations.get("errorPageFilterRegistration"); - assertThat(errorPageFilterRegistration.getOrder()).isEqualTo(Ordered.HIGHEST_PRECEDENCE + 1); - } - }); - try { - webServer.start(); - } - finally { - webServer.stop(); + ServletContext servletContext = mock(ServletContext.class); + given(servletContext.addFilter(any(), any(Filter.class))).willReturn(mock(Dynamic.class)); + given(servletContext.getInitParameterNames()).willReturn(Collections.emptyEnumeration()); + given(servletContext.getAttributeNames()).willReturn(Collections.emptyEnumeration()); + try (AbstractApplicationContext context = (AbstractApplicationContext) new WithErrorPageFilter() + .createRootApplicationContext(servletContext)) { + Map registrations = context.getBeansOfType(FilterRegistrationBean.class); + assertThat(registrations).hasSize(1); + FilterRegistrationBean errorPageFilterRegistration = registrations.get("errorPageFilterRegistration"); + assertThat(errorPageFilterRegistration.getOrder()).isEqualTo(Ordered.HIGHEST_PRECEDENCE + 1); } } @Test @SuppressWarnings("rawtypes") void errorPageFilterIsRegisteredForRequestAndAsyncDispatch() { - WebServer webServer = new UndertowServletWebServerFactory(0).getWebServer((servletContext) -> { - try (AbstractApplicationContext context = (AbstractApplicationContext) new WithErrorPageFilter() - .createRootApplicationContext(servletContext)) { - Map registrations = context - .getBeansOfType(FilterRegistrationBean.class); - assertThat(registrations).hasSize(1); - FilterRegistrationBean errorPageFilterRegistration = registrations.get("errorPageFilterRegistration"); - assertThat(errorPageFilterRegistration).hasFieldOrPropertyWithValue("dispatcherTypes", - EnumSet.of(DispatcherType.ASYNC, DispatcherType.REQUEST)); - } - }); - try { - webServer.start(); - } - finally { - webServer.stop(); + ServletContext servletContext = mock(ServletContext.class); + given(servletContext.addFilter(any(), any(Filter.class))).willReturn(mock(Dynamic.class)); + given(servletContext.getInitParameterNames()).willReturn(Collections.emptyEnumeration()); + given(servletContext.getAttributeNames()).willReturn(Collections.emptyEnumeration()); + try (AbstractApplicationContext context = (AbstractApplicationContext) new WithErrorPageFilter() + .createRootApplicationContext(servletContext)) { + Map registrations = context.getBeansOfType(FilterRegistrationBean.class); + assertThat(registrations).hasSize(1); + FilterRegistrationBean errorPageFilterRegistration = registrations.get("errorPageFilterRegistration"); + assertThat(errorPageFilterRegistration).hasFieldOrPropertyWithValue("dispatcherTypes", + EnumSet.of(DispatcherType.ASYNC, DispatcherType.REQUEST)); } } @@ -327,11 +306,6 @@ static class WithErrorPageFilter extends SpringBootServletInitializer { @Configuration(proxyBeanMethods = false) static class ExecutableWar extends SpringBootServletInitializer { - @Bean - ServletWebServerFactory webServerFactory() { - return new UndertowServletWebServerFactory(0); - } - } @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/view/MustacheViewResolverTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/view/MustacheViewResolverTests.java deleted file mode 100644 index be746c35a97d..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/view/MustacheViewResolverTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.view; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.mock.web.MockServletContext; -import org.springframework.web.servlet.View; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MustacheViewResolver}. - * - * @author Dave Syer - * @author Andy Wilkinson - */ -class MustacheViewResolverTests { - - private final MustacheViewResolver resolver = new MustacheViewResolver(); - - @BeforeEach - void init() { - GenericApplicationContext applicationContext = new GenericApplicationContext(); - applicationContext.refresh(); - this.resolver.setApplicationContext(applicationContext); - this.resolver.setServletContext(new MockServletContext()); - this.resolver.setPrefix("classpath:"); - this.resolver.setSuffix(".html"); - } - - @Test - void resolveNonExistent() throws Exception { - assertThat(this.resolver.resolveViewName("bar", null)).isNull(); - } - - @Test - @WithResource(name = "template.html", content = "Hello {{World}}") - void resolveExisting() throws Exception { - assertThat(this.resolver.resolveViewName("template", null)).isNotNull(); - } - - @Test - @WithResource(name = "template.html", content = "Hello {{World}}") - void setsContentType() throws Exception { - this.resolver.setContentType("application/octet-stream"); - View view = this.resolver.resolveViewName("template", null); - assertThat(view.getContentType()).isEqualTo("application/octet-stream"); - - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/view/MustacheViewTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/view/MustacheViewTests.java deleted file mode 100644 index c0fb9f1df50e..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/view/MustacheViewTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.view; - -import java.util.Collections; - -import com.samskivert.mustache.Mustache; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.testsupport.classpath.resources.WithResource; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.mock.web.MockServletContext; -import org.springframework.web.context.WebApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MustacheView}. - * - * @author Dave Syer - */ -class MustacheViewTests { - - private final MockHttpServletRequest request = new MockHttpServletRequest(); - - private final MockHttpServletResponse response = new MockHttpServletResponse(); - - private final AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext(); - - @BeforeEach - void init() { - this.context.refresh(); - MockServletContext servletContext = new MockServletContext(); - this.context.setServletContext(servletContext); - servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); - } - - @Test - @WithResource(name = "template.html", content = "Hello {{World}}") - void viewResolvesHandlebars() throws Exception { - MustacheView view = new MustacheView(); - view.setCompiler(Mustache.compiler()); - view.setUrl("classpath:template.html"); - view.setApplicationContext(this.context); - view.render(Collections.singletonMap("World", "Spring"), this.request, this.response); - assertThat(this.response.getContentAsString().trim()).isEqualTo("Hello Spring"); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderJettyClientIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderJettyClientIntegrationTests.java deleted file mode 100644 index 19e35dcf7ab8..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderJettyClientIntegrationTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.webservices.client; - -import java.time.Duration; - -import org.eclipse.jetty.client.HttpClient; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.JettyClientHttpRequestFactory; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.ws.transport.WebServiceMessageSender; -import org.springframework.ws.transport.http.ClientHttpRequestMessageSender; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HttpWebServiceMessageSenderBuilder} when Http Components is not - * available and, therefore, Jetty's client is used instead. - * - * @author Stephane Nicoll - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@ClassPathExclusions("httpclient5-*.jar") -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class HttpWebServiceMessageSenderBuilderJettyClientIntegrationTests { - - private final HttpWebServiceMessageSenderBuilder builder = new HttpWebServiceMessageSenderBuilder(); - - @Test - void buildUseJettyClientIfHttpComponentsIsNotAvailable() { - WebServiceMessageSender messageSender = this.builder.build(); - assertJettyClientHttpRequestFactory(messageSender); - } - - @Test - void buildWithCustomTimeouts() { - WebServiceMessageSender messageSender = this.builder.setConnectTimeout(Duration.ofSeconds(5)) - .setReadTimeout(Duration.ofSeconds(2)) - .build(); - JettyClientHttpRequestFactory factory = assertJettyClientHttpRequestFactory(messageSender); - HttpClient client = (HttpClient) ReflectionTestUtils.getField(factory, "httpClient"); - assertThat(client).isNotNull(); - assertThat(client.getConnectTimeout()).isEqualTo(5000); - assertThat(factory).hasFieldOrPropertyWithValue("readTimeout", 2000L); - } - - private JettyClientHttpRequestFactory assertJettyClientHttpRequestFactory(WebServiceMessageSender messageSender) { - assertThat(messageSender).isInstanceOf(ClientHttpRequestMessageSender.class); - ClientHttpRequestMessageSender sender = (ClientHttpRequestMessageSender) messageSender; - ClientHttpRequestFactory requestFactory = sender.getRequestFactory(); - assertThat(requestFactory).isInstanceOf(JettyClientHttpRequestFactory.class); - return (JettyClientHttpRequestFactory) requestFactory; - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderReactorClientIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderReactorClientIntegrationTests.java deleted file mode 100644 index df46bd9d6fd0..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderReactorClientIntegrationTests.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.webservices.client; - -import java.time.Duration; - -import io.netty.channel.ChannelOption; -import org.assertj.core.api.InstanceOfAssertFactories; -import org.junit.jupiter.api.Test; -import reactor.netty.http.client.HttpClient; - -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.ReactorClientHttpRequestFactory; -import org.springframework.ws.transport.WebServiceMessageSender; -import org.springframework.ws.transport.http.ClientHttpRequestMessageSender; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HttpWebServiceMessageSenderBuilder} when Reactor Netty is the - * predominant HTTP client. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@ClassPathExclusions({ "httpclient5-*.jar", "jetty-client-*.jar" }) -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class HttpWebServiceMessageSenderBuilderReactorClientIntegrationTests { - - private final HttpWebServiceMessageSenderBuilder builder = new HttpWebServiceMessageSenderBuilder(); - - @Test - void buildUsesReactorClientIfHttpComponentsAndJettyAreNotAvailable() { - WebServiceMessageSender messageSender = this.builder.build(); - assertReactorClientHttpRequestFactory(messageSender); - } - - @Test - void buildWithCustomTimeouts() { - WebServiceMessageSender messageSender = this.builder.setConnectTimeout(Duration.ofSeconds(5)) - .setReadTimeout(Duration.ofSeconds(2)) - .build(); - ReactorClientHttpRequestFactory factory = assertReactorClientHttpRequestFactory(messageSender); - assertThat(factory).extracting("httpClient", InstanceOfAssertFactories.type(HttpClient.class)) - .extracting((httpClient) -> httpClient.configuration().options(), InstanceOfAssertFactories.MAP) - .containsEntry(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000); - assertThat(factory).hasFieldOrPropertyWithValue("readTimeout", Duration.ofSeconds(2)); - } - - private ReactorClientHttpRequestFactory assertReactorClientHttpRequestFactory( - WebServiceMessageSender messageSender) { - assertThat(messageSender).isInstanceOf(ClientHttpRequestMessageSender.class); - ClientHttpRequestMessageSender sender = (ClientHttpRequestMessageSender) messageSender; - ClientHttpRequestFactory requestFactory = sender.getRequestFactory(); - assertThat(requestFactory).isInstanceOf(ReactorClientHttpRequestFactory.class); - return (ReactorClientHttpRequestFactory) requestFactory; - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderSimpleIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderSimpleIntegrationTests.java deleted file mode 100644 index 9be6a000d02a..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderSimpleIntegrationTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.webservices.client; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.testsupport.classpath.ClassPathExclusions; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.ws.transport.WebServiceMessageSender; -import org.springframework.ws.transport.http.ClientHttpRequestMessageSender; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HttpWebServiceMessageSenderBuilder} when no preferred HTTP clients are - * available - * - * @author Stephane Nicoll - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@ClassPathExclusions({ "httpclient5-*.jar", "jetty-client-*.jar", "reactor-netty-http-*.jar" }) -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class HttpWebServiceMessageSenderBuilderSimpleIntegrationTests { - - private final HttpWebServiceMessageSenderBuilder builder = new HttpWebServiceMessageSenderBuilder(); - - @Test - void buildUseUseSimpleClientByDefault() { - WebServiceMessageSender messageSender = this.builder.build(); - assertSimpleClientRequestFactory(messageSender); - } - - @Test - void buildWithCustomTimeouts() { - WebServiceMessageSender messageSender = this.builder.setConnectTimeout(Duration.ofSeconds(5)) - .setReadTimeout(Duration.ofSeconds(2)) - .build(); - SimpleClientHttpRequestFactory requestFactory = assertSimpleClientRequestFactory(messageSender); - assertThat(requestFactory).hasFieldOrPropertyWithValue("connectTimeout", 5000); - assertThat(requestFactory).hasFieldOrPropertyWithValue("readTimeout", 2000); - } - - private SimpleClientHttpRequestFactory assertSimpleClientRequestFactory(WebServiceMessageSender messageSender) { - assertThat(messageSender).isInstanceOf(ClientHttpRequestMessageSender.class); - ClientHttpRequestMessageSender sender = (ClientHttpRequestMessageSender) messageSender; - ClientHttpRequestFactory requestFactory = sender.getRequestFactory(); - assertThat(requestFactory).isInstanceOf(SimpleClientHttpRequestFactory.class); - return (SimpleClientHttpRequestFactory) requestFactory; - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderTests.java deleted file mode 100644 index 91cb09d2b73a..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/webservices/client/HttpWebServiceMessageSenderBuilderTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.webservices.client; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.ws.transport.WebServiceMessageSender; -import org.springframework.ws.transport.http.ClientHttpRequestMessageSender; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link HttpWebServiceMessageSenderBuilder}. - * - * @author Stephane Nicoll - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -class HttpWebServiceMessageSenderBuilderTests { - - @Test - void buildWithRequestFactorySupplier() { - ClientHttpRequestFactory requestFactory = mock(ClientHttpRequestFactory.class); - ClientHttpRequestMessageSender messageSender = build( - new HttpWebServiceMessageSenderBuilder().requestFactory(() -> requestFactory)); - assertThat(messageSender.getRequestFactory()).isSameAs(requestFactory); - } - - @Test - void buildWithReadAndConnectTimeout() { - ClientHttpRequestMessageSender messageSender = build( - new HttpWebServiceMessageSenderBuilder().requestFactory(SimpleClientHttpRequestFactory::new) - .setConnectTimeout(Duration.ofSeconds(5)) - .setReadTimeout(Duration.ofSeconds(2))); - SimpleClientHttpRequestFactory requestFactory = (SimpleClientHttpRequestFactory) messageSender - .getRequestFactory(); - assertThat(requestFactory).hasFieldOrPropertyWithValue("connectTimeout", 5000); - assertThat(requestFactory).hasFieldOrPropertyWithValue("readTimeout", 2000); - } - - @Test - void buildUsesHttpComponentsByDefault() { - ClientHttpRequestMessageSender messageSender = build( - new HttpWebServiceMessageSenderBuilder().setConnectTimeout(Duration.ofSeconds(5)) - .setReadTimeout(Duration.ofSeconds(5))); - ClientHttpRequestFactory requestFactory = messageSender.getRequestFactory(); - assertThat(requestFactory).isInstanceOf(HttpComponentsClientHttpRequestFactory.class); - } - - private ClientHttpRequestMessageSender build(HttpWebServiceMessageSenderBuilder builder) { - WebServiceMessageSender messageSender = builder.build(); - assertThat(messageSender).isInstanceOf(ClientHttpRequestMessageSender.class); - return ((ClientHttpRequestMessageSender) messageSender); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt b/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt index 2a5780abdb93..ef248d9f0289 100644 --- a/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt +++ b/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt @@ -21,8 +21,6 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.getBean import org.springframework.boot.kotlinsample.TestKotlinApplication -import org.springframework.boot.web.servlet.mock.MockFilter -import org.springframework.boot.web.servlet.server.MockServletWebServerFactory import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.env.StandardEnvironment @@ -36,14 +34,14 @@ class SpringApplicationExtensionsTests { @Test fun `Kotlin runApplication() top level function`() { - val context = runApplication() + val context = runApplication() assertThat(context).isNotNull() } @Test fun `Kotlin runApplication() top level function with a custom environment`() { val environment = StandardEnvironment() - val context = runApplication { + val context = runApplication { setEnvironment(environment) } assertThat(context).isNotNull() @@ -52,7 +50,7 @@ class SpringApplicationExtensionsTests { @Test fun `Kotlin runApplication(arg1, arg2) top level function`() { - val context = runApplication("--debug", "spring", "boot") + val context = runApplication("--debug", "spring", "boot") val args = context.getBean() assertThat(args.nonOptionArgs.toTypedArray()).containsExactly("spring", "boot") assertThat(args.containsOption("debug")).isTrue() @@ -61,7 +59,7 @@ class SpringApplicationExtensionsTests { @Test fun `Kotlin runApplication(arg1, arg2) top level function with a custom environment`() { val environment = StandardEnvironment() - val context = runApplication("--debug", "spring", "boot") { + val context = runApplication("--debug", "spring", "boot") { setEnvironment(environment) } val args = context.getBean() @@ -72,44 +70,52 @@ class SpringApplicationExtensionsTests { @Test fun `Kotlin fromApplication() top level function`() { - val context = fromApplication().with(ExampleWebConfig::class).run().applicationContext - assertThat(context.getBean()).isNotNull() + val context = fromApplication().with(ExampleConfig::class).run().applicationContext + assertThat(context.getBean()).isNotNull() } @Test fun `Kotlin fromApplication() top level function with multiple sources`() { val context = fromApplication() - .with(ExampleWebConfig::class, ExampleFilterConfig::class).run().applicationContext - assertThat(context.getBean()).isNotNull() - assertThat(context.getBean()).isNotNull() + .with(ExampleConfig::class, AnotherExampleConfig::class).run().applicationContext + assertThat(context.getBean()).isNotNull() + assertThat(context.getBean()).isNotNull() } @Test fun `Kotlin fromApplication() top level function when no main`() { - assertThatIllegalStateException().isThrownBy { fromApplication().run() } + assertThatIllegalStateException().isThrownBy { fromApplication().run() } .withMessage("Unable to use 'fromApplication' with " + - "org.springframework.boot.SpringApplicationExtensionsTests.ExampleWebConfig") + "org.springframework.boot.SpringApplicationExtensionsTests.ExampleConfig") } @Configuration(proxyBeanMethods = false) - internal open class ExampleWebConfig { + internal open class ExampleConfig { @Bean - open fun webServer(): MockServletWebServerFactory { - return MockServletWebServerFactory() + open fun exampleBean(): ExampleBean { + return ExampleBean() } } @Configuration(proxyBeanMethods = false) - internal open class ExampleFilterConfig { + internal open class AnotherExampleConfig { @Bean - open fun filter(): MockFilter { - return MockFilter() + open fun anotherExampleBean(): AnotherExampleBean { + return AnotherExampleBean() } } + class ExampleBean { + + } + + class AnotherExampleBean { + + } + } diff --git a/spring-boot-project/spring-boot/src/test/resources/logback-include-status-listener.xml b/spring-boot-project/spring-boot/src/test/resources/logback-include-status-listener.xml deleted file mode 100644 index 6be18d7a3786..000000000000 --- a/spring-boot-project/spring-boot/src/test/resources/logback-include-status-listener.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - [%p] - %m%n - - - - - - diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/AbstractApplicationEnvironmentTests.java b/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/AbstractApplicationEnvironmentTests.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/AbstractApplicationEnvironmentTests.java rename to spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/AbstractApplicationEnvironmentTests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/mock/MockFilter.java b/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/mock/MockFilter.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/mock/MockFilter.java rename to spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/mock/MockFilter.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/mock/MockServlet.java b/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/mock/MockServlet.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/mock/MockServlet.java rename to spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/mock/MockServlet.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/mock/package-info.java b/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/mock/package-info.java similarity index 100% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/mock/package-info.java rename to spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/mock/package-info.java diff --git a/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/server/MockServletWebServerFactory.java b/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/server/MockServletWebServerFactory.java deleted file mode 100644 index 5f97cbf05967..000000000000 --- a/spring-boot-project/spring-boot/src/testFixtures/java/org/springframework/boot/web/servlet/server/MockServletWebServerFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.web.servlet.server; - -import jakarta.servlet.ServletContext; - -import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.server.MockServletWebServer.RegisteredFilter; -import org.springframework.boot.web.servlet.server.MockServletWebServer.RegisteredServlet; - -import static org.mockito.Mockito.spy; - -/** - * Mock {@link ServletWebServerFactory}. - * - * @author Phillip Webb - * @author Andy Wilkinson - */ -public class MockServletWebServerFactory extends AbstractServletWebServerFactory { - - private MockServletWebServer webServer; - - @Override - public WebServer getWebServer(ServletContextInitializer... initializers) { - this.webServer = spy(new MockServletWebServer(mergeInitializers(initializers), getPort())); - return this.webServer; - } - - public MockServletWebServer getWebServer() { - return this.webServer; - } - - public ServletContext getServletContext() { - return (getWebServer() != null) ? getWebServer().getServletContext() : null; - } - - public RegisteredServlet getRegisteredServlet(int index) { - return (getWebServer() != null) ? getWebServer().getRegisteredServlet(index) : null; - } - - public RegisteredFilter getRegisteredFilter(int index) { - return (getWebServer() != null) ? getWebServer().getRegisteredFilters(index) : null; - } - -} diff --git a/spring-boot-system-tests/spring-boot-deployment-tests/build.gradle b/spring-boot-system-tests/spring-boot-deployment-tests/build.gradle index ca8791a8b52b..93fb7bae64f0 100644 --- a/spring-boot-system-tests/spring-boot-deployment-tests/build.gradle +++ b/spring-boot-system-tests/spring-boot-deployment-tests/build.gradle @@ -32,8 +32,11 @@ configurations.all { } dependencies { + compileOnly("jakarta.servlet:jakarta.servlet-api") + implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) { exclude group: "org.hibernate.validator" + exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat" } implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator")) @@ -41,12 +44,9 @@ dependencies { systemTestImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) systemTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) systemTestImplementation("org.apache.httpcomponents.client5:httpclient5") - systemTestImplementation("org.awaitility:awaitility") systemTestImplementation("org.testcontainers:junit-jupiter") systemTestImplementation("org.testcontainers:testcontainers") systemTestImplementation("org.springframework:spring-web") - - providedRuntime(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat")) } systemTest { diff --git a/spring-boot-system-tests/spring-boot-deployment-tests/src/systemTest/java/org/springframework/boot/deployment/AbstractDeploymentTests.java b/spring-boot-system-tests/spring-boot-deployment-tests/src/systemTest/java/org/springframework/boot/deployment/AbstractDeploymentTests.java index 407dc2d35fbb..c5f1ae8da9ca 100644 --- a/spring-boot-system-tests/spring-boot-deployment-tests/src/systemTest/java/org/springframework/boot/deployment/AbstractDeploymentTests.java +++ b/spring-boot-system-tests/spring-boot-deployment-tests/src/systemTest/java/org/springframework/boot/deployment/AbstractDeploymentTests.java @@ -31,8 +31,8 @@ import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.images.builder.dockerfile.DockerfileBuilder; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; @@ -104,6 +104,7 @@ private void test(Consumer consumer) { try { Awaitility.await().atMost(Duration.ofMinutes(10)).until(() -> { try { + System.out.println(this.container.getLogs()); consumer.accept(rest); return true; } diff --git a/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/java/org/springframework/boot/image/paketo/PaketoBuilderTests.java b/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/java/org/springframework/boot/image/paketo/PaketoBuilderTests.java index 9a08b77b4691..aeb02374d04f 100644 --- a/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/java/org/springframework/boot/image/paketo/PaketoBuilderTests.java +++ b/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/java/org/springframework/boot/image/paketo/PaketoBuilderTests.java @@ -386,6 +386,7 @@ private BuildResult buildImageWithRetry(String imageName, String... arguments) { return buildImage(imageName, arguments); } catch (Exception ex) { + ex.printStackTrace(); if (Duration.ofNanos(System.nanoTime() - start).toMinutes() > 6) { throw ex; } diff --git a/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainWarApp.gradle b/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainWarApp.gradle index c21274faafdc..b5d8828c99e3 100644 --- a/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainWarApp.gradle +++ b/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-plainWarApp.gradle @@ -38,7 +38,6 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:{bootVersion}") - providedRuntime("org.springframework.boot:spring-boot-starter-tomcat:{bootVersion}") } war { diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/build.gradle b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/build.gradle index d306cb701833..6e64e77cf8ef 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/build.gradle +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/build.gradle @@ -29,7 +29,6 @@ dependencies { intTestImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) intTestImplementation("org.apache.httpcomponents.client5:httpclient5") - intTestImplementation("org.awaitility:awaitility") intTestImplementation("org.springframework:spring-web") testRepository(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "mavenRepository")) diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/build.gradle b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/build.gradle index 10536ef4370e..aacd365c0bc7 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/build.gradle +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/build.gradle @@ -66,8 +66,8 @@ tasks.register("resourcesJar", Jar) { jar -> } dependencies { - compileOnly("org.eclipse.jetty.ee10:jetty-ee10-servlet") compileOnly("org.springframework:spring-web") + compileOnly("org.springframework.boot:spring-boot-jetty") implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) implementation("org.springframework.boot:spring-boot-starter") diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/java/com/example/JettyServerCustomizerConfig.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/java/com/example/JettyServerCustomizerConfig.java index 1ce60d5f15df..b6d4104d5923 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/java/com/example/JettyServerCustomizerConfig.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/java/com/example/JettyServerCustomizerConfig.java @@ -23,7 +23,7 @@ import org.eclipse.jetty.server.handler.ContextHandler; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; +import org.springframework.boot.jetty.JettyServerCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/java/com/example/ResourceHandlingApplication.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/java/com/example/ResourceHandlingApplication.java index 0579ac34e3db..6e1427a655c7 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/java/com/example/ResourceHandlingApplication.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/java/com/example/ResourceHandlingApplication.java @@ -28,7 +28,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.context.WebServerPortFileWriter; +import org.springframework.boot.web.server.context.WebServerPortFileWriter; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/build.gradle b/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/build.gradle index 9271274b6e63..68e1a0a8ff96 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/build.gradle +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/build.gradle @@ -27,6 +27,7 @@ configurations { dependencies { app project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "mavenRepository") + app project(path: ":spring-boot-project:spring-boot-restclient", configuration: "mavenRepository") app project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter", configuration: "mavenRepository") app project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator", configuration: "mavenRepository") app project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat", configuration: "mavenRepository") @@ -34,6 +35,7 @@ dependencies { app project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-web", configuration: "mavenRepository") app project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-webflux", configuration: "mavenRepository") app project(path: ":spring-boot-project:spring-boot-tools:spring-boot-gradle-plugin", configuration: "mavenRepository") + app project(path: ":spring-boot-project:spring-boot-webflux", configuration: "mavenRepository") intTestImplementation(enforcedPlatform(project(":spring-boot-project:spring-boot-parent"))) intTestImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-client-app/build.gradle b/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-client-app/build.gradle index cb09f8a6b2be..05f7f230ea31 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-client-app/build.gradle +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-client-app/build.gradle @@ -33,5 +33,6 @@ repositories { dependencies { implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) + implementation("org.springframework.boot:spring-boot-restclient") implementation("org.springframework.boot:spring-boot-starter-web") } diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-client-app/src/main/java/org/springframework/boot/sni/client/SniClientApplication.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-client-app/src/main/java/org/springframework/boot/sni/client/SniClientApplication.java index d2a063ee9347..fad9d10be959 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-client-app/src/main/java/org/springframework/boot/sni/client/SniClientApplication.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-client-app/src/main/java/org/springframework/boot/sni/client/SniClientApplication.java @@ -21,8 +21,8 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.web.client.RestClientSsl; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.restclient.autoconfigure.RestClientSsl; import org.springframework.context.annotation.Bean; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-reactive-app/build.gradle b/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-reactive-app/build.gradle index 8735939c3a8d..228cb599f7b2 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-reactive-app/build.gradle +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-sni-tests/spring-boot-sni-reactive-app/build.gradle @@ -56,9 +56,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-actuator") app(files(sourceSets.main.output)) - app("org.springframework:spring-webflux") { - exclude group: "spring-boot-project", module: "spring-boot-starter-reactor-netty" - } + app("org.springframework.boot:spring-boot-webflux") netty("org.springframework.boot:spring-boot-starter-webflux") tomcat("org.springframework.boot:spring-boot-starter-tomcat") undertow("org.springframework.boot:spring-boot-starter-undertow") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/main/java/smoketest/actuator/customsecurity/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/main/java/smoketest/actuator/customsecurity/SecurityConfiguration.java index a04503c9281a..8c6b48e726ce 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/main/java/smoketest/actuator/customsecurity/SecurityConfiguration.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/main/java/smoketest/actuator/customsecurity/SecurityConfiguration.java @@ -19,9 +19,9 @@ import java.util.ArrayList; import java.util.List; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; -import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; +import org.springframework.boot.security.autoconfigure.servlet.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java index 643b169c9678..2bda8c430220 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java @@ -20,8 +20,8 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.LocalHostUriTemplateHandler; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CorsSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CorsSampleActuatorApplicationTests.java index 22137da12101..0b3c346ff1e6 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CorsSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CorsSampleActuatorApplicationTests.java @@ -23,10 +23,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.server.test.client.LocalHostUriTemplateHandler; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java index ebc95a8a2bfe..8ae2b32f85c1 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java @@ -18,7 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.core.env.Environment; /** diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java index aa08feef9ee2..f7dd420d5c37 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java @@ -21,9 +21,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java index da042e709958..dfbe57f0c8a4 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java @@ -20,9 +20,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java index 7227fa42028e..f2565e5d0531 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-extension/src/main/java/smoketest/actuator/extension/MyExtensionWebMvcEndpointHandlerMapping.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-extension/src/main/java/smoketest/actuator/extension/MyExtensionWebMvcEndpointHandlerMapping.java index 5e898863c566..63f6f6167c27 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-extension/src/main/java/smoketest/actuator/extension/MyExtensionWebMvcEndpointHandlerMapping.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-extension/src/main/java/smoketest/actuator/extension/MyExtensionWebMvcEndpointHandlerMapping.java @@ -29,7 +29,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; -import org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping; +import org.springframework.boot.webmvc.actuate.endpoint.web.AbstractWebMvcEndpointHandlerMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-extension/src/test/java/smoketest/actuator/extension/SampleActuatorExtensionApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-extension/src/test/java/smoketest/actuator/extension/SampleActuatorExtensionApplicationTests.java index aa08469d68d5..713f7ef33d08 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-extension/src/test/java/smoketest/actuator/extension/SampleActuatorExtensionApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-extension/src/test/java/smoketest/actuator/extension/SampleActuatorExtensionApplicationTests.java @@ -21,11 +21,11 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.server.test.client.LocalHostUriTemplateHandler; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java index 31a41aa82911..1d96316da532 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java @@ -23,9 +23,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationTests.java index 3729ef878bee..fec7147f319b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationTests.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/ExampleHealthIndicator.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/ExampleHealthIndicator.java index f3a69a4841a6..484e94dee2ea 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/ExampleHealthIndicator.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/ExampleHealthIndicator.java @@ -16,8 +16,8 @@ package smoketest.actuator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.stereotype.Component; @Component diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/SampleActuatorApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/SampleActuatorApplication.java index 0b2d890f3b40..d73e846752b7 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/SampleActuatorApplication.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/SampleActuatorApplication.java @@ -20,13 +20,13 @@ import java.util.Map; import org.springframework.boot.SpringApplication; -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.boot.health.contributor.CompositeHealthContributor; +import org.springframework.boot.health.contributor.Health; +import org.springframework.boot.health.contributor.HealthContributor; +import org.springframework.boot.health.contributor.HealthIndicator; import org.springframework.context.annotation.Bean; @SpringBootApplication diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java index 357a2ef52915..3749431a4a3d 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java @@ -21,9 +21,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/CorsSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/CorsSampleActuatorApplicationTests.java index d8b90536c9f7..1fc85405f7d1 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/CorsSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/CorsSampleActuatorApplicationTests.java @@ -23,10 +23,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.server.test.client.LocalHostUriTemplateHandler; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/EndpointsPropertiesSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/EndpointsPropertiesSampleActuatorApplicationTests.java index fe9b371e4b26..770373ebca1b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/EndpointsPropertiesSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/EndpointsPropertiesSampleActuatorApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java index 0cc0d8995d4e..b8e51a7465f8 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java @@ -22,9 +22,9 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortAndEndpointWithExceptionHandlerSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortAndEndpointWithExceptionHandlerSampleActuatorApplicationTests.java index 168bb1dcb30e..0a320e80c298 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortAndEndpointWithExceptionHandlerSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortAndEndpointWithExceptionHandlerSampleActuatorApplicationTests.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java index 35b79918a0bb..f63312a88fa9 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPathSampleActuatorApplicationTests.java index 20d129a1c0c3..e59d54b90495 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPathSampleActuatorApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java index b51e7c2846d3..52b6a4ad8263 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java @@ -24,11 +24,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; +import org.springframework.boot.webmvc.error.DefaultErrorAttributes; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java index ddfbbc5d2e08..30d945d11789 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/NoManagementSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/NoManagementSampleActuatorApplicationTests.java index 73cd3f4fb889..c97b746e7adc 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/NoManagementSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/NoManagementSampleActuatorApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperFalseTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperFalseTests.java index a77251f2bea6..900f145d0030 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperFalseTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperFalseTests.java @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperTrueTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperTrueTests.java index 13e8dbd82c91..7b1d3be4c88b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperTrueTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperTrueTests.java @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationTests.java index 8b6c26dcad7d..6577b55d027e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationTests.java @@ -23,10 +23,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ServletPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ServletPathSampleActuatorApplicationTests.java index c0c0b7b9cbf5..683643486770 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ServletPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ServletPathSampleActuatorApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ShutdownSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ShutdownSampleActuatorApplicationTests.java index 7edcc8216b49..b072732f5c7c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ShutdownSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ShutdownSampleActuatorApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-cache/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-cache/build.gradle index 84f5ab654c14..bffc2c5dd013 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-cache/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-cache/build.gradle @@ -55,7 +55,7 @@ dependencies { ehcache("org.ehcache:ehcache::jakarta") hazelcast(enforcedPlatform(project(":spring-boot-project:spring-boot-dependencies"))) - hazelcast("com.hazelcast:hazelcast") + hazelcast(project(":spring-boot-project:spring-boot-hazelcast")) hazelcast("com.hazelcast:hazelcast-spring") implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator")) diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-couchbase/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-couchbase/build.gradle index 6b608c657a6c..46ba34d5f475 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-couchbase/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-couchbase/build.gradle @@ -22,11 +22,11 @@ plugins { description = "Spring Boot Data Couchbase smoke test" dependencies { - dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-reactor")) dockerTestImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) - dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) dockerTestImplementation(project(":spring-boot-project:spring-boot-testcontainers")) - dockerTestImplementation("io.projectreactor:reactor-core") + dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) dockerTestImplementation("io.projectreactor:reactor-test") dockerTestImplementation("org.apache.httpcomponents.client5:httpclient5") dockerTestImplementation("org.junit.jupiter:junit-jupiter") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-jpa/src/test/java/smoketest/data/jpa/SpyBeanSampleDataJpaApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-jpa/src/test/java/smoketest/data/jpa/SpyBeanSampleDataJpaApplicationTests.java deleted file mode 100644 index d720db0f642d..000000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-jpa/src/test/java/smoketest/data/jpa/SpyBeanSampleDataJpaApplicationTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smoketest.data.jpa; - -import org.junit.jupiter.api.Test; -import smoketest.data.jpa.service.CityRepository; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.test.web.servlet.assertj.MockMvcTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.then; - -/** - * Tests for {@link SampleDataJpaApplication} that use {@link SpyBean @SpyBean}. - * - * @author Andy Wilkinson - * @deprecated since 3.4.0 for removal in 4.0.0 - */ -@SuppressWarnings("removal") -@Deprecated(since = "3.4.0", forRemoval = true) -@SpringBootTest -@AutoConfigureMockMvc -@AutoConfigureTestDatabase -class SpyBeanSampleDataJpaApplicationTests { - - @Autowired - private MockMvcTester mvc; - - @SpyBean - private CityRepository repository; - - @Test - void testHome() { - assertThat(this.mvc.get().uri("/")).hasStatusOk().hasBodyTextEqualTo("Bath"); - then(this.repository).should().findByNameAndCountryAllIgnoringCase("Bath", "UK"); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-mongo/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-mongo/build.gradle index 4e8fa9219930..e15d8387d31f 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-mongo/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-mongo/build.gradle @@ -34,7 +34,7 @@ dependencies { dockerTestImplementation("org.testcontainers:mongodb") dockerTestImplementation("org.testcontainers:testcontainers") + implementation(project(":spring-boot-project:spring-boot-reactor")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-mongodb")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-mongodb-reactive")) - implementation("io.projectreactor:reactor-core") } \ No newline at end of file diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-r2dbc-flyway/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-r2dbc-flyway/build.gradle index a1c68e1358d4..5813dcd86187 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-r2dbc-flyway/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-r2dbc-flyway/build.gradle @@ -32,7 +32,7 @@ dependencies { implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-r2dbc")) - runtimeOnly("org.flywaydb:flyway-core") + runtimeOnly(project(":spring-boot-project:spring-boot-flyway")) runtimeOnly("org.flywaydb:flyway-database-postgresql") runtimeOnly("org.postgresql:postgresql") runtimeOnly("org.postgresql:r2dbc-postgresql") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-r2dbc-liquibase/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-r2dbc-liquibase/build.gradle index d606fe19f502..7e2edb2db799 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-r2dbc-liquibase/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-r2dbc-liquibase/build.gradle @@ -32,9 +32,8 @@ dependencies { implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-r2dbc")) - runtimeOnly("org.liquibase:liquibase-core") { - exclude group: "javax.xml.bind", module: "jaxb-api" - } + runtimeOnly(project(":spring-boot-project:spring-boot-jdbc")) + runtimeOnly(project(":spring-boot-project:spring-boot-liquibase")) runtimeOnly("org.postgresql:postgresql") runtimeOnly("org.postgresql:r2dbc-postgresql") runtimeOnly("org.springframework:spring-jdbc") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-redis/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-redis/build.gradle index f425c9feb407..71b8b513b636 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-redis/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-redis/build.gradle @@ -22,12 +22,12 @@ plugins { description = "Spring Boot Data Redis smoke test" dependencies { - dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-reactor")) dockerTestImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) + dockerTestImplementation(project(":spring-boot-project:spring-boot-test")) dockerTestImplementation(project(":spring-boot-project:spring-boot-testcontainers")) dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker")) dockerTestImplementation("com.redis:testcontainers-redis") - dockerTestImplementation("io.projectreactor:reactor-core") dockerTestImplementation("io.projectreactor:reactor-test") dockerTestImplementation("org.junit.jupiter:junit-jupiter") dockerTestImplementation("org.junit.platform:junit-platform-engine") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-devtools/src/test/java/smoketest/devtools/SampleDevToolsApplicationIntegrationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-devtools/src/test/java/smoketest/devtools/SampleDevToolsApplicationIntegrationTests.java index 040e4065f9ab..32a67530eaf2 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-devtools/src/test/java/smoketest/devtools/SampleDevToolsApplicationIntegrationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-devtools/src/test/java/smoketest/devtools/SampleDevToolsApplicationIntegrationTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-flyway/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-flyway/build.gradle index aaf57afa74d7..f7cb5e45ed55 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-flyway/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-flyway/build.gradle @@ -25,8 +25,8 @@ dependencies { implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-jpa")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) + runtimeOnly(project(":spring-boot-project:spring-boot-flyway")) runtimeOnly("com.h2database:h2") - runtimeOnly("org.flywaydb:flyway-core") testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hateoas/src/test/java/smoketest/hateoas/SampleHateoasApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hateoas/src/test/java/smoketest/hateoas/SampleHateoasApplicationTests.java index 3463a987e09f..e01c2d2d9676 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hateoas/src/test/java/smoketest/hateoas/SampleHateoasApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hateoas/src/test/java/smoketest/hateoas/SampleHateoasApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/build.gradle new file mode 100644 index 000000000000..9b27c39c1054 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/build.gradle @@ -0,0 +1,34 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id "java" +} + +description = "Spring Boot Hibernate smoke test" + +dependencies { + implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-freemarker")) + implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) + implementation(project(":spring-boot-project:spring-boot-jdbc")) + implementation(project(":spring-boot-project:spring-boot-hibernate")) + implementation("jakarta.xml.bind:jakarta.xml.bind-api") + + runtimeOnly("com.h2database:h2") + runtimeOnly("jakarta.transaction:jakarta.transaction-api") + + testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/SampleJpaApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/SampleJpaApplication.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/SampleJpaApplication.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/SampleJpaApplication.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/domain/Note.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/domain/Note.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/domain/Note.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/domain/Note.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/domain/Tag.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/domain/Tag.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/domain/Tag.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/domain/Tag.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/repository/JpaNoteRepository.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/repository/JpaNoteRepository.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/repository/JpaNoteRepository.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/repository/JpaNoteRepository.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/repository/JpaTagRepository.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/repository/JpaTagRepository.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/repository/JpaTagRepository.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/repository/JpaTagRepository.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/repository/NoteRepository.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/repository/NoteRepository.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/repository/NoteRepository.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/repository/NoteRepository.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/repository/TagRepository.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/repository/TagRepository.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/repository/TagRepository.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/repository/TagRepository.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/web/IndexController.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/web/IndexController.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/java/smoketest/jpa/web/IndexController.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/java/smoketest/jpa/web/IndexController.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/resources/application.properties similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/resources/application.properties rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/resources/application.properties diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/resources/import.sql b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/resources/import.sql similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/resources/import.sql rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/resources/import.sql diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/resources/templates/index.ftlh b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/resources/templates/index.ftlh similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/main/resources/templates/index.ftlh rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/main/resources/templates/index.ftlh diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/test/java/smoketest/jpa/SampleJpaApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/test/java/smoketest/jpa/SampleJpaApplicationTests.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/test/java/smoketest/jpa/SampleJpaApplicationTests.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/test/java/smoketest/jpa/SampleJpaApplicationTests.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/test/java/smoketest/jpa/repository/JpaNoteRepositoryIntegrationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/test/java/smoketest/jpa/repository/JpaNoteRepositoryIntegrationTests.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/test/java/smoketest/jpa/repository/JpaNoteRepositoryIntegrationTests.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/test/java/smoketest/jpa/repository/JpaNoteRepositoryIntegrationTests.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/test/java/smoketest/jpa/repository/JpaTagRepositoryIntegrationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/test/java/smoketest/jpa/repository/JpaTagRepositoryIntegrationTests.java similarity index 100% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/src/test/java/smoketest/jpa/repository/JpaTagRepositoryIntegrationTests.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-hibernate/src/test/java/smoketest/jpa/repository/JpaTagRepositoryIntegrationTests.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java index 2a9484216141..a5991256b5dd 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyManagementPortTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyManagementPortTests.java index 979b318c3213..13ebd741ccd8 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyManagementPortTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyManagementPortTests.java @@ -22,12 +22,12 @@ import smoketest.jersey.AbstractJerseyManagementPortTests.ResourceConfigConfiguration; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; +import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java index 4c29791c258c..efd53bdcabdb 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java @@ -22,9 +22,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java index c433bd96bc57..c882632565ac 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java @@ -22,9 +22,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyApplicationPathAndManagementPortTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyApplicationPathAndManagementPortTests.java index f528f2dd3e28..4a63a506bc8a 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyApplicationPathAndManagementPortTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyApplicationPathAndManagementPortTests.java @@ -20,9 +20,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java index 6f9776ea3cd3..0dd978cc7091 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyDifferentPortSampleActuatorApplicationTests.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty-jsp/src/test/java/smoketest/jetty/jsp/SampleWebJspApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty-jsp/src/test/java/smoketest/jetty/jsp/SampleWebJspApplicationTests.java index b595b0cc94bb..d1ca309a1a44 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty-jsp/src/test/java/smoketest/jetty/jsp/SampleWebJspApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty-jsp/src/test/java/smoketest/jetty/jsp/SampleWebJspApplicationTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty-ssl/src/test/java/smoketest/jetty/ssl/SampleJettySslApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty-ssl/src/test/java/smoketest/jetty/ssl/SampleJettySslApplicationTests.java index 5a0e69fb17c8..eabdb89e803f 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty-ssl/src/test/java/smoketest/jetty/ssl/SampleJettySslApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty-ssl/src/test/java/smoketest/jetty/ssl/SampleJettySslApplicationTests.java @@ -21,8 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -33,7 +33,7 @@ * * @author Dave Syer */ -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "debug=true") class SampleJettySslApplicationTests { @Autowired diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty/src/test/java/smoketest/jetty/SampleJettyApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty/src/test/java/smoketest/jetty/SampleJettyApplicationTests.java index 1b5432555489..fffc1c60eef5 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty/src/test/java/smoketest/jetty/SampleJettyApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jetty/src/test/java/smoketest/jetty/SampleJettyApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/build.gradle deleted file mode 100644 index c0c5b8ebc4f0..000000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jpa/build.gradle +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id "java" -} - -description = "Spring Boot JPA smoke test" - -dependencies { - implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-freemarker")) - implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - implementation("jakarta.persistence:jakarta.persistence-api") - implementation("jakarta.xml.bind:jakarta.xml.bind-api") - implementation("org.hibernate.orm:hibernate-core") - implementation("org.springframework:spring-orm") - - runtimeOnly("com.h2database:h2") - runtimeOnly("jakarta.transaction:jakarta.transaction-api") - - testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/build.gradle index 0b91f0abc08a..e9643a2df8d6 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-kafka/build.gradle @@ -40,7 +40,7 @@ dependencies { dockerTestImplementation("org.testcontainers:kafka") implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json")) - implementation("org.springframework.kafka:spring-kafka") + implementation(project(":spring-boot-project:spring-boot-kafka")) testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) testImplementation("org.awaitility:awaitility") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-liquibase/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-liquibase/build.gradle index e27cf9b1b3ef..3b7ae7631dc8 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-liquibase/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-liquibase/build.gradle @@ -21,13 +21,10 @@ plugins { description = "Spring Boot Liquibase smoke test" dependencies { + implementation(project(":spring-boot-project:spring-boot-liquibase")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - implementation("jakarta.xml.bind:jakarta.xml.bind-api") - implementation("org.liquibase:liquibase-core") { - exclude group: "javax.xml.bind", module: "jaxb-api" - } runtimeOnly("com.h2database:h2") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-authorization-server/src/test/java/smoketest/oauth2/server/SampleOAuth2AuthorizationServerApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-authorization-server/src/test/java/smoketest/oauth2/server/SampleOAuth2AuthorizationServerApplicationTests.java index 48e16cdf5495..efe6f2caf6d2 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-authorization-server/src/test/java/smoketest/oauth2/server/SampleOAuth2AuthorizationServerApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-authorization-server/src/test/java/smoketest/oauth2/server/SampleOAuth2AuthorizationServerApplicationTests.java @@ -26,8 +26,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.http.client.HttpRedirects; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java index cb488aac3af8..d4ce38e589f9 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java @@ -23,8 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.http.client.HttpRedirects; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-resource-server/src/test/java/smoketest/oauth2/resource/SampleOauth2ResourceServerApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-resource-server/src/test/java/smoketest/oauth2/resource/SampleOauth2ResourceServerApplicationTests.java index 7c8648ba3c1e..68adb8213410 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-resource-server/src/test/java/smoketest/oauth2/resource/SampleOauth2ResourceServerApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-resource-server/src/test/java/smoketest/oauth2/resource/SampleOauth2ResourceServerApplicationTests.java @@ -26,7 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/AttributeInjectionTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/AttributeInjectionTests.java index 120d41f40b76..a7509ccc93f4 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/AttributeInjectionTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/AttributeInjectionTests.java @@ -28,10 +28,10 @@ class AttributeInjectionTests { @Autowired(required = false) - private org.springframework.boot.web.servlet.error.ErrorAttributes errorAttributesServlet; + private org.springframework.boot.webmvc.error.ErrorAttributes errorAttributesServlet; @Autowired(required = false) - private org.springframework.boot.web.reactive.error.ErrorAttributes errorAttributesReactive; + private org.springframework.boot.webflux.error.ErrorAttributes errorAttributesReactive; @Test void contextLoads() { diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-prometheus/src/test/java/smoketest/prometheus/SamplePrometheusApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-prometheus/src/test/java/smoketest/prometheus/SamplePrometheusApplicationTests.java index 8dc5dd18337c..23846c9cc144 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-prometheus/src/test/java/smoketest/prometheus/SamplePrometheusApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-prometheus/src/test/java/smoketest/prometheus/SamplePrometheusApplicationTests.java @@ -22,7 +22,7 @@ import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-property-validation/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-property-validation/build.gradle index ec03a2eb06e8..6aee7aadb2e3 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-property-validation/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-property-validation/build.gradle @@ -26,4 +26,5 @@ dependencies { implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) + testImplementation(project(":spring-boot-project:spring-boot-web-server")) } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-property-validation/src/test/java/smoketest/propertyvalidation/SamplePropertyValidationApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-property-validation/src/test/java/smoketest/propertyvalidation/SamplePropertyValidationApplicationTests.java index c085ffdf5509..cda7195683eb 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-property-validation/src/test/java/smoketest/propertyvalidation/SamplePropertyValidationApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-property-validation/src/test/java/smoketest/propertyvalidation/SamplePropertyValidationApplicationTests.java @@ -20,9 +20,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.bind.validation.BindValidationException; import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-quartz/src/test/java/smoketest/quartz/SampleQuartzApplicationWebTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-quartz/src/test/java/smoketest/quartz/SampleQuartzApplicationWebTests.java index 761a699920c3..d93c65b2292c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-quartz/src/test/java/smoketest/quartz/SampleQuartzApplicationWebTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-quartz/src/test/java/smoketest/quartz/SampleQuartzApplicationWebTests.java @@ -33,7 +33,7 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/build.gradle index eacefd311a3c..b9d9c43bfb0b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/build.gradle @@ -20,17 +20,18 @@ plugins { description = "Spring Boot SAML 2 service provider smoke test" +configurations.all { + resolutionStrategy.eachDependency { + if (it.requested.group == 'org.opensaml') { + it.useVersion '4.0.1' + } + } +} + dependencies { + implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - implementation("org.opensaml:opensaml-core:4.0.1") - implementation("org.opensaml:opensaml-saml-api:4.0.1") - implementation("org.opensaml:opensaml-saml-impl:4.0.1") - implementation("org.springframework.security:spring-security-config") - implementation("org.springframework.security:spring-security-saml2-service-provider") { - exclude group: "org.opensaml", module: "opensaml-core" - exclude group: "org.opensaml", module: "opensaml-saml-api" - exclude group: "org.opensaml", module: "opensaml-saml-impl" - } + implementation(project(":spring-boot-project:spring-boot-security-saml2")) testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) testImplementation("org.apache.httpcomponents.client5:httpclient5") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java index 98fe2e846e48..cf86e10fe8ab 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java @@ -23,8 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.http.client.HttpRedirects; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/main/java/smoketest/secure/jersey/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/main/java/smoketest/secure/jersey/SecurityConfiguration.java index 04f9e49b88a3..25a1688e043c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/main/java/smoketest/secure/jersey/SecurityConfiguration.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/main/java/smoketest/secure/jersey/SecurityConfiguration.java @@ -16,8 +16,8 @@ package smoketest.secure.jersey; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/AbstractJerseySecureTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/AbstractJerseySecureTests.java index 5572f20b540c..47afbe91ea6e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/AbstractJerseySecureTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/AbstractJerseySecureTests.java @@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/CustomApplicationPathActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/CustomApplicationPathActuatorTests.java index a86910ad37dc..762f663ff3c6 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/CustomApplicationPathActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/CustomApplicationPathActuatorTests.java @@ -17,7 +17,7 @@ package smoketest.secure.jersey; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; /** * Integration tests for actuator endpoints with custom application path. diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/JerseySecureApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/JerseySecureApplicationTests.java index 0a5fb2869221..4d293e5d588b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/JerseySecureApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/JerseySecureApplicationTests.java @@ -17,7 +17,7 @@ package smoketest.secure.jersey; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; /** * Integration tests for actuator endpoints with custom security configuration. diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/ManagementPortAndPathJerseyApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/ManagementPortAndPathJerseyApplicationTests.java index 81b249a6da5a..fdefb1f676a1 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/ManagementPortAndPathJerseyApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/ManagementPortAndPathJerseyApplicationTests.java @@ -20,9 +20,9 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/ManagementPortCustomApplicationPathJerseyTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/ManagementPortCustomApplicationPathJerseyTests.java index 25a83109c583..5e373e40bf00 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/ManagementPortCustomApplicationPathJerseyTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-jersey/src/test/java/smoketest/secure/jersey/ManagementPortCustomApplicationPathJerseyTests.java @@ -19,9 +19,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java index d3d2f58a683d..3d2075beacf8 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java @@ -21,13 +21,13 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; -import org.springframework.boot.autoconfigure.security.reactive.PathRequest; +import org.springframework.boot.security.autoconfigure.actuate.reactive.EndpointRequest; +import org.springframework.boot.security.autoconfigure.reactive.PathRequest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.web.server.ServerHttpSecurity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/SampleSecureWebFluxCustomSecurityTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/SampleSecureWebFluxCustomSecurityTests.java index c89559b6abb4..2e9553ae5579 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/SampleSecureWebFluxCustomSecurityTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/SampleSecureWebFluxCustomSecurityTests.java @@ -21,9 +21,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; -import org.springframework.boot.autoconfigure.security.reactive.PathRequest; +import org.springframework.boot.security.autoconfigure.actuate.reactive.EndpointRequest; +import org.springframework.boot.security.autoconfigure.reactive.PathRequest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-servlet/src/test/java/smoketest/servlet/SampleServletApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-servlet/src/test/java/smoketest/servlet/SampleServletApplicationTests.java index 48022cd8e3f0..51b5fb2c1b06 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-servlet/src/test/java/smoketest/servlet/SampleServletApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-servlet/src/test/java/smoketest/servlet/SampleServletApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/build.gradle index 2e4bcd10a7c0..c4a008174c29 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/build.gradle @@ -21,13 +21,10 @@ plugins { description = "Spring Boot Session smoke test" dependencies { + implementation(project(":spring-boot-project:spring-boot-session-hazelcast")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - implementation("com.hazelcast:hazelcast") - implementation("org.springframework.session:spring-session-hazelcast") { - exclude group: "javax.annotation", module: "javax.annotation-api" - } testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/main/java/smoketest/session/hazelcast/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/main/java/smoketest/session/hazelcast/SecurityConfiguration.java index 069440b404f2..1c59a1d80ff3 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/main/java/smoketest/session/hazelcast/SecurityConfiguration.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/main/java/smoketest/session/hazelcast/SecurityConfiguration.java @@ -16,8 +16,8 @@ package smoketest.session.hazelcast; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/test/java/smoketest/session/hazelcast/SampleSessionHazelcastApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/test/java/smoketest/session/hazelcast/SampleSessionHazelcastApplicationTests.java index 254be87806c1..18d562919a11 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/test/java/smoketest/session/hazelcast/SampleSessionHazelcastApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-hazelcast/src/test/java/smoketest/session/hazelcast/SampleSessionHazelcastApplicationTests.java @@ -26,7 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/build.gradle index b41bc608adf6..e55ca8c050ab 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/build.gradle @@ -21,11 +21,11 @@ plugins { description = "Spring Boot Session JDBC smoke test" dependencies { + implementation(project(":spring-boot-project:spring-boot-session-jdbc")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) runtimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc")) - runtimeOnly("org.springframework.session:spring-session-jdbc") runtimeOnly("com.h2database:h2") testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/main/java/smoketest/session/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/main/java/smoketest/session/SecurityConfiguration.java index 62e8ba9914d9..6cc40850e4d3 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/main/java/smoketest/session/SecurityConfiguration.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/main/java/smoketest/session/SecurityConfiguration.java @@ -16,8 +16,8 @@ package smoketest.session; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/test/java/smoketest/session/SampleSessionJdbcApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/test/java/smoketest/session/SampleSessionJdbcApplicationTests.java index b83cd3402105..7db4be4524fd 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/test/java/smoketest/session/SampleSessionJdbcApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-jdbc/src/test/java/smoketest/session/SampleSessionJdbcApplicationTests.java @@ -27,10 +27,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.http.client.HttpRedirects; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -53,7 +53,7 @@ * @author Madhura Bhave */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { "server.servlet.session.timeout:2" }) + properties = { "server.servlet.session.timeout:2", "debug=true" }) class SampleSessionJdbcApplicationTests { private static final ClientHttpRequestFactorySettings DONT_FOLLOW_REDIRECTS = ClientHttpRequestFactorySettings diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/build.gradle index a91fde7acf10..027117d83791 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/build.gradle @@ -28,9 +28,9 @@ dependencies { dockerTestImplementation("org.testcontainers:junit-jupiter") dockerTestImplementation("org.testcontainers:mongodb") + implementation(project(":spring-boot-project:spring-boot-session-data-mongodb")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-mongodb")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - implementation("org.springframework.session:spring-session-data-mongodb") } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/dockerTest/java/smoketest/session/mongodb/SampleSessionMongoApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/dockerTest/java/smoketest/session/mongodb/SampleSessionMongoApplicationTests.java index a3684dd74b0a..f8f7d3e69378 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/dockerTest/java/smoketest/session/mongodb/SampleSessionMongoApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/dockerTest/java/smoketest/session/mongodb/SampleSessionMongoApplicationTests.java @@ -28,10 +28,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/main/java/smoketest/session/mongodb/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/main/java/smoketest/session/mongodb/SecurityConfiguration.java index 9d72d4d5fc55..26d0999647a6 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/main/java/smoketest/session/mongodb/SecurityConfiguration.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-mongo/src/main/java/smoketest/session/mongodb/SecurityConfiguration.java @@ -16,8 +16,8 @@ package smoketest.session.mongodb; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/build.gradle index c26e38e74752..4ab88e46a469 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/build.gradle @@ -28,9 +28,9 @@ dependencies { dockerTestImplementation("com.redis:testcontainers-redis") dockerTestImplementation("org.testcontainers:junit-jupiter") + implementation(project(":spring-boot-project:spring-boot-session-data-redis")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-redis")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - implementation("org.springframework.session:spring-session-data-redis") } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/dockerTest/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/dockerTest/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java index e553517c42d8..5226f96b25cd 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/dockerTest/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/dockerTest/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java @@ -28,9 +28,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/main/java/smoketest/session/redis/SecurityConfiguration.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/main/java/smoketest/session/redis/SecurityConfiguration.java index 3b9c8f54e22c..86ecd6d9a9ac 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/main/java/smoketest/session/redis/SecurityConfiguration.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/main/java/smoketest/session/redis/SecurityConfiguration.java @@ -16,8 +16,8 @@ package smoketest.session.redis; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-mongo/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-mongo/build.gradle index 5b06052ac82b..93f0989df22e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-mongo/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-mongo/build.gradle @@ -28,9 +28,9 @@ dependencies { dockerTestImplementation("org.testcontainers:junit-jupiter") dockerTestImplementation("org.testcontainers:mongodb") + implementation(project(":spring-boot-project:spring-boot-session-data-mongodb")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-webflux")) runtimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-mongodb-reactive")) - runtimeOnly("org.springframework.session:spring-session-data-mongodb") } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-mongo/src/dockerTest/java/smoketest/session/SampleSessionWebFluxMongoApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-mongo/src/dockerTest/java/smoketest/session/SampleSessionWebFluxMongoApplicationTests.java index f7123bd28dad..5d65c995ec58 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-mongo/src/dockerTest/java/smoketest/session/SampleSessionWebFluxMongoApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-mongo/src/dockerTest/java/smoketest/session/SampleSessionWebFluxMongoApplicationTests.java @@ -27,9 +27,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-redis/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-redis/build.gradle index c4bbc4e8cf82..c956807a5a91 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-redis/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-redis/build.gradle @@ -28,9 +28,9 @@ dependencies { dockerTestImplementation("com.redis:testcontainers-redis") dockerTestImplementation("org.testcontainers:junit-jupiter") + implementation(project(":spring-boot-project:spring-boot-session-data-redis")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-webflux")) runtimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-redis-reactive")) - runtimeOnly("org.springframework.session:spring-session-data-redis") } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-redis/src/dockerTest/java/smoketest/session/SampleSessionWebFluxRedisApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-redis/src/dockerTest/java/smoketest/session/SampleSessionWebFluxRedisApplicationTests.java index dd59e9153e29..34b0c0f3b81c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-redis/src/dockerTest/java/smoketest/session/SampleSessionWebFluxRedisApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux-redis/src/dockerTest/java/smoketest/session/SampleSessionWebFluxRedisApplicationTests.java @@ -27,9 +27,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/build.gradle index ba85f57e5e98..d837536eec30 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/build.gradle @@ -21,6 +21,7 @@ plugins { description = "Spring Boot Test smoke test" dependencies { + implementation(project(":spring-boot-project:spring-boot-restclient")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-jpa")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/src/main/java/smoketest/test/service/RemoteVehicleDetailsService.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/src/main/java/smoketest/test/service/RemoteVehicleDetailsService.java index 3fa8152f0146..23c58264d314 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/src/main/java/smoketest/test/service/RemoteVehicleDetailsService.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/src/main/java/smoketest/test/service/RemoteVehicleDetailsService.java @@ -20,7 +20,7 @@ import org.apache.commons.logging.LogFactory; import smoketest.test.domain.VehicleIdentificationNumber; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.util.Assert; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/src/test/java/smoketest/test/SampleTestApplicationWebIntegrationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/src/test/java/smoketest/test/SampleTestApplicationWebIntegrationTests.java index 76fb89d13dfa..3a128a168f58 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/src/test/java/smoketest/test/SampleTestApplicationWebIntegrationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-test/src/test/java/smoketest/test/SampleTestApplicationWebIntegrationTests.java @@ -26,7 +26,7 @@ import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.test.context.bean.override.mockito.MockitoBean; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-testng/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-testng/build.gradle index 57b6c56678f5..034b50b0ecf7 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-testng/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-testng/build.gradle @@ -22,11 +22,14 @@ description = "Spring Boot TestNG smoke test" dependencies { implementation(platform(project(":spring-boot-project:spring-boot-dependencies"))) + implementation(project(":spring-boot-project:spring-boot-http-converter")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat")) - implementation("org.springframework:spring-webmvc") + implementation(project(":spring-boot-project:spring-boot-webmvc")) + testImplementation(project(":spring-boot-project:spring-boot-restclient")) testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-web-server-test")) testImplementation("org.assertj:assertj-core") testImplementation("org.springframework:spring-test") testImplementation("org.testng:testng:6.8.13") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-testng/src/test/java/smoketest/testng/SampleTestNGApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-testng/src/test/java/smoketest/testng/SampleTestNGApplicationTests.java index 3f8e2af70f4d..e0bb26d6347d 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-testng/src/test/java/smoketest/testng/SampleTestNGApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-testng/src/test/java/smoketest/testng/SampleTestNGApplicationTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-jsp/src/test/java/smoketest/tomcat/jsp/SampleWebJspApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-jsp/src/test/java/smoketest/tomcat/jsp/SampleWebJspApplicationTests.java index 9801d800d8f9..1b5cb9feac91 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-jsp/src/test/java/smoketest/tomcat/jsp/SampleWebJspApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-jsp/src/test/java/smoketest/tomcat/jsp/SampleWebJspApplicationTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/main/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/main/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplication.java index 3ec37cc45591..cd07b750e9ff 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/main/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplication.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/main/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplication.java @@ -20,8 +20,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; import org.springframework.context.annotation.Bean; /** @@ -36,7 +36,7 @@ public class SampleTomcatTwoConnectorsApplication { @Bean public ServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); - tomcat.addAdditionalTomcatConnectors(createStandardConnector()); + tomcat.addAdditionalConnectors(createStandardConnector()); return tomcat; } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java index 86ed545b0b48..d6911b2f40e1 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java @@ -25,11 +25,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; +import org.springframework.boot.tomcat.TomcatWebServer; import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.context.WebServerInitializedEvent; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-ssl/src/test/java/smoketest/tomcat/ssl/SampleTomcatSslApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-ssl/src/test/java/smoketest/tomcat/ssl/SampleTomcatSslApplicationTests.java index 71fa9a8b370e..480239bed956 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-ssl/src/test/java/smoketest/tomcat/ssl/SampleTomcatSslApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-ssl/src/test/java/smoketest/tomcat/ssl/SampleTomcatSslApplicationTests.java @@ -21,8 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.json.JsonContent; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/build.gradle index 5d32342b16e1..08957351370c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/build.gradle @@ -21,9 +21,10 @@ plugins { description = "Spring Boot Tomcat smoke test" dependencies { + implementation(project(":spring-boot-project:spring-boot-http-converter")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat")) - implementation("org.springframework:spring-webmvc") + implementation(project(":spring-boot-project:spring-boot-webmvc")) testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/src/test/java/smoketest/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/src/test/java/smoketest/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java index 317651f7799c..ebf18e6ad974 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/src/test/java/smoketest/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/src/test/java/smoketest/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java @@ -23,13 +23,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -57,7 +57,7 @@ void testHome() { } @Configuration(proxyBeanMethods = false) - @Import({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) @ComponentScan(basePackageClasses = { SampleController.class, HelloWorldService.class }) diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/src/test/java/smoketest/tomcat/SampleTomcatApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/src/test/java/smoketest/tomcat/SampleTomcatApplicationTests.java index 478c107eaef2..834a1dc9e61e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/src/test/java/smoketest/tomcat/SampleTomcatApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat/src/test/java/smoketest/tomcat/SampleTomcatApplicationTests.java @@ -32,9 +32,9 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11-ssl/src/test/java/smoketest/tomcat/ssl/SampleTomcat11SslApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11-ssl/src/test/java/smoketest/tomcat/ssl/SampleTomcat11SslApplicationTests.java index 67c68afc1593..0382d36e50b6 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11-ssl/src/test/java/smoketest/tomcat/ssl/SampleTomcat11SslApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11-ssl/src/test/java/smoketest/tomcat/ssl/SampleTomcat11SslApplicationTests.java @@ -21,8 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.json.JsonContent; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/build.gradle index 56513e3d29f6..feb0875b2614 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/build.gradle @@ -29,9 +29,10 @@ configurations.all { } dependencies { + implementation(project(":spring-boot-project:spring-boot-http-converter")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat")) - implementation("org.springframework:spring-webmvc") + implementation(project(":spring-boot-project:spring-boot-webmvc")) testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/src/test/java/smoketest/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/src/test/java/smoketest/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java index cbaa267e9b37..2ee9253d033a 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/src/test/java/smoketest/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/src/test/java/smoketest/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java @@ -23,13 +23,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; +import org.springframework.boot.web.server.test.client.TestRestTemplate; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -57,7 +57,7 @@ void testHome() { } @Configuration(proxyBeanMethods = false) - @Import({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) @ComponentScan(basePackageClasses = { SampleController.class, HelloWorldService.class }) diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/src/test/java/smoketest/tomcat/SampleTomcat11ApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/src/test/java/smoketest/tomcat/SampleTomcat11ApplicationTests.java index 5d812cbfc8b9..f3547778354e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/src/test/java/smoketest/tomcat/SampleTomcat11ApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat11/src/test/java/smoketest/tomcat/SampleTomcat11ApplicationTests.java @@ -32,9 +32,9 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.tomcat.TomcatWebServer; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-traditional/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-traditional/build.gradle index e2d7d310ae3b..a3c75f4325a9 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-traditional/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-traditional/build.gradle @@ -28,7 +28,7 @@ configurations { dependencies { implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - implementation("org.springframework:spring-webmvc") + implementation(project(":spring-boot-project:spring-boot-webmvc")) providedRuntime(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat")) providedRuntime("org.apache.tomcat.embed:tomcat-embed-jasper") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-traditional/src/test/java/smoketest/traditional/SampleTraditionalApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-traditional/src/test/java/smoketest/traditional/SampleTraditionalApplicationTests.java index 2cda6c75cefc..fb048946a4f9 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-traditional/src/test/java/smoketest/traditional/SampleTraditionalApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-traditional/src/test/java/smoketest/traditional/SampleTraditionalApplicationTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-undertow-ssl/src/test/java/smoketest/undertow/ssl/SampleUndertowSslApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-undertow-ssl/src/test/java/smoketest/undertow/ssl/SampleUndertowSslApplicationTests.java index 5b4b52769145..88b9e88c3107 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-undertow-ssl/src/test/java/smoketest/undertow/ssl/SampleUndertowSslApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-undertow-ssl/src/test/java/smoketest/undertow/ssl/SampleUndertowSslApplicationTests.java @@ -21,8 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-undertow/src/test/java/smoketest/undertow/SampleUndertowApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-undertow/src/test/java/smoketest/undertow/SampleUndertowApplicationTests.java index cf76e6068468..d574ad36b7a5 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-undertow/src/test/java/smoketest/undertow/SampleUndertowApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-undertow/src/test/java/smoketest/undertow/SampleUndertowApplicationTests.java @@ -25,7 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java index bf4ea5b13ecd..c4ed98366f0e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java @@ -20,7 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; import org.springframework.context.ApplicationContext; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java index 5a70d2985f07..29207a03fb2d 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.web.context.WebApplicationContext; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-freemarker/src/test/java/smoketest/freemarker/SampleWebFreeMarkerApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-freemarker/src/test/java/smoketest/freemarker/SampleWebFreeMarkerApplicationTests.java index f0816ddd17c4..90cbbeb9c382 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-freemarker/src/test/java/smoketest/freemarker/SampleWebFreeMarkerApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-freemarker/src/test/java/smoketest/freemarker/SampleWebFreeMarkerApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java index cb87ab3e5b56..22488199826c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java @@ -23,8 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-jsp/src/test/java/smoketest/jsp/SampleWebJspApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-jsp/src/test/java/smoketest/jsp/SampleWebJspApplicationTests.java index 86adf14645c4..28400c7f885b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-jsp/src/test/java/smoketest/jsp/SampleWebJspApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-jsp/src/test/java/smoketest/jsp/SampleWebJspApplicationTests.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/main/java/smoketest/security/method/SampleMethodSecurityApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/main/java/smoketest/security/method/SampleMethodSecurityApplication.java index e843d9448525..b85cd3e4919f 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/main/java/smoketest/security/method/SampleMethodSecurityApplication.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/main/java/smoketest/security/method/SampleMethodSecurityApplication.java @@ -18,9 +18,9 @@ import jakarta.servlet.DispatcherType; -import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.security.autoconfigure.actuate.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java index 325a69d96fe5..5f6c7cf2c0d4 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java @@ -23,8 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-mustache/src/test/java/smoketest/mustache/SampleWebMustacheApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-mustache/src/test/java/smoketest/mustache/SampleWebMustacheApplicationTests.java index ca3f962e5371..3cc90c615fc8 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-mustache/src/test/java/smoketest/mustache/SampleWebMustacheApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-mustache/src/test/java/smoketest/mustache/SampleWebMustacheApplicationTests.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java index 16684cc61cfd..f00d5ccf36db 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java @@ -24,8 +24,8 @@ import org.springframework.boot.http.client.HttpRedirects; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java index b40bd59fa541..4815f05f594a 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java @@ -24,8 +24,8 @@ import org.springframework.boot.http.client.HttpRedirects; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/AbstractErrorPageTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/AbstractErrorPageTests.java index 693fe12c71b9..8f2f64e5a4f3 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/AbstractErrorPageTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/AbstractErrorPageTests.java @@ -20,7 +20,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/AbstractUnauthenticatedErrorPageTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/AbstractUnauthenticatedErrorPageTests.java index dbc0954c3366..f0cf5c1606ce 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/AbstractUnauthenticatedErrorPageTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/AbstractUnauthenticatedErrorPageTests.java @@ -20,7 +20,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java index 8f4576510bde..e6d5ac3c481f 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java @@ -25,8 +25,8 @@ import org.springframework.boot.http.client.HttpRedirects; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-static/src/test/java/smoketest/web/staticcontent/SampleWebStaticApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-static/src/test/java/smoketest/web/staticcontent/SampleWebStaticApplicationTests.java index 40033ab9684c..9fc285a513f4 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-static/src/test/java/smoketest/web/staticcontent/SampleWebStaticApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-static/src/test/java/smoketest/web/staticcontent/SampleWebStaticApplicationTests.java @@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/main/resources/application.properties index c20caf35b134..d312c861a7e1 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/main/resources/application.properties +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/main/resources/application.properties @@ -2,3 +2,5 @@ spring.thymeleaf.cache: false server.tomcat.access_log_enabled: true server.tomcat.basedir: target/tomcat + +logging.level.org.thymeleaf:trace \ No newline at end of file diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java index 763fc0f8d318..e7397085ad61 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java @@ -23,8 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorDifferentPortTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorDifferentPortTests.java index bb8fcdd1fab3..7d4dbe06f426 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorDifferentPortTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorDifferentPortTests.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.web.server.test.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java index 8fd0adcac887..c410b828f60b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java @@ -29,7 +29,7 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.ws.client.core.WebServiceTemplate; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java index 163d9e1208fc..948419b34212 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java index 3eea065ef302..24253108a58a 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java @@ -33,11 +33,11 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java index b7bdbcab54ca..8ff2d6d238d7 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java index ca4e03a63a02..9cb03743c55b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java @@ -35,9 +35,9 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java index a91d3fb84391..5a0498aaaec2 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java index 11ebd88939e1..77f105ea8f8a 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java @@ -35,9 +35,9 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/checkstyle/import-control.xml b/src/checkstyle/import-control.xml index e45b3b705007..df8f1073bdf6 100644 --- a/src/checkstyle/import-control.xml +++ b/src/checkstyle/import-control.xml @@ -5,6 +5,7 @@ + @@ -17,12 +18,20 @@ - - + + + + + + + + + + + - @@ -31,7 +40,6 @@ - @@ -41,8 +49,27 @@ - + + + + + + + + + + + + + + + + + + + + @@ -65,9 +92,6 @@ - - - @@ -102,39 +126,60 @@ + + + + + + + + + - + + + + + + + - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + - @@ -149,16 +194,10 @@ - - - - - - @@ -166,14 +205,6 @@ - - - - - - - - - +